Dx7 Day/Night System

Ok after this tutorial you will have a working day and night system for DX7… Basically we are making a game time that starts and stops when you turn on/off your server. In the map editor there is a new layer being drawn that is the darkness effect. You have the option to choose where and if this new layer is drawn so you can make lights, campfires and other things that will cause the light to not appear… Its not the best looking thing in the world but heck its pretty cool to have this if your using dx7 still… This was ripped from an older engine made by Stein so all credits are to him for creating this system.

-Server-

modConstants

Add this to the bottom

' Game Time
Public Const GAME_MINUTES_PER_SECOND = 1

modDatabase

Find this line

PutVar App.Path & "\data\options.ini", "OPTIONS", "Website", Options.Website

Under it add:

PutVar App.Path & "\data\options.ini", "OPTIONS", "DayNight", STR(Options.DayNight)

In the next sub below the previous one : LoadOptions

Paste this at the bottom just like you did the last one:

Options.DayNight = Val(GetVar(App.Path & "\data\options.ini", "OPTIONS", "DayNight"))

modGeneral

In sub InitServer find this line:

' Initialize the random-number generator
Randomize ', seed

Below it Add this:

' Set the game time to the middle of the day.
GameMinutes = 0
GameHours = 12
DayTime = True

In the same Sub find this line: ’ load options, set if they dont exist

Your going to replace ,or make look like, that whole part all the way to the End if above this: ’ Get the listening socket ready to go

With this:

' load options, set if they dont exist
If Not FileExist(App.Path & "\data\options.ini", True) Then
Options.Game_Name = "Eclipse Origins"
Options.Port = 7001
Options.MOTD = "Eclipse Origins."
Options.Website = "http://www.touchofdeathforums.com/smf/"
Options.DayNight = 1 ‘New part
SaveOptions
Else
LoadOptions
End If
If Options.DayNight = 0 Then ‘New
frmServer.Label8.Visible = False ‘New
frmServer.lblGameTime.Visible = False ‘New
End If
```‘New

In **modGlobals** Add this to the bottom:

’ Game Time
Public GameMinutes As Byte
Public GameHours As Byte
Public DayTime As Boolean


In **modTypes** find this line: **Private Type OptionsRec**

Add this before End Type:

DayNight As Byte

**modServerLoop**

Find this:

If Tick > tmr1000 Then
If isShuttingDown Then
Call HandleShutdown
End If
tmr1000 = GetTickCount + 1000
End If


And replace with this:

If Tick > tmr1000 Then
If isShuttingDown Then
Call HandleShutdown
End If

’ Change the game time.
If Options.DayNight = 1 Then
GameMinutes = GameMinutes + GAME_MINUTES_PER_SECOND
If GameMinutes > 59 Then
GameMinutes = 0
GameHours = GameHours + 1
If GameHours > 23 Then
GameHours = 0
End If
End If

’ See if we need to switch to day or night.
If DayTime = True And GameHours > 19 Then
DayTime = False
SendGameTime
GlobalMsg “Darkness has fallen upon these Lands!”, Yellow
ElseIf DayTime = False And GameHours > 7 And GameHours < 19 Then
DayTime = True
SendGameTime
GlobalMsg “The Sun has risen across the Kingdom!”, Yellow
End If
’ Update the label
If DayTime = True Then
frmServer.lblGameTime.Caption = "(Day) " & Trim(STR(GameHours)) & “:” & Trim(STR(GameMinutes))
Else
frmServer.lblGameTime.Caption = "(Night) " & Trim(STR(GameHours)) & “:” & Trim(STR(GameMinutes))
End If
End If
tmr1000 = GetTickCount + 1000
End If

**modServerTcp**

Add this to the bottom:

Sub SendGameTime()
Dim Buffer As clsBuffer

Set Buffer = New clsBuffer
Buffer.WriteLong SSendTime
If DayTime = True Then
Buffer.WriteLong 1
Else
Buffer.WriteLong 0
End If

SendDataToAll Buffer.ToArray()
Set Buffer = Nothing

End Sub


**modPlayer**

Find this line : **' Send some more little goodies, no need to explain these**

Below the other calls add this:

Call SendGameTime

**modEnumerations**

Add this to the bottom of the server packets:

SSendTime


Find this line : **Public Enum MapLayer**

Add this above the LayerCount:

Night


Boom, now open your client.vbp

**Client**

Add the night tilesheet to your tilesets folder and number it correctly (the number after your last tileset -.-)

**modGlobals**

Add this to the bottom:

Public DayTime As Boolean

**modDirectDraw7**

Find this line:

’ Lock the backbuffer so we can draw text and names
TexthDC = DDS_BackBuffer.GetDC


Above it add this:

’ Render Night
If DayTime = False Or frmEditor_Map.optLayer(6).Value = True Then
For X = 0 To Map.maxX
For Y = 0 To Map.maxY
BltNightTile X, Y
Next
Next
End If

Add this to the bottom of modDirectDraw7:

Public Sub BltNightTile(ByVal X As Long, ByVal Y As Long)
Dim rec As RECT, i As Long

With Map.Tile(X, Y)
i = MapLayer.Night

’ skip tile if tileset isn’t set
If (.Layer(i).tileset > 0 And .Layer(i).tileset <= NumTileSets) And (.Layer(i).X > 0 Or .Layer(i).Y > 0) Then
’ sort out rec
rec.Top = .Layer(i).Y * PIC_Y
rec.Bottom = rec.Top + PIC_Y
rec.Left = .Layer(i).X * PIC_X
rec.Right = rec.Left + PIC_X
’ render
 Call Engine_BltFast(Camera.Left + ConvertMapX(x * PIC_X), Camera.top + ConvertMapY(Y * PIC_Y), DDS_Tileset(.Layer(i).Tileset), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
End If

End With

End Sub

**modHandleData**

Add this below the other ones in the InitMessages sub:

HandleDataSub(SSendTime) = GetAddress(AddressOf HandleSendTime)


At the bottom of modHandleData add this:

Private Sub HandleSendTime(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim Buffer As clsBuffer
Dim Temp As Byte

Set Buffer = New clsBuffer
Buffer.WriteBytes Data()

Temp = Buffer.ReadLong

If Temp = 1 Then DayTime = True
If Temp = 0 Then DayTime = False

Set Buffer = Nothing
End Sub

**modEnumerations**

Add this to the bottom of the server packets:

SSendTime


Find this line : **Public Enum MapLayer**

Add this above the LayerCount:

Night


In **modTypes** find this line: **Private Type OptionsRec**

Add this before End Type:

NightTile As Byte

**modDatabase**

Find this line sub: **Public Sub SaveOptions()**

Above the **Error Handler** add this:

Call PutVar(Filename, “Graphics”, “Night”, str(Options.NightTile))


In the next sub below the previous one : **LoadOptions**

Find this line: **Options.Debug = 0**

Below it add this:

Options.NightTile = ##


Ok below that find this: **Options.Debug = GetVar(Filename, "Options", "Debug")**

Below that line add this:

Options.NightTile = GetVar(Filename, “Graphics”, “Night”)


Ok for the **Form Work

Client Side-

FrmEditor_Map:**

Find the map layers radio buttons… Copy and paste one of them. Make sure you paste it inside of the frame: fraLayers.. After you have pasted it **make sure the index is set to 6**.

Now Add this to the bottom of frmEditor_map:

Private Sub optLayer_Click(Index As Integer)
If Index = Night Then
scrlTileSet.Value = Options.NightTile
scrlTileSet_Change
scrlTileSet.Enabled = False
Else
scrlTileSet.Enabled = True
End If
End Sub

**Server Form Work-**
**frmServer**

1.Anywhere on the server panel make a label named: **label 8**

set the caption to : **Game Time:**

2\. Beside it make a label named: **lblGameTime**

Set the caption to : **xx:xx**

**OK in your Server/Data Folder open options.ini and add this to the bottom: daynight=1**

**In your client/datafiles/ folder open the config.ini and add this to the bottom:**

[Graphics]
Night= 57


Hey that’s it!! If I missed anything let me know I think its all there.. You should have a working day/night system for EO2.0 or EO2.3..

Sorry I missed a couple steps like the server form work and to add the new map layer serverside… added the formwork steps to the bottom of the OP also added a quick screenshot

This looks great man, i’m sure people will find it useful.

Regards,

General Pony

Forgot this very important step

Server side modConstants add this to the bottom:

 ' Game Time

Public Const GAME_MINUTES_PER_SECOND = 1 

adding to OP now 😃

Hey this is a pretty nice feature to have, can still be put to good use.

This looks great, thanks for sharing!

You want to do the same in DirectX8?, I believe that would be great, since it would be much more beautiful and charming.

Does this work for Dx8/Nightly? If not - I would like tot hrow out there that a Night/Day system for Dx8/Nightly would be epic! Thanks for uploading a tutorial for Dx7 nonetheless. =]

Because changing a few DD7 calls into D3D8 is too much effort to put into your own games right?

Because changing a few DD7 calls into D3D8 is too much effort to put into your own games right?

I’m just new 🤷.

How would i do that? =S, Thanks for any and all feedback.

Nice addition, this can be useful for sure. I like that you can do “lights with it.”

The best thing is you can create light, this is great!

This looks great, thanks for sharing!

You want to do the same in DirectX8?, I believe that would be great, since it would be much more beautiful and charming.

If u were gonna do this in dx8 u should just use the game time system and make it work with the map tinting… would look cool and maybe even make it where it gets darker the later it gets amd brighter as the sun comes back up :)

must delete all maps ?

Nope

Note: Addition for this thing , If you want to use it on Real Time (Not 1 Second per Minute) Then follow this step

Find


[color]If[/color][color] [/color][color]Tick[/color][color] [/color][color]>[/color][color] tmr1000 [/color][color]Then[/color]

[color]				 [/color][color]If[/color][color] isShuttingDown [/color][color]Then[/color]

[color]						 [/color][color]Call[/color][color] [/color][color]HandleShutdown[/color]

[color]				 [/color][color]End[/color][color] [/color][color]If[/color]

[color]				 [/color][color]' Change the game time.

				 If Options.DayNight = 1 Then

						 GameMinutes = GameMinutes + GAME_MINUTES_PER_SECOND

						 If GameMinutes > 59 Then

								 GameMinutes = 0

								 GameHours = GameHours + 1

								 If GameHours > 23 Then

										 GameHours = 0

								 End If

						 End If

						 '[/color][color] [/color][color]See[/color][color] [/color][color]if[/color][color] we need to [/color][color]switch[/color][color] to day [/color][color]or[/color][color] night[/color][color].[/color]

[color]						 [/color][color]If[/color][color] [/color][color]DayTime[/color][color] [/color][color]=[/color][color] [/color][color]True[/color][color] [/color][color]And[/color][color] [/color][color]GameHours[/color][color] [/color][color]>[/color][color] [/color][color]19[/color][color] [/color][color]Then[/color]

[color]								 [/color][color]DayTime[/color][color] [/color][color]=[/color][color] [/color][color]False[/color]

[color]								 [/color][color]SendGameTime[/color]

[color]								 [/color][color]GlobalMsg[/color][color] [/color][color]"Darkness has fallen upon these Lands!"[/color][color],[/color][color] [/color][color]Yellow[/color]

[color]						 [/color][color]ElseIf[/color][color] [/color][color]DayTime[/color][color] [/color][color]=[/color][color] [/color][color]False[/color][color] [/color][color]And[/color][color] [/color][color]GameHours[/color][color] [/color][color]>[/color][color] [/color][color]7[/color][color] [/color][color]And[/color][color] [/color][color]GameHours[/color][color] [/color][color]<[/color][color] [/color][color]19[/color][color] [/color][color]Then[/color]

[color]								 [/color][color]DayTime[/color][color] [/color][color]=[/color][color] [/color][color]True[/color]

[color]								 [/color][color]SendGameTime[/color]

[color]								 [/color][color]GlobalMsg[/color][color] [/color][color]"The Sun has risen across the Kingdom!"[/color][color],[/color][color] [/color][color]Yellow[/color]

[color]						 [/color][color]End[/color][color] [/color][color]If[/color]

[color]						 [/color][color]' Update the label

						 If DayTime = True Then

								 frmServer.lblGameTime.Caption = "(Day) " & Trim(STR(GameHours)) & ":" & Trim(STR(GameMinutes))

						 Else

								 frmServer.lblGameTime.Caption = "(Night) " & Trim(STR(GameHours)) & ":" & Trim(STR(GameMinutes))

						 End If

				 End If

				 tmr1000 = GetTickCount + 1000

		 End If [/color]

[color][/color]

Replace it with

[code]

[color][size]If[/size][/color][color][size]Tick[/size][/color][color][size]>[/size][/color][color][size] tmr1000 [/size][/color][color][size]Then[/size][/color]

[color]				 [/color][color]If[/color][color] isShuttingDown [/color][color]Then[/color]

[color]						 [/color][color]Call[/color][color] [/color][color]HandleShutdown[/color]

[color]				 [/color][color]End[/color][color] [/color][color]If[/color]

[color]				 [/color][color]' Change the game time.

				 If Options.DayNight = 1 Then

						 GameSeconds = GameSeconds + GAME_MINUTES_PER_SECOND

						 If GameSeconds > 59 Then

						 GameSeconds = 0

						 GameMinutes = GameMinutes + 1

						 If GameMinutes > 59 Then

								 GameMinutes = 0

								 GameHours = GameHours + 1

								 If GameHours > 23 Then

										 GameHours = 0

								 End If

						 End If

					 End If

						 '[/color][color] [/color][color]See[/color][color] [/color][color]if[/color][color] we need to [/color][color]switch[/color][color] to day [/color][color]or[/color][color] night[/color][color].[/color]

[color]						 [/color][color]If[/color][color] [/color][color]DayTime[/color][color] [/color][color]=[/color][color] [/color][color]True[/color][color] [/color][color]And[/color][color] [/color][color]GameHours[/color][color] [/color][color]>[/color][color] [/color][color]19[/color][color] [/color][color]Then[/color]

[color]								 [/color][color]DayTime[/color][color] [/color][color]=[/color][color] [/color][color]False[/color]

[color]								 [/color][color]SendGameTime[/color]

[color]								 [/color][color]GlobalMsg[/color][color] [/color][color]"Darkness has fallen upon these Lands!"[/color][color],[/color][color] [/color][color]Yellow[/color]

[color]						 [/color][color]ElseIf[/color][color] [/color][color]DayTime[/color][color] [/color][color]=[/color][color] [/color][color]False[/color][color] [/color][color]And[/color][color] [/color][color]GameHours[/color][color] [/color][color]>[/color][color] [/color][color]7[/color][color] [/color][color]And[/color][color] [/color][color]GameHours[/color][color] [/color][color]<[/color][color] [/color][color]19[/color][color] [/color][color]Then[/color]

[color]								 [/color][color]DayTime[/color][color] [/color][color]=[/color][color] [/color][color]True[/color]

[color]								 [/color][color]SendGameTime[/color]

[color]								 [/color][color]GlobalMsg[/color][color] [/color][color]"The Sun has risen across the Kingdom!"[/color][color],[/color][color] [/color][color]Yellow[/color]

[color]						 [/color][color]End[/color][color] [/color][color]If[/color]

[color]						 [/color][color]' Update the label

						 If DayTime = True Then

								 frmServer.lblGameTime.Caption = "(Day) " & Trim(STR(GameHours)) & ":" & Trim(STR(GameMinutes))

						 Else

								 frmServer.lblGameTime.Caption = "(Night) " & Trim(STR(GameHours)) & ":" & Trim(STR(GameMinutes))

						 End If

				 End If

				 tmr1000 = GetTickCount + 1000

		 End If [/color]

[color][/color]

[color]Next Find this[/color]

[code]

[color][size]' Game Time[/size][/color]

[color]Public GameMinutes As Byte

Public GameHours As Byte

Public DayTime As Boolean [/color]

[color][/color]

[color]Replace it with or add the addition[/color]

[code]

[color][size]' Game Time[/size][/color]

[color]Public GameSeconds As Byte

Public GameMinutes As Byte

Public GameHours As Byte

Public DayTime As Boolean[/color]

[color][/color]

[color]Note me if i'm wrong[/color]

[color]Sorry New Site HATE me , I will re do this later[/color][/code][/code][/code]

Ok here is a little update for this tutorial…

Add this to the bottom of ServerTCP:

Sub SendGameTimeTo(ByVal Index As Long)

Dim Buffer As clsBuffer

    Set Buffer = New clsBuffer

    Buffer.WriteLong SSendTime

    If DayTime = True Then

        Buffer.WriteLong 1

    Else

        Buffer.WriteLong 0

    End If

    SendDataTo Index, Buffer.ToArray()

    Set Buffer = Nothing

End Sub

Next in modPlayer in Sub JoinGame find:

Call SendGameTime

And change it to:

Call SendGameTimeTo(Index)

This will only send the game time to the player that logs on and not everyone like before.

Done…

OPTIONAL

Here is a cool addon that will allow you to set whether an npc spawns during the day, night, or both.

First find this in sub UpdateMapLogic:

' //////////////////////////////////////

         ' // This is used for spawning an NPC //

        ' //////////////////////////////////////

Change that whole part down to End Sub to this:

' //////////////////////////////////////

                ' // This is used for spawning an NPC //

                ' //////////////////////////////////////

                ' Check if we are supposed to spawn an npc or not

                If MapNpc(mapnum).NPC(x).Num = 0 And Map(mapnum).NPC(x) > 0 Then

                    If TickCount > MapNpc(mapnum).NPC(x).SpawnWait + (NPC(Map(mapnum).NPC(x)).SpawnSecs * 1000) Then

                        ' See if we are using the day/night system. If we are act accordinly, otherwise just spawn the mob

                        If Options.DayNight = 1 Then

                            ' Check for gametime, this is an addition in 1.4.2\. We're only

                            ' spawning NPCs that are allowed to spawn in the current time

                            ' of the day.

                            If DayTime = True And NPC(Map(mapnum).NPC(x)).SpawnAtDay = 1 Then

                                Call SpawnNpc(x, mapnum)

                            ElseIf DayTime = False And NPC(Map(mapnum).NPC(x)).SpawnAtNight = 1 Then

                                Call SpawnNpc(x, mapnum)

                            End If

                        Else

                            ' Not using Day/Night, so just spawn it regardless.

                            Call SpawnNpc(x, mapnum)

                        End If

                    End If

                End If

                ' Despawn mobs if the day/night system is active.

                If Options.DayNight = 1 Then

                    ' Righto, let's see if we need to despawn an NPC until the time of the day changes.

                    ' Ignore this if the NPC has a target.

                    If MapNpc(mapnum).NPC(x).target = 0 And Map(mapnum).NPC(x) > 0 And Map(mapnum).NPC(x) <= MAX_NPCS Then

                        If DayTime = True And NPC(Map(mapnum).NPC(x)).SpawnAtDay = 0 Then

                            DespawnNPC mapnum, x

                        ElseIf DayTime = False And NPC(Map(mapnum).NPC(x)).SpawnAtNight = 0 Then

                            DespawnNPC mapnum, x

                        End If

                    End If

                End If

            Next

        End If

        DoEvents

    Next

    ' Make sure we reset the timer for npc hp regeneration

    If GetTickCount > GiveNPCHPTimer + 10000 Then

        GiveNPCHPTimer = GetTickCount

    End If

    ' Make sure we reset the timer for door closing

    If GetTickCount > KeyTimer + 15000 Then

        KeyTimer = GetTickCount

    End If

End Sub

Next Find this sub : Sub SpawnMapNpcs

Change the whole sub to this :


Sub SpawnMapNpcs(ByVal mapnum As Long)

    Dim i As Long

    For i = 1 To MAX_MAP_NPCS

        If Map(mapnum).NPC(i) > 0 And Map(mapnum).NPC(i) <= MAX_NPCS Then

            If Options.DayNight = 1 Then

                If DayTime = True And NPC(Map(mapnum).NPC(i)).SpawnAtDay = 1 Then

                    Call SpawnNpc(i, mapnum)

                ElseIf DayTime = False And NPC(Map(mapnum).NPC(i)).SpawnAtNight = 1 Then

                    Call SpawnNpc(i, mapnum)

                End If

            Else

                Call SpawnNpc(i, mapnum)

            End If

        End If

    Next

End Sub

In modTypes under npcrec add:

SpawnAtDay As Byte

    SpawnAtNight As Byte

Add this to the bottom of modGameLogic:

Sub DespawnNPC(ByVal mapnum As Long, ByVal NPCNum As Long)

Dim i As Long, Buffer As clsBuffer

    ' Set the NPC data to blank so it despawns.

    MapNpc(mapnum).NPC(NPCNum).Num = 0

    MapNpc(mapnum).NPC(NPCNum).SpawnWait = 0

    MapNpc(mapnum).NPC(NPCNum).Vital(Vitals.HP) = 0

    ' clear DoTs and HoTs

    For i = 1 To MAX_DOTS

        With MapNpc(mapnum).NPC(NPCNum).DoT(i)

            .Spell = 0

            .Timer = 0

            .Caster = 0

            .StartTime = 0

            .Used = False

        End With

        With MapNpc(mapnum).NPC(NPCNum).HoT(i)

            .Spell = 0

            .Timer = 0

            .Caster = 0

            .StartTime = 0

            .Used = False

       End With

    Next

    ' send death to the map

    Set Buffer = New clsBuffer

    Buffer.WriteLong SNpcDead

    Buffer.WriteLong NPCNum

    SendDataToMap mapnum, Buffer.ToArray()

    Set Buffer = Nothing

    'Loop through entire map and purge NPC from targets

    For i = 1 To Player_HighIndex

        If IsPlaying(i) And IsConnected(i) Then

            If Player(i).Map = mapnum Then

                    If TempPlayer(i).targetType = TARGET_TYPE_NPC Then

                        If TempPlayer(i).target = NPCNum Then

                            TempPlayer(i).target = 0

                            TempPlayer(i).targetType = TARGET_TYPE_NONE

                            SendTarget i

                    End If

                End If

            End If

        End If

    Next

End Sub

OK now for the client side:

FormWork: frmEditor_NPC

1. Somewhere make a Check box and name it : chkSday

Set the caption to: Spawn during day

2.Near it make another checkbox and name it : chkSnight

Set the caption to : Spawn at night

Add this code to the bottom of frmEditor_NPC:

' day night

Private Sub chkSDay_Click()

    NPC(EditorIndex).SpawnAtDay = chkSDay.Value

End Sub

Private Sub chkSNight_Click()

    NPC(EditorIndex).SpawnAtNight = chkSNight.Value

End Sub

In modGameEditors find this in NpcEditorInit: .scrlAnimation.Value = NPC(EditorIndex).Animation

Under it add this:

.chkSDay.Value = NPC(EditorIndex).SpawnAtDay

        .chkSNight.Value = NPC(EditorIndex).SpawnAtNight

In modTypes under npcrec add this:

SpawnAtDay As Byte

    SpawnAtNight As Byte

And your done… 😃 will add this to the tut later

Is this now for Dx8/Nightly? Also ; Can you send me the project I sent to you a few days ago? Good work with the tutorial above. =]

Ever talk to General Pony about getting this to work in a Dx8/Nightly environment? =]

That would be entirelly epic to see this work on such a setup.

it works but when you put map 50x50 it start blinking when you walk :S

Hmm I have not had that issue yet zopto, ill look into it…

Log in to reply