In the previous post we created the structures for our research and construction, and their interface windows. Now we will connect everything and start actually researching and building units.
This is going to be a bit of a pickle since we'll have to update multiple parts of our code, one sub calls another one and they all connect to different parts of the renderer. We need to also restrict which technologies or buildings the player can create based on what is researched until now.
Connecting our data structures to our UI
We'll start by creating visuals for hiding our non researched or non available units and technologies. (We'll simply hide the non available technologies and make the researched ones green, which we will also do for our construction window).
Now let's update our rendering code for our research window first. (Inside SUIWindow = 2 clause)
'New code
For Z = 60 To 87
If Lib_Research_S(Z - 59).Available = 0 Then 'If a technology is not available then draw a gray box over it
sRect = New Rectangle(SButton(Z).X * ScreenWidth, SButton(Z).Y * ScreenHeight, SButton(Z).Width * ScreenWidth, SButton(Z).Height * ScreenHeight)
DrawQuad(sRect.X, sRect.Y, sRect.Width, sRect.Height, 1.0F, 1.0F, 0.04, 0.04, 0.04F)
Else
If Lib_Research_S(Z - 59).Researched = 1 Then 'If a technology has already been researched draw a green box over it
sRect = New Rectangle(SButton(Z).X * ScreenWidth, SButton(Z).Y * ScreenHeight, SButton(Z).Width * ScreenWidth, SButton(Z).Height * ScreenHeight)
DrawQuad(sRect.X, sRect.Y, sRect.Width, sRect.Height, 1.0F, 0.4F, 0.04, 1, 0.04)
End If
End If
Next
'Updated/changed code
If SButtonHover >= 60 And SButtonHover <= 87 Then
If Lib_Research_S(SButtonHover - 59).Available = 1 Then
If Lib_Research_S(SButtonHover - 59).Name.Contains(" ") Then
DrawText(Split(Lib_Research_S(SButtonHover - 59).Name, " ")(0), 697 * (ScreenWidth / UISizeW), 436 * (ScreenHeight / UISizeH), 1.1, 1, 0.8, 0.8, 0.8, 1)
DrawText(Split(Lib_Research_S(SButtonHover - 59).Name, " ")(1), 697 * (ScreenWidth / UISizeW), 446 * (ScreenHeight / UISizeH), 1.1, 1, 0.8, 0.8, 0.8, 1)
DrawText(Int(Lib_Research_S(SButtonHover - 59).Turns - Lib_Research_S(SButtonHover - 59).Turns * (Faction(0).STLibrary.BasicB(1) + Faction(0).STLibrary.BasicB(4) + Faction(0).STLibrary.BasicB(7)) / 100), 783 * (ScreenWidth / UISizeW), 436 * (ScreenHeight / UISizeH), 1.3, 1, 0.8, 0.8, 0.8, 1)
Else
DrawText(Lib_Research_S(SButtonHover - 59).Name, 697 * (ScreenWidth / UISizeW), 436 * (ScreenHeight / UISizeH), 1.1, 1, 0.8, 0.8, 0.8, 1)
DrawText(Int(Lib_Research_S(SButtonHover - 59).Turns - Lib_Research_S(SButtonHover - 59).Turns * (Faction(0).STLibrary.BasicB(1) + Faction(0).STLibrary.BasicB(4) + Faction(0).STLibrary.BasicB(7)) / 100), 783 * (ScreenWidth / UISizeW), 436 * (ScreenHeight / UISizeH), 1.3, 1, 0.8, 0.8, 0.8, 1)
End If
Else
DrawText("None", 697 * (ScreenWidth / UISizeW), 436 * (ScreenHeight / UISizeH), 1.3, 1, 0.8, 0.8, 0.8, 1) 'Construction Hovering over
End If
Else
DrawText("None", 697 * (ScreenWidth / UISizeW), 436 * (ScreenHeight / UISizeH), 1.3, 1, 0.8, 0.8, 0.8, 1) 'Construction Hovering over
End If
The above should give give something like the image below, where we can distinguish researched items and show only the available ones.
And for our unit and building window we do the same process under If SUIWindowConstruct = 1
'New code
For Z = 23 To 58
If Lib_Construct_S(Z - 22).Unlocked = 0 Then 'If a technology is not available then draw a gray box over it
sRect = New Rectangle(SButton(Z).X * ScreenWidth, SButton(Z).Y * ScreenHeight, SButton(Z).Width * ScreenWidth, SButton(Z).Height * ScreenHeight)
DrawQuad(sRect.X, sRect.Y, sRect.Width, sRect.Height, 1.0F, 1.0F, 0.04, 0.04, 0.04F)
End If
Next
'Updated code
If SButtonHover >= 23 And SButtonHover <= 44 Then
If Lib_Construct_S(SButtonHover - 22).Unlocked = 1 Then
DrawText(Lib_Construct_S(SButtonHover - 22).Name & " (" & Int(Lib_Construct_S(SButtonHover - 22).Turns - Lib_Construct_S(SButtonHover - 22).Turns * (Faction(0).STLibrary.BasicB(6) + Faction(0).STLibrary.BasicB(4)) / 100) & ")", 17 * (ScreenWidth / UISizeW), 507 * (ScreenHeight / UISizeH), 1.3, 1, 0.8, 0.8, 0.8, 1) 'Units Hovering over
End If
ElseIf SButtonHover >= 45 And SButtonHover <= 58 Then
If Lib_Construct_S(SButtonHover - 22).Unlocked = 1 Then
DrawText(Lib_Construct_S(SButtonHover - 22).Name & " (" & Int(Lib_Construct_S(SButtonHover - 22).Turns - Lib_Construct_S(SButtonHover - 22).Turns * (Faction(0).STLibrary.BasicB(7) + Faction(0).STLibrary.BasicB(4)) / 100) & ")", 17 * (ScreenWidth / UISizeW), 507 * (ScreenHeight / UISizeH), 1.3, 1, 0.8, 0.8, 0.8, 1) 'Buildings Hovering over
End If
Else
DrawText("None", 21 * (ScreenWidth / UISizeW), 507 * (ScreenHeight / UISizeH), 1.3, 1, 0.8, 0.8, 0.8, 1) 'Construction Hovering over
End If
End If
And we get the following result for the construction window
For the player to start with some researches and units already available I added this code to Game_Library_Construct sub
Q = 1
Lib_Research_S(Q).Researched = 0
Lib_Research_S(Q).Available = 1
Q = 8
Lib_Research_S(Q).Researched = 0
Lib_Research_S(Q).Available = 1
Q = 15
Lib_Research_S(Q).Researched = 0
Lib_Research_S(Q).Available = 1
Q = 22
Lib_Research_S(Q).Researched = 0
Lib_Research_S(Q).Available = 1
Lib_Construct_S(1).Unlocked = 1
Lib_Construct_S(2).Unlocked = 1
Also added these two variables on FactionStruct structure (They will hold current research, turns and flags enabled from some research)
Dim CurResearchTurns As Integer
Dim CanBuildFarms As Integer
Dim CanBuildRoads As Integer
Which will have two units and the four main technology trees available at the start of the game.
Now let's go to our button click clause inside GameButtons("CLICK")
ElseIf sbuttonhover >= 60 And sbuttonhover <= 87 Then
If Lib_Research_S(SButtonHover - 59).Available = 1 And Lib_Research_S(SButtonHover - 59).Researched = 0 Then 'Technology is available and not researched
Faction(0).CurResearchID = SButtonHover - 59
Faction(0).CurResearchTurns = Int(Lib_Research_S(SButtonHover - 59).Turns - Lib_Research_S(SButtonHover - 59).Turns * (Faction(0).STLibrary.BasicB(1) + Faction(0).STLibrary.BasicB(4) + Faction(0).STLibrary.BasicB(7)) / 100)
End If
ElseIf SButtonHover = 88 Then 'If the mouse is over close research button
If SUIWindow = 2 Then
SUIWindow = 0
End If
And creating that button with index (88) that you see above on GameButtons("CREATE") so we can close our research window
SButton(88).Text = "Close Research"
SButton(88).Enabled = 1
SButton(88).X = 694 : SButton(88).Y = 502
SButton(88).Width = 116 : SButton(88).Height = 22
SButton(88).UIState = 2
On Faction_F("END_TURN") add the following
I = 0
If Faction(I).CurResearchID > 0 Then
If Faction(I).CurResearchTurns > 0 Then
Faction(I).CurResearchTurns -= 1
ElseIf Faction(I).CurResearchTurns = 0 Then
Lib_Research_S(Faction(I).CurResearchID).Researched = 1
Game_Library_Construct("REFRESH_RESEARCH", Faction(I).CurResearchID, 0)
Faction(I).CurResearchID = 0
End If
End If
So when the research is finished it will be flagged as researched and will call the sub Game_Library_Construct("REFRESH_RESEARCH", 0, 0) to unlock technologies.
Inside Game_Library_Construct("LOAD",0,0)
For IndexID = 1 To 6 'This loop assigns the research to unlock the next index in the tree of the 4 tech trees
Lib_Research_S(IndexID).ResearchID1 = IndexID + 1
Lib_Research_S(IndexID + 7).ResearchID1 = IndexID + 8
Lib_Research_S(IndexID + 14).ResearchID1 = IndexID + 15
Lib_Research_S(IndexID + 21).ResearchID1 = IndexID + 22
Next
Lib_Research_S(1).ConstructionID1 = 23 : Lib_Research_S(1).ConstructionID2 = 0 'Can build farms
Lib_Research_S(2).ConstructionID1 = 26 : Lib_Research_S(2).ConstructionID2 = 0
Lib_Research_S(3).ConstructionID1 = 6 : Lib_Research_S(3).ConstructionID2 = 0
Lib_Research_S(4).ConstructionID1 = 7 : Lib_Research_S(4).ConstructionID2 = 0
Lib_Research_S(5).ConstructionID1 = 21 : Lib_Research_S(5).ConstructionID2 = 0
Lib_Research_S(6).ConstructionID1 = 10 : Lib_Research_S(6).ConstructionID2 = 0
Lib_Research_S(7).ConstructionID1 = 31 : Lib_Research_S(7).ConstructionID2 = 0
Lib_Research_S(8).ConstructionID1 = 3 : Lib_Research_S(8).ConstructionID2 = 26
Lib_Research_S(9).ConstructionID1 = 5 : Lib_Research_S(9).ConstructionID2 = 27
Lib_Research_S(10).ConstructionID1 = 4 : Lib_Research_S(10).ConstructionID2 = 5
Lib_Research_S(11).ConstructionID1 = 8 : Lib_Research_S(11).ConstructionID2 = 9
Lib_Research_S(12).ConstructionID1 = 11 : Lib_Research_S(12).ConstructionID2 = 0
Lib_Research_S(13).ConstructionID1 = 31 : Lib_Research_S(13).ConstructionID2 = 0
Lib_Research_S(14).ConstructionID1 = 16 : Lib_Research_S(14).ConstructionID2 = 19
Lib_Research_S(15).ConstructionID1 = 0 : Lib_Research_S(15).ConstructionID2 = 0
Lib_Research_S(16).ConstructionID1 = 29 : Lib_Research_S(16).ConstructionID2 = 0 'Can build Roads
Lib_Research_S(17).ConstructionID1 = 14 : Lib_Research_S(17).ConstructionID2 = 25
Lib_Research_S(18).ConstructionID1 = 13 : Lib_Research_S(18).ConstructionID2 = 34
Lib_Research_S(19).ConstructionID1 = 12 : Lib_Research_S(19).ConstructionID2 = 32
Lib_Research_S(20).ConstructionID1 = 36 : Lib_Research_S(20).ConstructionID2 = 0
Lib_Research_S(21).ConstructionID1 = 18 : Lib_Research_S(21).ConstructionID2 = 20
Lib_Research_S(22).ConstructionID1 = 0 : Lib_Research_S(22).ConstructionID2 = 0
Lib_Research_S(23).ConstructionID1 = 24 : Lib_Research_S(23).ConstructionID2 = 0
Lib_Research_S(24).ConstructionID1 = 28 : Lib_Research_S(24).ConstructionID2 = 30
Lib_Research_S(25).ConstructionID1 = 33 : Lib_Research_S(25).ConstructionID2 = 0
Lib_Research_S(26).ConstructionID1 = 0 : Lib_Research_S(26).ConstructionID2 = 0
Lib_Research_S(27).ConstructionID1 = 15 : Lib_Research_S(27).ConstructionID2 = 17
Lib_Research_S(28).ConstructionID1 = 22 : Lib_Research_S(28).ConstructionID2 = 0
So this Index redirecting above will tell us in the next bit of code if technology indexed X is researched, Construction indexed Y is available. Now since I just added some variables like CanBuildRoads like this without indexing we'll just throw them in as available using some exceptions on the next code.
On the same sub Game_Library_Construct create a clause REFRESH_RESEARCH
ElseIf func = "REFRESH_RESEARCH" Then
I = Lib_Research_S(X).ConstructionID1
Q = Lib_Research_S(X).ConstructionID2
Lib_Construct_S(I).Unlocked = 1 'Unlock construction 1
Lib_Construct_S(Q).Unlocked = 1 'Unlock construction 2
Lib_Research_S(Lib_Research_S(X).ResearchID1).Available = 1 'Unlock new research
If X = 1 Then Faction(0).CanBuildFarms = 1
If X = 16 Then Faction(0).CanBuildRoads = 1
As seen on the image, one research unlocked a new one and a building is available for construction.
Now the process of a building or a unit to show up as available for construction is ready and we need to write the code to actually construct it. We need to have a city selected to actually build something, and we are going to add the buildings that are finished in the city screen render afterwards.
Let's go step by step with images since this is going to be a bit long.
Constructing units and buildings
Adding buttons to shuffle through our cities - GameButtons("CREATE")
SButton(89).Text = "Previous city"
SButton(89).Enabled = 1
SButton(89).X = 638 : SButton(89).Y = 326
SButton(89).Width = 15 : SButton(89).Height = 15
SButton(89).UIState = 1
SButton(90).Text = "Next city"
SButton(90).Enabled = 1
SButton(90).X = 800 : SButton(90).Y = 326
SButton(90).Width = 15 : SButton(90).Height = 15
SButton(90).UIState = 1
Using buttons to shuffle through our cities - GameButtons("CLICK")
ElseIf SButtonHover = 89 Then 'Go to the previous city
If SUICity > 0 Then
If Faction(0).City(SUICity - 1).Enabled = 1 Then
SUICity -= 1
End If
End If
ElseIf SButtonHover = 90 Then 'Go to the next city
If SUICity < MaxCitiesPF Then
If Faction(0).City(SUICity + 1).Enabled = 1 Then
SUICity += 1
End If
End If
Now that we can shuffle through our cities let's create a clause when clicking construct, in case the faction window is open but there is no city available (settlers only)
On button (22) click event add this clause
If Faction(0).City(SUICity).Enabled = 1 Then
SUIWindowConstruct = 1
End If
Now onwards to assigning something to get constructed
Inside our city struct add this variable : Dim Constructed() As Integer 'Holds index for built constructs
Inside our Faction_F("CREATE_FACTIONS") :
For Q = 0 To MaxCitiesPF
ReDim Faction(I).City(Q).Constructed(100)
Next
On button click
ElseIf sbuttonhover >= 23 And sbuttonhover <= 44 Then 'Constructing unit buttons
If Lib_Construct_S(SButtonHover - 22).Unlocked = 1 Then 'Unit is available to construct
Faction(0).City(SUICity).ConstructionID = SButtonHover - 22
Faction(0).City(SUICity).ConstructTurns = Int(Lib_Construct_S(SButtonHover - 22).Turns - Lib_Construct_S(SButtonHover - 22).Turns * (Faction(0).STLibrary.BasicB(6) + Faction(0).STLibrary.BasicB(4)) / 100)
End If
ElseIf sbuttonhover >= 45 And sbuttonhover <= 58 Then 'Constructing buildings buttons
If Lib_Construct_S(SButtonHover - 22).Unlocked = 1 Then 'building is available to construct
If Faction(0).City(SUICity).Constructed(SButtonHover - 22) = 0 Then 'If this building has not been built
Faction(0).City(SUICity).ConstructionID = SButtonHover - 22
Faction(0).City(SUICity).ConstructTurns = Int(Lib_Construct_S(SButtonHover - 22).Turns - Lib_Construct_S(SButtonHover - 22).Turns * (Faction(0).STLibrary.BasicB(7) + Faction(0).STLibrary.BasicB(4)) / 100)
End If
End If
Inside our city rendering
If Faction(0).City(SUICity).ConstructionID <> 0 Then
DrawText(Lib_Construct_S(Faction(0).City(SUICity).ConstructionID).Name, 642 * (ScreenWidth / UISizeW), (414) * (ScreenHeight / UISizeH), 1.2, 1, 0.8, 0.8, 0.8, 1)
DrawText(Faction(0).City(SUICity).ConstructTurns, 784 * (ScreenWidth / UISizeW), (414) * (ScreenHeight / UISizeH), 1.2, 1, 0.8, 0.8, 0.8, 1)
Else
DrawText("No construction", 642 * (ScreenWidth / UISizeW), (414) * (ScreenHeight / UISizeH), 1.2, 1, 0.8, 0.8, 0.8, 1)
DrawText("+1", 784 * (ScreenWidth / UISizeW), (414) * (ScreenHeight / UISizeH), 1.2, 1, 0.8, 0.8, 0.8, 1)
End If
Now we have almost all of our construction visuals and our clicking references ready so we can update our end turn code.
For I = 0 To MaxFactions
For Q = 0 To MaxCitiesPF
If Faction(I).City(Q).ConstructionID > 0 Then
If Faction(I).City(Q).ConstructTurns > 0 Then
Faction(I).City(Q).ConstructTurns -= 1
Else 'If turns are finished
If Faction(I).City(Q).ConstructionID <= 22 Then 'If it's a unit that finished construction
CREATE_UNIT(Faction(I).City(Q).ConstructionID, Q, I)
Else 'If it's a building that finished construction
Faction(I).City(Q).Constructed(Faction(I).City(Q).ConstructionID) = 1
End If
Faction(I).City(Q).ConstructionID = 0 'Null construction
End If
Else 'No construction
Faction(I).STLibrary.BasicA(1) += 1 'Add to treasury
End If
Next
Next
When a unit is finished as you see above calls a new sub called CREATE_UNIT so let's add that sub.
Public Sub CREATE_UNIT(ByVal UnitID As Integer, ByVal CityID As Integer, ByVal FactionID As Integer)
Dim I, Q As Integer
For I = 0 To MaxUnitsPF
If Faction(FactionID).Unit(I).ID = 0 Then
Q = I
Exit For
End If
Next
Faction(FactionID).Unit(Q).ID = UnitID
Faction(FactionID).Unit(Q).TileX = Faction(FactionID).City(CityID).TileX
Faction(FactionID).Unit(Q).TileY = Faction(FactionID).City(CityID).TileY
Dim X, Y As Integer
X = Faction(FactionID).Unit(Q).TileX
Y = Faction(FactionID).Unit(Q).TileY
Faction(FactionID).Unit(Q).X = ((X - Y) * GridWidth / 2) * ZoomVar 'Making sure it gets the proper X,Y based on resizing
Faction(FactionID).Unit(Q).Y = ((X + Y) * GridHeight / 2) * ZoomVar 'Making sure it gets the proper X,Y based on resizing
Faction(FactionID).Unit(Q).TargetX = Faction(FactionID).Unit(Q).X
Faction(FactionID).Unit(Q).TargetY = Faction(FactionID).Unit(Q).Y
Faction(FactionID).Unit(Q).TurnPoints = 2
Unit_F("MOVE_CALCULATE", Q)
End Sub
The above new sub creates the unit specified, places it on the city that created it and calculates possible moves for it.
Units are finished, now let's create some visuals for the buildings too.
If you check above what happens when a building construction is finished, you'll see this line of code Faction(I).City(Q).Constructed(Faction(I).City(Q).ConstructionID) = 1, which is in effect a boolean. Let's do something with this boolean and our interface sprite sheet.
For Z = 23 To 36
If Faction(0).City(SUICity).Constructed(Z) = 1 Then
sRect = New Rectangle(280 + (Z - 22) * 23, 281, 23, 16)
If Z <= 28 Then
dRect = New Rectangle(660 * (ScreenWidth / UISizeW) + (Z - 23) * 23 * (ScreenWidth / UISizeW), 358 * (ScreenHeight / UISizeH), sRect.Width * (ScreenWidth / UISizeW), sRect.Height * (ScreenHeight / UISizeH))
ElseIf Z <= 32 Then
dRect = New Rectangle(660 * (ScreenWidth / UISizeW) + (Z - 28) * 23 * (ScreenWidth / UISizeW), 372 * (ScreenHeight / UISizeH), sRect.Width * (ScreenWidth / UISizeW), sRect.Height * (ScreenHeight / UISizeH))
Else
dRect = New Rectangle(660 * (ScreenWidth / UISizeW) + (Z - 32) * 23 * (ScreenWidth / UISizeW), 386 * (ScreenHeight / UISizeH), sRect.Width * (ScreenWidth / UISizeW), sRect.Height * (ScreenHeight / UISizeH))
End If
DrawTexturedQuad(sRect, dRect, 907, 548, 3, 1.0F, 1, 1, 1, 1)
End If
Next
The above code, when construction on a building finishes will take the building from the sprite sheet and place them as seen below.
These buildings draw on index order so their place on the window is fixed, if you want them to draw the one after the other one you can just create a second list and populate it with the current ones and their build order.
Comments
Post a Comment