Contents Back Forward |
11. Attack Thread |
11.1 Attack Thread overview In this chapter we will face the last thread: the Attack Thread. Attack Thread continuosly scans Tot memory searching for a battle, when a battle takes place the attack thread will wait until it ends and then execute user-defined AttackCheck; Why it waits 'till the end of the battle? for a couple of reasons: 1) since i'm not able to freeze tot but only to read/write in its memory, it could be risky to let user access to attack structures while tot is busy in reading/writing them ('cause an attack is taking place). 2) In this way the designer can gain more information on battle, as who won, who lost, how much health the winner has lost in the battle and so on. Again the exact source-code of Attack Thread is very complex so i decided to let it out. Anyway you must know only one think to use AttackThread: AttackCheck will be executed after each battle in the game. | 11.2 Attack functions There are no specific attack function in CSPL, this because usually you can access all structures you need using Unit functions. Anyway AttackCheck is a special function which requires an explanation because it's different from other XXXXCheck functions we've seen before 'cause it takes parameters: void AttackCheck(Unit* Attacker,Unit* Attacked,BOOL Winner) As you can see AttackCheck takes three parameters: two pointers to Unit structures (Attacker & Attacked) and one boolean (Winner) Obviously Attacker is the unit which started the battle Attacked is the unit which has been attacked by attacker and Winner is a flag which is TRUE if Attacker won the battle, FALSE otherwise. Notice that if Winner is TRUE Attacked is removed by Civ2, if Winner is FALSE Attacker is removed by Civ2, so, even if you can still access to their data structures (CSPL will back up Attacker & Attacked units to avoid that Civ2 overwrite them with newly built units), if you want to make the loser unit to win (changing the result of Civ2 battle), you should first destroy the winner unit and then create a new unit with values copied by loser Unit structure. NOTICE: Even if you can change the result of a battle, this cannot be done in a complete way, because if a unit is destroyed all units which are on the same stack will be lost forever and you couldn't catch infos on them (this is a Civ2 limit as you can notice thinking a bit on what happens when you smash a barbarian unit stacked with a leader, who´s the first to guess what i mean? ;o) ) |
11.3 Example 10 : EnhancedUnits In Civilization2 winning a battle against an enemy unit could bring to the winner unit the veteran status but nothing particular interesting. In Colonization instead, when indians were able to defeat europeans soldiers, they could seize the rifles (or horses) changing their unit into another(natives+guns) more powerful. There are a lot of situations in Civ2 where a similar functionality would be very useful (in sci-fi or fantasy scenarios for example, apart from historical example given above), we could imagine also a hierarchy of levels: starting from level0 units will battle against other units gaining sometimes (for each 10 units killed or something similar) a level advance and changing their unit type. Again, you can use the exact opposite, if after a battle the winner unit has a health bar in red, this means it sustained too much damages and it is transformed into a weaker unit type (until the player takes it to a friendly city etc etc but this is something i let designers to investigate). Now we will try to use attack thread to give Tot a similar effect: In a real scenario probably level0 units will be very weak, forcing the player to waste a lot of level0 units to obtain some level1 unit, anyway, since this is an example and we don't want to wait 50 turns building and wasting units only to see if this effects work we will take powerful level0 units (dragoons), more powerful level1 units (Cavalry) with a weak enemy unit (warrior) To test it we will start a new game and using the cheat menu we will add some dragoons and warriors units. PHASE 0: CREATING A NEW PROJECTAs we've learned in the previous chapters the first step towards CSPL compilation is the project creation (usually done with CSPLCompanion);again create a new project called EnhancedUnits. PHASE 1: UNDERSTANDING WHAT WE NEEDThe first thing a CSPL designer should think is : "which thread i need?"In this situation, we will try to use only AttackThread, and this seems right since our changes are tied to attack routines. PHASE 2: DESIGNING THE EVENTThe next thing we have to do is to design the "skeleton" of our event:From the first chapter we know that event is made of HEAD (Trigger Statement) and BODY (Action Statement): In this case HEAD is "A dragoon has won a battle against a warrior" while BODY is "The winner unit should became a Cavalry." PHASE 3: FIXING UP SECONDARY PROBLEMSThe event designed in phase 2 leaves a lot of problems still open:First of all, there is only one Wonder so we need to ensure that it will be only one Special King Unit in the whole game. This can be done creating King Unit as a special unit, this means fixing prereq to no and giving a single unit to a particular civ (using for example events or giving it to one civ from start). Another problem is with wonder: we must ensure that no one will ever build that wonder (again, this can be obtained with no prereq) Another problem: what we should do while King is in transit between cities? in my opinion wonder should be destroyed and re-established when King units enters in a new city. In that way, if the King is killed while moving, the wonder effect is lost forever. Now we've cleared a couple of things about the event we should realize and we can start develping it PHASE 4: CODING THE EVENTThis time it's easy: since when AttackCheck is called we know that a battle took place we will start searching for the winner.If Winner is TRUE and attacker is a dragoon and attacked is a warrior we should trigger the event. If Winner is FALSE and attacker is a warrior and attacked is a dragoon we should trigger the event. else we shouldn´t trigger the event. Let's write a bit of code (obviously we are in AttackCheck function so we knows that Winner is a boolean indicating the battle winner, Attacker and Attacked are pointers to Unit structures)
Obviously now we need to define this ChangeType(Unit* Temp) function we used above:This function obviously should change the type of Unit structure pointed by Temp pointer and write back the changed info to Tot memory: Let's see how this can be done:
void ChangeType(Unit* Temp)
We should also add a messagebox warning the player of the unit enhancement:
void ChangeType(Unit* Temp)
We should remember to sign our ChangeType function in used-section of cspl.h and also that the code written above should be written in AttackCheck function:
PHASE 5: MERGING THE RESULTING SOURCE CODENow it's time to merge all source code we've written:Editing CSPLClient.h: In CSPLClient.h we need to activate the attack thread: BYTE ACTIVITY_FLAG=ACTIVATE_ATTACK; Then we need to write down the signature of user-defined ChangeType function: void ChangeType(Unit* Attacked); And we've finished with CSPLClient.h . Editing CSPLClient.csp: We have two things to do: The first one is to write down the AttackCheck implementation:
And now we need to write down the ChangeType function:
void ChangeType(Unit* Temp)
And we've finished also with cspl.csp PHASE 6: COMPILING AND LINKING THE SOURCE CODEAt this point save CSPLClient.h and CSPLClient.csp files and use CSPLCompanion to compile and link EnhancedUnits;you should obtain a CSPLClient executable in EnhancedUnits directory, To test this example you should create a game with a couple of dragoons units and some enemy warriors nearby; start CSPLClient.exe and attacks Warriors unit with your Dragoons, each time you win a battle your Dragoon unit should became a cavalry one. Notice that exists a lot of possible ways to modify this event, but this one is is probably the most simple; You could change the AttackCheck code to trigger the event with any enemy units, or to trigger only when unit is attacking or again, only when dragoon unit is owned by a human, or you can use global variables to trigger the event only when a unit win 10 battles and so on. |