From 1253b8c1ece3af78a35586ecd02f056a7b3cdd29 Mon Sep 17 00:00:00 2001 From: johns <> Date: Mon, 16 Apr 2001 00:16:36 +0000 Subject: [PATCH] Upgrades now supports changing the unit-type of already build units. --- doc/ChangeLog.html | 3 +- src/include/player.h | 24 +- src/include/upgrade.h | 45 ++-- src/include/upgrade_structs.h | 116 +++++---- src/unit/upgrade.cpp | 469 +++++++++++++++++----------------- 5 files changed, 343 insertions(+), 314 deletions(-) diff --git a/doc/ChangeLog.html b/doc/ChangeLog.html index 73378d700..53b0b8d38 100644 --- a/doc/ChangeLog.html +++ b/doc/ChangeLog.html @@ -600,7 +600,7 @@ <LI>Spell death and decay handled now like original. <LI>Spell whirlwind now moves correct and did the correct damage on the correct position. - <LI>Spell raise dead removes the corpse and works on djacent fields. + <LI>Spell raise dead removes the corpse and works on adjacent fields. <LI>Added decay of units, eye of k. and skeletons dies after some seconds. <LI>Spell blizzard handled more like the original. <LI>Spell runes works now correct. @@ -608,6 +608,7 @@ (from Latimerius) <LI>Fixed bug: Spells hits unit without hitpoints, dumps core. (from Latimerius) + <LI>Upgrades now supports changing the unit-type of already build units. <LI>+++ </UL> </UL> diff --git a/src/include/player.h b/src/include/player.h index 4271e8724..78c190652 100644 --- a/src/include/player.h +++ b/src/include/player.h @@ -10,7 +10,7 @@ // /**@name player.h - The player headerfile. */ // -// (c) Copyright 1998-2000 by Lutz Sammer +// (c) Copyright 1998-2001 by Lutz Sammer // // $Id$ @@ -19,6 +19,26 @@ //@{ +/*---------------------------------------------------------------------------- +-- Documentation +----------------------------------------------------------------------------*/ + +/** +** @struct _player_ player.h +** +** \#include "player.h" +** +** typedef struct _player_ Player; +** +** This structure contains all informations about a player in game. +** +** The player structure members: +** +** Player::Player +** +** FIXME: not written documentation +*/ + /*---------------------------------------------------------------------------- -- Includes ----------------------------------------------------------------------------*/ @@ -98,7 +118,7 @@ struct _player_ { // Upgrades/Allows: Allow Allow; /// Allowed for player - UpgradeTimers UTimers; /// Timer for the upgrades + UpgradeTimers UpgradeTimers; /// Timer for the upgrades }; /* diff --git a/src/include/upgrade.h b/src/include/upgrade.h index 55826c575..a638ae121 100644 --- a/src/include/upgrade.h +++ b/src/include/upgrade.h @@ -9,11 +9,10 @@ // FreeCraft - A free fantasy real time strategy game engine // /**@name upgrade.h - The upgrades headerfile. */ -/* -** (c) Copyright 1999,2000 by Vladi Belperchinov-Shabanski -** -** $Id$ -*/ +// +// (c) Copyright 1999-2001 by Vladi Belperchinov-Shabanski +// +// $Id$ #ifndef __UPGRADE_H__ #define __UPGRADE_H__ @@ -43,13 +42,18 @@ typedef struct _player_ Player; // recursive includes :( -- Functions ----------------------------------------------------------------------------*/ -extern void InitUpgrades(void); /// init upgrade/allow structures -extern Upgrade* UpgradeByIdent(const char*); /// upgrade of identifier -extern void SaveUpgrades(FILE*); /// save the upgrades -extern void ParsePudALOW(const char*,int); /// parse pud alow table -extern void ParsePudUGRD(const char*,int); /// parse pud ugrd table -extern void UpgradesCclRegister(void); /// Register CCL features for upgrades - + /// init upgrade/allow structures +extern void InitUpgrades(void); + /// upgrade of identifier +extern Upgrade* UpgradeByIdent(const char*); + /// save the upgrades +extern void SaveUpgrades(FILE*); + /// parse pud alow (upgrade/spell/units allow) table +extern void ParsePudALOW(const char*,int); + /// parse pud ugrd (upgrade cost) table +extern void ParsePudUGRD(const char*,int); + /// Register CCL features for upgrades +extern void UpgradesCclRegister(void); // CHAOS PUR @@ -147,24 +151,23 @@ extern int ActionIdByIdent( const char* sid ); -- Upgrades ----------------------------------------------------------------------------*/ -// amount==-1 to cancel upgrade, could happen when building destroyed during upgrade -// using this we could have one upgrade research in two buildings, so we can have -// this upgrade faster. -void UpgradeIncTime( Player* player, int id, int amount ); -void UpgradeIncTime2( Player* player, char* sid, int amount ); // by ident string + /// Upgrade will be acquired, called by UpgradeIncTime() when timer reached +extern void UpgradeAcquire( Player* player,const Upgrade* upgrade ); + + /// Increment the upgrade timer. +extern void UpgradeIncTime( Player* player, int id, int amount ); +extern void UpgradeIncTime2( Player* player, char* sid, int amount ); // by ident string // this function will mark upgrade done and do all required modifications to // unit types and will modify allow/forbid maps - // called by UpgradeIncTime() when timer reached -void UpgradeAcquire( Player* player,Upgrade* upgrade ); // for now it will be empty? // perhaps acquired upgrade can be lost if ( for example ) a building is lost // ( lumber mill? stronghold? ) // this function will apply all modifiers in reverse way -void UpgradeLost( Player* player, int id ); -void UpgradeLost2( Player* player, char* sid ); // by ident string +extern void UpgradeLost( Player* player, int id ); +extern void UpgradeLost2( Player* player, char* sid ); // by ident string /*---------------------------------------------------------------------------- -- Allow(s) diff --git a/src/include/upgrade_structs.h b/src/include/upgrade_structs.h index 9b7c9dae2..f409cf381 100644 --- a/src/include/upgrade_structs.h +++ b/src/include/upgrade_structs.h @@ -39,8 +39,6 @@ #define MAXUNITTYPES MAXUACOUNT /// max upgrades count #define MAXUPGRADES MAXUACOUNT - /// max actions count -#define MAXACTIONS MAXUACOUNT // include spells /*---------------------------------------------------------------------------- -- Declarations @@ -120,6 +118,51 @@ typedef struct _upgrade_ { IconConfig Icon; /// icon to display to the user } Upgrade; +/*---------------------------------------------------------------------------- +-- upgrades and modifiers +----------------------------------------------------------------------------*/ + +/** +** Modifiers of the unit stats. +** All the following are modifiers not values! +** @see UnitStats +*/ +typedef struct _modifiers_ { + int AttackRange; /// attack range modifier + int SightRange; /// sight range modifier + int BasicDamage; /// basic damage modifier + int PiercingDamage; /// piercing damage modifier + int Armor; /// armor modifier + int Speed; /// speed modifier (FIXME: not working) + int HitPoints; /// hit points modifier + + int Costs[MaxCosts]; /// costs modifier +} Modifiers; + +/** +** This is the modifier of an upgrade. +** This do the real action of an upgrade, an upgrade can have multiple +** modifiers. +*/ +typedef struct _upgrade_modifier_ { + + int UpgradeId; /// used to filter required modifier + + Modifiers Modifier; /// modifier of unit stats + + // allow/forbid bitmaps -- used as chars for example: + // `?' -- leave as is, `F' -- forbid, `A' -- allow + // FIXME: see below allow more semantics? + // FIXME: pointers or ids would be faster and less memory use + char ChangeUnits[MAXUNITTYPES]; /// allow/forbid units + char ChangeUpgrades[MAXUPGRADES]; /// allow/forbid upgrades + char ApplyTo[MAXUNITTYPES]; /// which unit types are affected + + // FIXME: UnitType* + void* ConvertTo; /// convert to this unit-type. + +} UpgradeModifier; + /** ** Allow what a player can do. Every player has an own Allow struct. ** @@ -134,10 +177,23 @@ typedef struct _upgrade_ { */ typedef struct _allow_ { char Units[MAXUNITTYPES]; /// Units allowed/disallowed - // FIXME: Actions isn't used yet. - //char Actions[MAXACTIONS]; /// Actions allowed/disallowed char Upgrades[MAXUPGRADES]; /// Upgrades allowed/disallowed } Allow; + +/** +** Upgrade timer used in the player structure. +** Every player has an own UpgradeTimers struct. +*/ +typedef struct _upgrade_timers_ { + + /** + ** all 0 at the beginning, all upgrade actions do increment values in + ** this struct. + */ + int Upgrades[MAXUPGRADES]; /// Counter for each upgrade + +} UpgradeTimers; + /*---------------------------------------------------------------------------- -- Variables ----------------------------------------------------------------------------*/ @@ -145,58 +201,6 @@ typedef struct _allow_ { extern const char UpgradeType[]; /// upgrade type extern Upgrade Upgrades[MAXUACOUNT]; /// The main user useable upgrades - - - -//Cleaning this -//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -/*---------------------------------------------------------------------------- --- upgrades and modifiers -----------------------------------------------------------------------------*/ - -typedef struct _modifiers_ { - // all the following are modifiers not values! - int AttackRange; /// attack range modifier - int SightRange; /// sight range modifier - int BasicDamage; /// basic damage modifier - int PiercingDamage; /// piercing damage modifier - int Armor; /// armor modifier - int Speed; /// speed modifier (FIXME: not working) - int HitPoints; /// hit points modifier - - int Costs[MaxCosts]; /// costs modifier -} Modifiers; - -typedef struct _upgrade_modifier_ { - - int uid; // used to filter required by upgrade modifiers - - Modifiers mods; - - // allow/forbid bitmaps -- used as chars for example: - // `?' -- leave as is, `F' -- forbid, `A' -- allow - // FIXME: pointers or ids would be faster and less memory use - char af_units[MAXUNITTYPES]; // allow/forbid units - //char af_actions[MAXACTIONS]; // allow/forbid actions - char af_upgrades[MAXUPGRADES]; // allow/forbid upgrades - char apply_to[MAXUNITTYPES]; // which unit types are affected - -} UpgradeModifier; - -typedef struct _upgrade_timers_ { - - // all 0 at the beginning, all upgrade actions do increment values in - // this struct, every player has own UpgradeTimers struct - int upgrades[MAXUPGRADES]; - -} UpgradeTimers; - - //@} #endif // !__UPGRADE_STRUCTS_H__ diff --git a/src/unit/upgrade.cpp b/src/unit/upgrade.cpp index a1b6af418..67f7d9d00 100644 --- a/src/unit/upgrade.cpp +++ b/src/unit/upgrade.cpp @@ -35,9 +35,9 @@ #include "etlib/hash.h" local int AddUpgradeModifierBase(int,int,int,int,int,int,int,int,int*, - const char*,const char*,const char*,const char*); + const char*,const char*,const char*,UnitType*); local int AddUpgradeModifier(int,int,int,int,int,int,int,int,int*, - const char*,const char*,const char*,const char*); + const char*,const char*,const char*); /*---------------------------------------------------------------------------- -- Variables @@ -83,6 +83,8 @@ local struct _wc_upgrades_ { int CostsModifier[MaxCosts];/// costs modifier const char* Units; /// units affected + + const char* ConvertTo; /// convert to this unit } WcUpgrades[] = { // Name Icon // Time Gold Wood Oil At Si BD PD Ar Sp HP Time Gold Wood Oil @@ -387,10 +389,6 @@ local void SetupAllow(void) ,sizeof(Players[z].Allow.Upgrades)); memset(Players[z].Allow.Units,'A' ,sizeof(Players[z].Allow.Units)); -#if 0 - memset(Players[z].Allow.Actions,'A' - ,sizeof(Players[z].Allow.Actions)); -#endif } // Give some upgrades as default. @@ -836,69 +834,74 @@ global void SaveUpgrades(FILE* file) // for( i=0; i<UpgradeModifiersCount; ++i ) { fprintf(file,"(define-modifier '%s", - Upgrades[UpgradeModifiers[i]->uid].Ident); + Upgrades[UpgradeModifiers[i]->UpgradeId].Ident); - if( UpgradeModifiers[i]->mods.AttackRange ) { + if( UpgradeModifiers[i]->Modifier.AttackRange ) { fprintf(file,"\n '(attack-range %d)" - ,UpgradeModifiers[i]->mods.AttackRange ); + ,UpgradeModifiers[i]->Modifier.AttackRange ); } - if( UpgradeModifiers[i]->mods.SightRange ) { + if( UpgradeModifiers[i]->Modifier.SightRange ) { fprintf(file,"\n '(sight-range %d)" - ,UpgradeModifiers[i]->mods.SightRange ); + ,UpgradeModifiers[i]->Modifier.SightRange ); } - if( UpgradeModifiers[i]->mods.SightRange ) { + if( UpgradeModifiers[i]->Modifier.SightRange ) { fprintf(file,"\n '(attack-range %d)" - ,UpgradeModifiers[i]->mods.SightRange ); + ,UpgradeModifiers[i]->Modifier.SightRange ); } - if( UpgradeModifiers[i]->mods.BasicDamage ) { + if( UpgradeModifiers[i]->Modifier.BasicDamage ) { fprintf(file,"\n '(basic-damage %d)" - ,UpgradeModifiers[i]->mods.BasicDamage ); + ,UpgradeModifiers[i]->Modifier.BasicDamage ); } - if( UpgradeModifiers[i]->mods.PiercingDamage ) { + if( UpgradeModifiers[i]->Modifier.PiercingDamage ) { fprintf(file,"\n '(piercing-damage %d)" - ,UpgradeModifiers[i]->mods.PiercingDamage ); + ,UpgradeModifiers[i]->Modifier.PiercingDamage ); } - if( UpgradeModifiers[i]->mods.Armor ) { + if( UpgradeModifiers[i]->Modifier.Armor ) { fprintf(file,"\n '(armor %d)" - ,UpgradeModifiers[i]->mods.Armor ); + ,UpgradeModifiers[i]->Modifier.Armor ); } - if( UpgradeModifiers[i]->mods.Speed ) { + if( UpgradeModifiers[i]->Modifier.Speed ) { fprintf(file,"\n '(speed %d)" - ,UpgradeModifiers[i]->mods.Speed ); + ,UpgradeModifiers[i]->Modifier.Speed ); } - if( UpgradeModifiers[i]->mods.HitPoints ) { + if( UpgradeModifiers[i]->Modifier.HitPoints ) { fprintf(file,"\n '(hit-points %d)" - ,UpgradeModifiers[i]->mods.HitPoints ); + ,UpgradeModifiers[i]->Modifier.HitPoints ); } for( j=0; j<MaxCosts; ++j ) { - if( UpgradeModifiers[i]->mods.Costs[j] ) { + if( UpgradeModifiers[i]->Modifier.Costs[j] ) { fprintf(file,"\n '(%s-cost %d)" - ,DEFAULT_NAMES[j],UpgradeModifiers[i]->mods.Costs[j]); + ,DEFAULT_NAMES[j],UpgradeModifiers[i]->Modifier.Costs[j]); } } for( j=0; j<MAXUNITTYPES; ++j ) { // allow/forbid units - if( UpgradeModifiers[i]->af_units[j]!='?' ) { + if( UpgradeModifiers[i]->ChangeUnits[j]!='?' ) { fprintf(file,"\n '(allow %s %d)", UnitTypes[j].Ident, - UpgradeModifiers[i]->af_units[j]); + UpgradeModifiers[i]->ChangeUnits[j]); } } for( j=0; j<MAXUPGRADES; ++j ) { // allow/forbid upgrades - if( UpgradeModifiers[i]->af_upgrades[j]!='?' ) { + if( UpgradeModifiers[i]->ChangeUpgrades[j]!='?' ) { fprintf(file,"\n '(allow %s %c)",Upgrades[j].Ident, - UpgradeModifiers[i]->af_upgrades[j]); + UpgradeModifiers[i]->ChangeUpgrades[j]); } } for( j=0; j<MAXUNITTYPES; ++j ) { // apply to units - if( UpgradeModifiers[i]->apply_to[j]!='?' ) { + if( UpgradeModifiers[i]->ApplyTo[j]!='?' ) { fprintf(file,"\n '(apply-to %s)",UnitTypes[j].Ident); } } + if( UpgradeModifiers[i]->ConvertTo ) { + fprintf(file,"\n '(convert-to %s)", + ((UnitType*)UpgradeModifiers[i]->ConvertTo)->Ident); + } + fprintf(file,")\n\n"); } @@ -973,6 +976,7 @@ local SCM CclDefineModifier(SCM list) char units[MAXUNITTYPES]; char upgrades[MAXUPGRADES]; char apply_to[MAXUNITTYPES]; + UnitType* convert_to; attack_range=0; sight_range=0; @@ -985,6 +989,7 @@ local SCM CclDefineModifier(SCM list) memset(units,'?',sizeof(units)); memset(upgrades,'?',sizeof(upgrades)); memset(apply_to,'?',sizeof(apply_to)); + convert_to=NULL; value=gh_car(list); list=gh_cdr(list); @@ -1050,6 +1055,11 @@ local SCM CclDefineModifier(SCM list) str=gh_scm2newstr(gh_car(value),NULL); apply_to[UnitTypeIdByIdent(str)]='X'; free(str); + } else if( gh_eq_p(temp,gh_symbol2scm("convert-to")) ) { + value=gh_cdr(value); + str=gh_scm2newstr(gh_car(value),NULL); + convert_to=UnitTypeByIdent(str); + free(str); } else { errl("wrong tag",temp); return SCM_UNSPECIFIED; @@ -1058,7 +1068,7 @@ local SCM CclDefineModifier(SCM list) AddUpgradeModifierBase(uid,attack_range,sight_range, basic_damage,piercing_damage,armor,speed,hit_points,costs, - units,NULL,upgrades,apply_to); + units,upgrades,apply_to,convert_to); return SCM_UNSPECIFIED; } @@ -1262,10 +1272,10 @@ void UpgradesDone(void) // free upgrade/allow structures #endif // returns upgrade modifier id or -1 for error ( actually this id is useless, just error checking ) -local int AddUpgradeModifierBase(int aUid,int aattack_range,int asight_range, - int abasic_damage,int apiercing_damage,int aarmor,int aspeed, - int ahit_points,int* acosts,const char* aaf_units,const char* aaf_actions, - const char* aaf_upgrades,const char* aapply_to) +local int AddUpgradeModifierBase(int uid,int attack_range,int sight_range, + int basic_damage,int piercing_damage,int armor,int speed, + int hit_points,int* costs,const char* af_units, + const char* af_upgrades,const char* apply_to,UnitType* convert_to) { int i; UpgradeModifier *um; @@ -1275,27 +1285,26 @@ local int AddUpgradeModifierBase(int aUid,int aattack_range,int asight_range, return -1; } - um->uid = aUid; + um->UpgradeId = uid; // get/save stats modifiers - um->mods.AttackRange = aattack_range; - um->mods.SightRange = asight_range; - um->mods.BasicDamage = abasic_damage; - um->mods.PiercingDamage = apiercing_damage; - um->mods.Armor = aarmor; - um->mods.Speed = aspeed; - um->mods.HitPoints = ahit_points; + um->Modifier.AttackRange = attack_range; + um->Modifier.SightRange = sight_range; + um->Modifier.BasicDamage = basic_damage; + um->Modifier.PiercingDamage = piercing_damage; + um->Modifier.Armor = armor; + um->Modifier.Speed = speed; + um->Modifier.HitPoints = hit_points; for( i=0; i<MaxCosts; ++i ) { - um->mods.Costs[i] = acosts[i]; + um->Modifier.Costs[i] = costs[i]; } - memcpy(um->af_units,aaf_units,sizeof(um->af_units)); -#if 0 - memcpy(um->af_actions,aaf_actions,sizeof(um->af_actions)); -#endif - memcpy(um->af_upgrades,aaf_upgrades,sizeof(um->af_upgrades)); - memcpy(um->apply_to,aapply_to,sizeof(um->apply_to)); + memcpy(um->ChangeUnits,af_units,sizeof(um->ChangeUnits)); + memcpy(um->ChangeUpgrades,af_upgrades,sizeof(um->ChangeUpgrades)); + memcpy(um->ApplyTo,apply_to,sizeof(um->ApplyTo)); + + um->ConvertTo=convert_to; UpgradeModifiers[UpgradeModifiersCount] = um; @@ -1304,23 +1313,22 @@ local int AddUpgradeModifierBase(int aUid,int aattack_range,int asight_range, // returns upgrade modifier id or -1 for error ( actually this id is useless, just error checking ) -local int AddUpgradeModifier( int aUid, - int aattack_range, - int asight_range, - int abasic_damage, - int apiercing_damage, - int aarmor, - int aspeed, - int ahit_points, +local int AddUpgradeModifier( int uid, + int attack_range, + int sight_range, + int basic_damage, + int piercing_damage, + int armor, + int speed, + int hit_points, - int* acosts, + int* costs, // following are comma separated list of required string id's - const char* aaf_units, // "A:unit-mage,F:unit-grunt" -- allow mages, forbid grunts - const char* aaf_actions, // "A:PeonAttack" - const char* aaf_upgrades, // "F:upgrade-Shield1,R:upgrade-ShieldTotal" -- :) - const char* aapply_to // "unit-Peon,unit-Peasant" + const char* af_units, // "A:unit-mage,F:unit-grunt" -- allow mages, forbid grunts + const char* af_upgrades, // "F:upgrade-Shield1,R:upgrade-ShieldTotal" -- :) + const char* apply_to // "unit-Peon,unit-Peasant" ) { @@ -1334,36 +1342,33 @@ local int AddUpgradeModifier( int aUid, return -1; } - um->uid = aUid; + um->UpgradeId = uid; // get/save stats modifiers - um->mods.AttackRange = aattack_range; - um->mods.SightRange = asight_range; - um->mods.BasicDamage = abasic_damage; - um->mods.PiercingDamage = apiercing_damage; - um->mods.Armor = aarmor; - um->mods.Speed = aspeed; - um->mods.HitPoints = ahit_points; + um->Modifier.AttackRange = attack_range; + um->Modifier.SightRange = sight_range; + um->Modifier.BasicDamage = basic_damage; + um->Modifier.PiercingDamage = piercing_damage; + um->Modifier.Armor = armor; + um->Modifier.Speed = speed; + um->Modifier.HitPoints = hit_points; for( i=0; i<MaxCosts; ++i ) { - um->mods.Costs[i] = acosts[i]; + um->Modifier.Costs[i] = costs[i]; } // FIXME: all the thing below is sensitive to the format of the string! // FIXME: it will be good if things are checked for errors better! // FIXME: perhaps the function `strtok()' should be replaced with local one? - memset( um->af_units, '?', sizeof(um->af_units) ); -#if 0 - memset( um->af_actions, '?', sizeof(um->af_actions) ); -#endif - memset( um->af_upgrades, '?', sizeof(um->af_upgrades) ); - memset( um->apply_to, '?', sizeof(um->apply_to) ); + memset( um->ChangeUnits, '?', sizeof(um->ChangeUnits) ); + memset( um->ChangeUpgrades, '?', sizeof(um->ChangeUpgrades)); + memset( um->ApplyTo, '?', sizeof(um->ApplyTo) ); // // get allow/forbid's for units // - s1 = strdup( aaf_units ); + s1 = strdup( af_units ); DebugCheck(!s1); for( s2 = strtok( s1, "," ); s2; s2=strtok( NULL, "," ) ) { int id; @@ -1373,33 +1378,14 @@ local int AddUpgradeModifier( int aUid, if ( id == -1 ) { continue; // should we cancel all and return error?! } - um->af_units[id] = s2[0]; + um->ChangeUnits[id] = s2[0]; } free(s1); - // - // get allow/forbid's for actions - // -#if 0 - s1 = strdup( aaf_actions ); - DebugCheck(!s1); - for( s2 = strtok( s1, "," ); s2; s2=strtok( NULL, "," ) ) { - int id; - DebugCheck(!( s2[0] == 'A' || s2[0] == 'F' )); - DebugCheck(!( s2[1] == ':' )); - id = ActionIdByIdent( s2+2 ); - if ( id == -1 ) { - continue; // should we cancel all and return error?! - } - um->af_actions[id] = s2[0]; - } - free(s1); -#endif - // // get allow/forbid's for upgrades // - s1 = strdup( aaf_upgrades ); + s1 = strdup( af_upgrades ); DebugCheck(!s1); for( s2 = strtok( s1, "," ); s2; s2=strtok( NULL, "," ) ) { int id; @@ -1409,14 +1395,14 @@ local int AddUpgradeModifier( int aUid, if ( id == -1 ) { continue; // should we cancel all and return error?! } - um->af_upgrades[id] = s2[0]; + um->ChangeUpgrades[id] = s2[0]; } free(s1); // // get units that are affected by this upgrade // - s1 = strdup( aapply_to ); + s1 = strdup( apply_to ); DebugCheck(!s1); for( s2 = strtok( s1, "," ); s2; s2=strtok( NULL, "," ) ) { int id; @@ -1426,7 +1412,7 @@ local int AddUpgradeModifier( int aUid, if ( id == -1 ) { break; // cade: should we cancel all and return error?! } - um->apply_to[id] = 'X'; // something other than '?' + um->ApplyTo[id] = 'X'; // something other than '?' } free(s1); @@ -1438,35 +1424,35 @@ local int AddUpgradeModifier( int aUid, // this function is used for define `simple' upgrades // with only one modifier -global void AddSimpleUpgrade( const char* aIdent, - const char* aIcon, +global void AddSimpleUpgrade( const char* ident, + const char* icon, // upgrade costs - int* aCosts, + int* costs, // upgrade modifiers - int aattack_range, - int asight_range, - int abasic_damage, - int apiercing_damage, - int aarmor, - int aspeed, - int ahit_points, + int attack_range, + int sight_range, + int basic_damage, + int piercing_damage, + int armor, + int speed, + int hit_points, int* mcosts, - const char* aapply_to // "unit-Peon,unit-Peasant" + const char* apply_to // "unit-Peon,unit-Peasant" ) { Upgrade* up; - up = AddUpgrade(aIdent,aIcon,aCosts); + up = AddUpgrade(ident,icon,costs); if ( !up ) { return; } - AddUpgradeModifier(up-Upgrades,aattack_range,asight_range,abasic_damage, - apiercing_damage,aarmor,aspeed,ahit_points, + AddUpgradeModifier(up-Upgrades,attack_range,sight_range,basic_damage, + piercing_damage,armor,speed,hit_points, mcosts, - "","","", // no allow/forbid maps - aapply_to); + "","", // no allow/forbid maps + apply_to); } /*---------------------------------------------------------------------------- @@ -1511,99 +1497,142 @@ global int UpgradeIdByIdent(const char* sid) return -1; } -#if 0 -// FIXME: Docu -global int ActionIdByIdent( const char* sid ) -{ - // FIXME: there's no actions table yet - DebugLevel0Fn(" fix this %s\n",sid); - return -1; -} -#endif - /*---------------------------------------------------------------------------- -- Upgrades ----------------------------------------------------------------------------*/ -// amount==-1 to cancel upgrade, could happen when building destroyed during upgrade -// using this we could have one upgrade research in two buildings, so we can have -// this upgrade faster. -global void UpgradeIncTime( Player* player, int id, int amount ) +/** +** Increment the counter of an upgrade. +** +** Amount==-1 to cancel upgrade, could happen when building destroyed +** during upgrade. Using this we could have one upgrade research in two +** buildings, so we can have this upgrade faster. +** +** @param player Player pointer of the incremented upgrade. +** @param id Upgrade id number. +** @param amount Value to add to timer. -1 to cancel upgrade +*/ +global void UpgradeIncTime(Player * player, int id, int amount) { - player->UTimers.upgrades[id] += amount; - if ( player->UTimers.upgrades[id] >= Upgrades[id].Costs[TimeCost] ) - { - player->UTimers.upgrades[id] = Upgrades[id].Costs[TimeCost]; - UpgradeAcquire( player, &Upgrades[id] ); + player->UpgradeTimers.Upgrades[id] += amount; + if (player->UpgradeTimers.Upgrades[id] >= Upgrades[id].Costs[TimeCost]) { + player->UpgradeTimers.Upgrades[id] = Upgrades[id].Costs[TimeCost]; + UpgradeAcquire(player, &Upgrades[id]); } } -// this function will mark upgrade done and do all required modifications to -// unit types and will modify allow/forbid maps -global void ApplyUpgradeModifier( Player* player, UpgradeModifier* um ) +/** +** Apply the modifiers of an upgrade. +** +** This function will mark upgrade done and do all required modifications +** to unit types and will modify allow/forbid maps +** +** @param player Player that get all the upgrades. +** @param um Upgrade modifier that do the effects +*/ +local void ApplyUpgradeModifier(Player * player, const UpgradeModifier * um) { int z; int j; - int pn = player-Players; // player number + int pn; - for ( z = 0; z < MAXUACOUNT; z++ ) - { + pn = player->Player; // player number + for (z = 0; z < MAXUACOUNT; z++) { // allow/forbid unit types for player - if ( um->af_units[z] == 'A' ) player->Allow.Units[z] = 'A'; - if ( um->af_units[z] == 'F' ) player->Allow.Units[z] = 'F'; - -#if 0 - // allow/forbid actions for player - if ( um->af_actions[z] == 'A' ) player->Allow.Actions[z] = 'A'; - if ( um->af_actions[z] == 'F' ) player->Allow.Actions[z] = 'F'; -#endif - - // allow/forbid upgrades for player - if ( player->Allow.Upgrades[z] != 'R' ) - { // only if upgrade is not acquired - if ( um->af_upgrades[z] == 'A' ) player->Allow.Upgrades[z] = 'A'; - if ( um->af_upgrades[z] == 'F' ) player->Allow.Upgrades[z] = 'F'; - // we can even have upgrade acquired w/o costs - if ( um->af_upgrades[z] == 'R' ) player->Allow.Upgrades[z] = 'R'; + if (um->ChangeUnits[z] == 'A') { + player->Allow.Units[z] = 'A'; + } + if (um->ChangeUnits[z] == 'F') { + player->Allow.Units[z] = 'F'; } - DebugCheck(!( um->apply_to[z] == '?' || um->apply_to[z] == 'X' )); - if ( um->apply_to[z] == 'X' ) - { // this modifier should be applied to unittype id == z + // allow/forbid upgrades for player. only if upgrade is not acquired + if (player->Allow.Upgrades[z] != 'R') { + if (um->ChangeUpgrades[z] == 'A') { + player->Allow.Upgrades[z] = 'A'; + } + if (um->ChangeUpgrades[z] == 'F') { + player->Allow.Upgrades[z] = 'F'; + } + // we can even have upgrade acquired w/o costs + if (um->ChangeUpgrades[z] == 'R') { + player->Allow.Upgrades[z] = 'R'; + } + } - DebugLevel3Fn(" applied to %d\n",z); + DebugCheck(!(um->ApplyTo[z] == '?' || um->ApplyTo[z] == 'X')); + + // this modifier should be applied to unittype id == z + if (um->ApplyTo[z] == 'X') { + + DebugLevel3Fn(" applied to %d\n", z); // upgrade stats - UnitTypes[z].Stats[pn].AttackRange += um->mods.AttackRange; - UnitTypes[z].Stats[pn].SightRange += um->mods.SightRange; - UnitTypes[z].Stats[pn].BasicDamage += um->mods.BasicDamage; - UnitTypes[z].Stats[pn].PiercingDamage += um->mods.PiercingDamage; - UnitTypes[z].Stats[pn].Armor += um->mods.Armor; - UnitTypes[z].Stats[pn].Speed += um->mods.Speed; - UnitTypes[z].Stats[pn].HitPoints += um->mods.HitPoints; - + UnitTypes[z].Stats[pn].AttackRange += um->Modifier.AttackRange; + UnitTypes[z].Stats[pn].SightRange += um->Modifier.SightRange; + UnitTypes[z].Stats[pn].BasicDamage += um->Modifier.BasicDamage; + UnitTypes[z].Stats[pn].PiercingDamage + += um->Modifier.PiercingDamage; + UnitTypes[z].Stats[pn].Armor += um->Modifier.Armor; + UnitTypes[z].Stats[pn].Speed += um->Modifier.Speed; + UnitTypes[z].Stats[pn].HitPoints += um->Modifier.HitPoints; // upgrade costs :) - for( j=0; j<MaxCosts; ++j ) { - UnitTypes[z].Stats[pn].Costs[j] += um->mods.Costs[j]; + for (j = 0; j < MaxCosts; ++j) { + UnitTypes[z].Stats[pn].Costs[j] += um->Modifier.Costs[j]; } UnitTypes[z].Stats[pn].Level++; + + if( um->ConvertTo ) { + UnitType* dst; + UnitType* src; + Unit* unit; + int i; + + src=&UnitTypes[z]; + dst=(UnitType*)um->ConvertTo; + dst->Stats[pn].Level++; + for( i=0; i<player->TotalNumUnits; ++i ) { + unit=player->Units[i]; + if( unit->Type==src ) { + unit->HP+=dst->Stats[pn].HitPoints + -unit->Stats->HitPoints; + // don't have such unit now + player->UnitTypesCount[src->Type]--; + unit->Type=dst; + unit->Stats=&dst->Stats[pn]; + // and we have new one... + player->UnitTypesCount[dst->Type]++; + UpdateForNewUnit(unit,1); + if( dst->CanCastSpell ) { + unit->Mana=MAGIC_FOR_NEW_UNITS; + } + CheckUnitToBeDrawn(unit); + } + } + } } } } - // called by UpgradeIncTime() when timer reached -global void UpgradeAcquire( Player* player, Upgrade* upgrade ) +/** +** Handle that an upgrade was acquired. +** Called by UpgradeIncTime() when timer reached +** +** @param player Player researching the upgrade. +** @param upgrade Upgrade ready researched. +*/ +global void UpgradeAcquire( Player* player, const Upgrade* upgrade ) { int z; int id; id=upgrade-Upgrades; - player->UTimers.upgrades[id] = upgrade->Costs[TimeCost]; + player->UpgradeTimers.Upgrades[id] = upgrade->Costs[TimeCost]; AllowUpgradeId( player, id, 'R' ); // research done for ( z = 0; z < UpgradeModifiersCount; z++ ) { - if ( UpgradeModifiers[z]->uid == id ) { + if ( UpgradeModifiers[z]->UpgradeId == id ) { ApplyUpgradeModifier( player, UpgradeModifiers[z] ); } } @@ -1613,6 +1642,7 @@ global void UpgradeAcquire( Player* player, Upgrade* upgrade ) // if( player==ThisPlayer ) { UpdateButtonPanel(); + MustRedraw|=RedrawInfoPanel; } } @@ -1624,7 +1654,7 @@ global void UpgradeLost( Player* player, int id ) { return; //FIXME: remove this if implemented below - player->UTimers.upgrades[id] = 0; + player->UpgradeTimers.Upgrades[id] = 0; AllowUpgradeId( player, id, 'A' ); // research is lost i.e. available // FIXME: here we should reverse apply upgrade... } @@ -1644,17 +1674,6 @@ global void AllowUnitId( Player* player, int id, char af ) // id -- unit type id player->Allow.Units[id] = af; } -#if 0 -/** -** FIXME: docu -*/ -global void AllowActionId( Player* player, int id, char af ) -{ - DebugCheck(!( af == 'A' || af == 'F' )); - player->Allow.Actions[id] = af; -} -#endif - /** ** FIXME: docu */ @@ -1673,17 +1692,6 @@ global char UnitIdAllowed(const Player* player, int id ) return player->Allow.Units[id]; } -#if 0 -/** -** FIXME: docu -*/ -global char ActionIdAllowed(const Player* player, int id ) -{ - if ( id < 0 || id >= MAXUACOUNT ) return 'F'; - return player->Allow.Actions[id]; -} -#endif - /** ** FIXME: docu */ @@ -1696,34 +1704,38 @@ global char UpgradeIdAllowed(const Player* player, int id ) } // ***************by sid's -/** -** FIXME: docu -*/ -global void UpgradeIncTime2( Player* player, char* sid, int amount ) // by ident string - { UpgradeIncTime( player, UpgradeIdByIdent(sid), amount ); } -/** -** FIXME: docu -*/ -global void UpgradeLost2( Player* player, char* sid ) // by ident string - { UpgradeLost( player, UpgradeIdByIdent(sid) ); } /** ** FIXME: docu */ -global void AllowUnitByIdent( Player* player, const char* sid, char af ) - { AllowUnitId( player, UnitTypeIdByIdent(sid), af ); }; -#if 0 +global void UpgradeIncTime2(Player * player, char *sid, int amount) // by ident string +{ + UpgradeIncTime(player, UpgradeIdByIdent(sid), amount); +} + /** ** FIXME: docu */ -global void AllowActionByIdent( Player* player, const char* sid, char af ) - { AllowActionId( player, ActionIdByIdent(sid), af ); }; -#endif +global void UpgradeLost2(Player * player, char *sid) // by ident string +{ + UpgradeLost(player, UpgradeIdByIdent(sid)); +} + /** ** FIXME: docu */ -global void AllowUpgradeByIdent( Player* player, const char* sid, char af ) - { AllowUpgradeId( player, UpgradeIdByIdent(sid), af ); }; +global void AllowUnitByIdent(Player * player, const char *sid, char af) +{ + AllowUnitId(player, UnitTypeIdByIdent(sid), af); +} + +/** +** FIXME: docu +*/ +global void AllowUpgradeByIdent(Player * player, const char *sid, char af) +{ + AllowUpgradeId(player, UpgradeIdByIdent(sid), af); +} /** ** FIXME: docu @@ -1742,27 +1754,16 @@ global void AllowByIdent(Player* player, const char* sid, char af ) /** ** FIXME: docu */ -global char UnitIdentAllowed(const Player* player,const char* sid ) +global char UnitIdentAllowed(const Player * player, const char *sid) { - return UnitIdAllowed( player, UnitTypeIdByIdent(sid) ); + return UnitIdAllowed(player, UnitTypeIdByIdent(sid)); } -#if 0 -/** -** FIXME: docu -*/ -global char ActionIdentAllowed(const Player* player,const char* sid ) -{ - return ActionIdAllowed( player, ActionIdByIdent(sid) ); -} -#endif - /** ** FIXME: docu */ -global char UpgradeIdentAllowed(const Player* player,const char* sid ) +global char UpgradeIdentAllowed(const Player * player, const char *sid) { - return UpgradeIdAllowed( player, UpgradeIdByIdent(sid) ); + return UpgradeIdAllowed(player, UpgradeIdByIdent(sid)); } - //@}