PDA

View Full Version : [Tutorial] Linking buildings to captured points



fuggles
13th Jan 09, 4:39 AM
As per the request, please find below a tutorial to set up a buildings on your DoW maps which will be gifted to a player when they capture a nearby point.

Have fun and good luck!

Part 1 - First Things First


Okay, so before we get cracking there are somethings we need to get out the way:

1) This is my third tutorial, so it's likely that it might not be the greatest ever, although I'll try my best and update based on feedback.

2) The methods used in this tutorial are mine and other SCAR coders will have their own ways which might even be better(!) but we can always cross that bridge when we come to it

3) I originally tried setting this up so that when you decap a point then the related building goes back to being neutral/world owned, however this caused a ton of CTD errors as DoW does not like world owned units being thrown in very much. As it is now, if you lose a point then the building remains yours, but it will changes sides if the point is taken, or alternatively, if you blow up the building then it will not return until someone captures the point.

4) Download the tutorial map from:
http://www.mediafire.com/?znfmddaoh2z

and put the files in
C:\Program Files\THQ\Dawn of War - Dark Crusade\DXP2\Data\scenarios\mp

or the Soulstorm equivalent - It's a 2 player map called Capturables Tutorial.

Now, if you have it, open up the map in the map editor, also if you can open up the .SCAR in notepad or Scite then that might be useful.

Setting Up the Map

First up is an overview:
http://img133.imageshack.us/img133/1387/tutorial1wi6.th.jpg (http://img133.imageshack.us/my.php?image=tutorial1wi6.jpg)

Here you can see a selection of buildings and some things which look a bit like fried eggs with labels such as 'spawnpoint1' - these are markers and will be covered a bit later.



CARTOGRAPH...Y? Because I gotta!

So the first thing you need to do is have a map with some points and some buildings. For clarity, it doesn't matter if the points are relics, critical points or strategic points, the code will still work out dandy. I'm not going to teach you how to use the map tool here, just click the toolbar button that looks like a miniature cheerleader with green pompoms and then pop things down that are set to Player 'World' to make them neutral.

Now everything's down and we're ready to go we need to put the builings and capture points into Entity Groups.


What's in a name?

SCAR handles two types of groups, entities (Egroups) and squads (Sgroups). In rough terms, an entity is a building and a squad is a unit and although these groups can be setup dynamically in game, for the sake of scripting its nice and sometimes essential to do it before hand.

Again, I shall presume that you know how to put buildings on the map using the editor, and having done so that you can select them using the drag tool or the cheerleader.

Okay, let's start with the capturable points (CP's). We'll keep it simple and select them one at a time, naming each one consecutively.

To create an Entity group you need to go 'Groups' and then 'Create Entity Group' from the top menu:

http://img70.imageshack.us/img70/121/tutorial3zv9.th.jpg (http://img70.imageshack.us/my.php?image=tutorial3zv9.jpg)

The naming convention for the CP's is for them to be called 'cap_point#' where # is the number you have got to, starting at 1 of course. On the tutorial map there are cap_point1, cap_point2, cap_point3 and cap_point4.

Note that it is possible to select multiple points and put them all in the same Egroup, so that you can set it that you need to capture several points to earn the reward, but for the sake of the tutorial I've kept it to one point per one building.


Now...onto the buildings!

For the associated building the process is exactly the same, albeit with a different Egroup name- Select the building associated with the nearby point and then give them an Egroup name of 'building#' where # is the number that corresponds to the cap_point number. Basically if you get it by capturing 'cap_point1' then the building group will be called 'building1'.


So now everything is labelled in a conformist way (fight the man!) we need to move onto those fried eggs from earlier and look at markers:


A few words about markers

Markers, generally basic markers, are an integral part of SCAR mapping as they allow you to set up points of reference on the map. You may wonder why they are relevent now, but from my experiences in doing this type of coding you have three options when associating a building to a respawn point:

i) The building is normal and if it is destroyed then it is gone forever
ii) The building is invulnerable and can never be destroyed
iii) The building is normal, but if it is destroyed it will be respawned

Now, my personal feeling on i) is that it's a bit rough and removes any sort of back-and-forth quite quickly, ii) causes problems with the AI who will shoot an invulnerable building until the cows come home and effectively stop your game. This just leaves iii) which is the method that I am using. See me enforce my personal opinions upon you! BWAHAHAHAHAHAAAAAA!

For option iii) to work however, we need to put down some markers as to the location of the buildings for when they need to respawn, so let's mark our territory.

The menu for markers is summoned by clicking on the little red flag on the tool bar:

http://img183.imageshack.us/img183/1238/tutorial5pb7.th.jpg (http://img183.imageshack.us/my.php?image=tutorial5pb7.jpg)

From here you need to select BASIC MARKER and then click on the map to put down a marker. Now if you select a marker by clicking on it, or drag selecting you will see the marker info appear in the top right of the screen. There are two values of interest here; name and radius. To edit either of these you double click on them in the marker info window.

For the name, again there is a convention and it has to be 'spawnpoint#' where again the # corresponds to the building number which corresponds to the CP number. The marker should go on the map under where your building starts.

For the radius, this has to be big enough to comfortably go around the building as if it is too small then it will not be spawned. As you can see from the tutorial map, I have generally used 7 but have had to use 14 for the Space Marine vehicle plant as it's quite large.




Part 2 - SCAR Afoot!


Firstly, a SCAR file needs some standard things which make up the basic opening:



import("ScarUtil.scar")
import("WXPScarUtil.scar")
import("WCUtil.scar")


These lines call in the various SCAR libraries that Dawn of War provides. Now we'll look at the OnInit function, which is what will be loaded as soon as the map loads up by use of the Scar_AddInit function:




function OnInit()

t_Players = {}
t_Buildings = {"space_marine_generator","space_marine_vehicle_building","space_marine_turret_bolter","space_marine_orbital_relay_stronghold_sp"}
print"let's go"
t_Buildtime = {}

Rule_AddOneShot(players,0)

end



Scar_AddInit(OnInit)


As indicated by the curly brackets {} you can see that we are creating a table called t_Players, which will be important as you need tables for FOR operators and it's where we will store the player information that the SCAR needs so as to know which player is which.

This will all be set up in the 'players' function, which is why we run it immediately (Rule_AddOneShot means run once, the 0 is time before it is run) and why all the other functions are on an interval delay. When interval delay functions are called, the first number is how often in seconds the function will be run, the second number is the delay in seconds before this kicks off (which in this case is well after the players have been setup).

There are 2 other tables, t_Buildings and t_Buildtime. t_Buildtime will look after itself for now, but I shall explain t_Buildings quickly. As you may have deduced from looking at it, the entries in the t_Buildings table relate to the 'building#' Egroups on the map. This table will tell the code which building type to respawn when it is required. You will need to set this up in the same way for your buildings, as we are using number correlations to keep track of things. You will see later on that the code basically takes a look at 'critpoint1' and if this is captured it checks that 'building1' is okay and if it is not then it get t_Buildings[1] and creates it. The number in the [] is its position in the table, so t_Buildings[3] would be the third value, or "space_marine_turret_bolter".

Note that the values here are entity names, which you can find easily and copy and paste using windows explorer if you have used the mod tools to unpack the DoW data archives. If you have not used the mod tools to unpack everything in a huge folder somewhere, you just need to use the name of the structure shown in the Map Editor when you are placing buildings:

http://img242.imageshack.us/img242/3093/tutorial4oa0.th.jpg (http://img242.imageshack.us/my.php?image=tutorial4oa0.jpg)

Now we have set up our tables and put the wheels in motion.

Love the game, love the players

So let's look at the players function:



function players()
local playerCount = World_GetPlayerCount()
for i = 0, playerCount-1 do
j =( i +1)
t_Players[j] = World_GetPlayerAt(i)
end


Rule_AddInterval(CheckOwnership,1)
end



This function is quite simple and workmanlike. It's well, only feature is a FOR loop which cycles through each start location and assigns a place to each player on the t_Players table. This is purely so we can put all the players in a table for the SCAR to use. Each player is placed into the t_Players table.


Now let's have a look at what you have come here for, the CheckOwnership function.



function CheckOwnership()


--replace 4 with the number of buildings / strategy points that you have
local playerCount = World_GetPlayerCount()

for i = 1, playerCount do
for j = 1, 4 do

if EGroup_IsCapturedByPlayer("cap_point"..j,t_Players[i],true) then
if EGroup_Exists("building"..j) and EGroup_Count(EGroup_FromName("building"..j))==0 then
t_Buildtime[j] = t_Buildtime[j] + 1
if t_Buildtime[j] > 15 then
Entity_CreateBuildingMarker(t_Players[i],"building"..j, t_Buildings[j],"spawnpoint"..j, 1)
end
else t_Buildtime[j] = 0
end

EGroup_SetPlayerOwner("building"..j, t_Players[i])
end


end
end


end



This bones of this function are the two FOR loops, which basically starts with player1, checks point 1 to see if it owned and if so whether building1 is okay, then checks point 2 etc until all the points have been checked for player1, at which point it does the same for player2.

You will see I have put a comment in about replacing the number 4 and this relates to

[I]for j = 1, 4 do[I]

To clarify the 4 here should be the number of 'critpoint' Egroups that you have. On my map I have 4, so it is 1,4 do in the code. If I had 10 different points then 'critpoint10' would be my highest and my code would read 1,10 do

The rest is pretty much as I described earlier - if the point is captured by a player it will check to see if the building is intact. If the building is not intact then you can see that the t_Buildtime value increases. This is in essence a respawn timer - the function runs every second, and this is to give the player some penalty for losing their building and to stop it respawing endlessly at full health.

You can see that there is a line which reads:

if t_Buildtime[j] > 15 then

and here 15 is the respawn time, i.e after 15 seconds of the building not existing, it's time to bring it back. Feel free to adjust this value to personal taste!



...


And that's really it. It's only a simple script and as such only has two user servicable parts, one of which is optional! Hopefully it is of use to you fine folks.



Part 3 - I prefer 'Until we meet again'


So there we have my tutorial - Excelsior!

Hopefully it all makes sense and you have at least a vague grasp of what's going down. It really is all to do with markers and Egroups, so as long as you understand what is making things tick then you'll be okay. If not then pop some kind of distressed post in this thread and I'll be about.


My life veers from stupidly busy to nothing going on and currently I'm in the busy phase, so I haven't given as much time to this as I'd perhaps like, so please forgive my copy and pasting and also if I don't get back to you immediately on any problems!


TTFN

gerberman
13th Jan 09, 11:49 AM
Cracking stuff fuggles, cheers for this!

Lleman
13th Jan 09, 12:07 PM
Interesting tut, fuggles. I'm no SCAR coder but this helps understand it better, and more important, gives lots of ideas.
Cheers! :D