From c0f3658faa100035c308466cf0ad4bcdaa1970f8 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Tue, 27 Mar 2012 03:23:03 +0000 Subject: [PATCH] - bugfix for network scenarios to NOT close unconnected network slots before loading, they will turn into AI players (this is required because the scenario code may require those factions) - added ability to morph and indicate the morph command should ignore resource costs, add this to the command type: --- source/glest_game/ai/ai_interface.cpp | 4 +- source/glest_game/ai/ai_interface.h | 2 +- source/glest_game/ai/ai_rule.cpp | 48 +++- .../menu/menu_state_custom_game.cpp | 26 +- source/glest_game/type_instances/faction.cpp | 263 ++++++++++-------- source/glest_game/type_instances/faction.h | 14 +- source/glest_game/type_instances/unit.cpp | 36 +-- source/glest_game/type_instances/unit.h | 2 +- source/glest_game/types/command_type.cpp | 11 +- source/glest_game/types/command_type.h | 2 + source/glest_game/types/element_type.cpp | 19 +- source/glest_game/types/element_type.h | 1 + source/glest_game/world/unit_updater.cpp | 8 +- source/glest_game/world/world.cpp | 8 +- 14 files changed, 274 insertions(+), 170 deletions(-) diff --git a/source/glest_game/ai/ai_interface.cpp b/source/glest_game/ai/ai_interface.cpp index 9358360b..31eca45a 100644 --- a/source/glest_game/ai/ai_interface.cpp +++ b/source/glest_game/ai/ai_interface.cpp @@ -632,8 +632,8 @@ bool AiInterface::reqsOk(const CommandType *ct){ return world->getFaction(factionIndex)->reqsOk(ct); } -bool AiInterface::checkCosts(const ProducibleType *pt){ - return world->getFaction(factionIndex)->checkCosts(pt); +bool AiInterface::checkCosts(const ProducibleType *pt, const CommandType *ct) { + return world->getFaction(factionIndex)->checkCosts(pt,ct); } bool AiInterface::isFreeCells(const Vec2i &pos, int size, Field field){ diff --git a/source/glest_game/ai/ai_interface.h b/source/glest_game/ai/ai_interface.h index 6a696180..988c00ec 100644 --- a/source/glest_game/ai/ai_interface.h +++ b/source/glest_game/ai/ai_interface.h @@ -98,7 +98,7 @@ public: bool isAlly(int factionIndex) const; bool reqsOk(const RequirableType *rt); bool reqsOk(const CommandType *ct); - bool checkCosts(const ProducibleType *pt); + bool checkCosts(const ProducibleType *pt, const CommandType *ct); bool isFreeCells(const Vec2i &pos, int size, Field field); const Unit *getFirstOnSightEnemyUnit(Vec2i &pos, Field &field, int radius); Map * getMap(); diff --git a/source/glest_game/ai/ai_rule.cpp b/source/glest_game/ai/ai_rule.cpp index b0570851..cd66ff50 100644 --- a/source/glest_game/ai/ai_rule.cpp +++ b/source/glest_game/ai/ai_rule.cpp @@ -821,13 +821,49 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){ //if unit meets requirements if(aiInterface->reqsOk(pt->getUnitType())) { - if(ai->outputAIBehaviourToConsole()) printf("produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]\n",aiInterface->checkCosts(pt->getUnitType()), this->getName().c_str()); - //aiInterface->printLog(4, "produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]",aiInterface->checkCosts(pt->getUnitType()), this->getName().c_str()); - sprintf(szBuf,"produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]",aiInterface->checkCosts(pt->getUnitType()), this->getName().c_str()); + const CommandType *ctypeForCostCheck = NULL; + //for each unit + for(int i=0; igetMyUnitCount(); ++i){ + + //for each command + const UnitType *ut= aiInterface->getMyUnit(i)->getType(); + for(int j=0; jgetCommandTypeCount(); ++j){ + const CommandType *ct= ut->getCommandType(j); + + //if the command is produce + if(ct->getClass()==ccProduce || ct->getClass()==ccMorph){ + const UnitType *producedUnit= static_cast(ct->getProduced()); + + //if units match + if(producedUnit == pt->getUnitType()){ + + if(ai->outputAIBehaviourToConsole()) printf("produceSpecific aiInterface->reqsOk(ct) = [%d] Testing AI RULE Name[%s]\n",aiInterface->reqsOk(ct), this->getName().c_str()); + //aiInterface->printLog(4, "produceSpecific aiInterface->reqsOk(ct) = [%d] Testing AI RULE Name[%s]",aiInterface->reqsOk(ct), this->getName().c_str()); + + if(aiInterface->reqsOk(ct)){ + if(ctypeForCostCheck == NULL || ct->getClass() == ccMorph) { + if(ctypeForCostCheck != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = dynamic_cast(ct); + if(mct->getIgnoreResourceRequirements() == true) { + ctypeForCostCheck= ct; + } + } + else { + ctypeForCostCheck= ct; + } + } + } + } + } + } + } + + if(ai->outputAIBehaviourToConsole()) printf("produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]\n",aiInterface->checkCosts(pt->getUnitType(),ctypeForCostCheck), this->getName().c_str()); + sprintf(szBuf,"produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]",aiInterface->checkCosts(pt->getUnitType(),ctypeForCostCheck), this->getName().c_str()); aiInterface->printLog(4, szBuf); //if unit doesnt meet resources retry - if(aiInterface->checkCosts(pt->getUnitType()) == false) { + if(aiInterface->checkCosts(pt->getUnitType(),ctypeForCostCheck) == false) { sprintf(szBuf,"Check costs FAILED."); aiInterface->printLog(4, szBuf); @@ -1291,7 +1327,7 @@ void AiRuleBuild::buildSpecific(const BuildTask *bt) { if(aiInterface->reqsOk(bt->getUnitType())) { //retry if not enough resources - if(aiInterface->checkCosts(bt->getUnitType()) == false) { + if(aiInterface->checkCosts(bt->getUnitType(),NULL) == false) { ai->retryTask(bt); return; } @@ -1555,7 +1591,7 @@ void AiRuleUpgrade::upgradeSpecific(const UpgradeTask *upgt){ if(aiInterface->reqsOk(upgt->getUpgradeType())){ //if resources dont meet retry - if(!aiInterface->checkCosts(upgt->getUpgradeType())){ + if(!aiInterface->checkCosts(upgt->getUpgradeType(), NULL)) { ai->retryTask(upgt); return; } diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index 948aeefd..a1314be1 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -2874,10 +2874,12 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force if(forceCloseUnusedSlots == true && (ct == ctNetworkUnassigned || ct == ctNetwork)) { if(serverInterface->getSlot(i) == NULL || serverInterface->getSlot(i)->isConnected() == false) { + if(checkBoxScenario.getValue() == false) { //printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); - listBoxControls[i].setSelectedItemIndex(ctClosed); - ct = ctClosed; + listBoxControls[i].setSelectedItemIndex(ctClosed); + ct = ctClosed; + } } } else if(ct == ctNetworkUnassigned && i < mapInfo.players) { @@ -3475,19 +3477,21 @@ void MenuStateCustomGame::updateControlers() { void MenuStateCustomGame::closeUnusedSlots(){ try { - ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); - for(int i= 0; igetSlot(i) == NULL || - serverInterface->getSlot(i)->isConnected() == false) { - //printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); + if(checkBoxScenario.getValue() == false) { + ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); + for(int i= 0; igetSlot(i) == NULL || + serverInterface->getSlot(i)->isConnected() == false) { + //printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); - listBoxControls[i].setSelectedItemIndex(ctClosed); + listBoxControls[i].setSelectedItemIndex(ctClosed); + } } } + updateNetworkSlots(); } - updateNetworkSlots(); } catch(const std::exception &ex) { char szBuf[4096]=""; diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index 973b9a43..9faab4b9 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -682,36 +682,43 @@ bool Faction::reqsOk(const CommandType *ct) const { // ================== cost application ================== //apply costs except static production (start building/production) -bool Faction::applyCosts(const ProducibleType *p){ - - if(!checkCosts(p)){ - return false; +bool Faction::applyCosts(const ProducibleType *p,const CommandType *ct) { + bool ignoreResourceCosts = false; + if(ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = dynamic_cast(ct); + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); } - assert(p != NULL); - //for each unit cost spend it - //pass 2, decrease resources, except negative static costs (ie: farms) - for(int i=0; igetCostCount(); ++i) { - const Resource *r= p->getCost(i); - if(r == NULL) { - char szBuf[1024]=""; - sprintf(szBuf,"cannot apply costs for p [%s] %d of %d costs resource is null",p->getName().c_str(),i,p->getCostCount()); - throw runtime_error(szBuf); - } - - const ResourceType *rt= r->getType(); - if(rt == NULL) { - char szBuf[1024]=""; - sprintf(szBuf,"cannot apply costs for p [%s] %d of %d costs resourcetype [%s] is null",p->getName().c_str(),i,p->getCostCount(),r->getDescription().c_str()); - throw runtime_error(szBuf); - } - int cost= r->getAmount(); - if((cost > 0 || (rt->getClass() != rcStatic)) && rt->getClass() != rcConsumable) - { - incResourceAmount(rt, -(cost)); + if(ignoreResourceCosts == false) { + if(checkCosts(p,ct) == false) { + return false; } - } + assert(p != NULL); + //for each unit cost spend it + //pass 2, decrease resources, except negative static costs (ie: farms) + for(int i=0; igetCostCount(); ++i) { + const Resource *r= p->getCost(i); + if(r == NULL) { + char szBuf[1024]=""; + sprintf(szBuf,"cannot apply costs for p [%s] %d of %d costs resource is null",p->getName().c_str(),i,p->getCostCount()); + throw runtime_error(szBuf); + } + + const ResourceType *rt= r->getType(); + if(rt == NULL) { + char szBuf[1024]=""; + sprintf(szBuf,"cannot apply costs for p [%s] %d of %d costs resourcetype [%s] is null",p->getName().c_str(),i,p->getCostCount(),r->getDescription().c_str()); + throw runtime_error(szBuf); + } + int cost= r->getAmount(); + if((cost > 0 || (rt->getClass() != rcStatic)) && rt->getClass() != rcConsumable) + { + incResourceAmount(rt, -(cost)); + } + + } + } return true; } @@ -733,100 +740,128 @@ void Faction::applyDiscount(const ProducibleType *p, int discount) } //apply static production (for starting units) -void Faction::applyStaticCosts(const ProducibleType *p) { +void Faction::applyStaticCosts(const ProducibleType *p,const CommandType *ct) { assert(p != NULL); - //decrease static resources - for(int i=0; i < p->getCostCount(); ++i) { - const ResourceType *rt= p->getCost(i)->getType(); - //assert(rt != NULL); - if(rt == NULL) { - throw runtime_error(string(__FUNCTION__) + " rt == NULL for ProducibleType [" + p->getName() + "] index: " + intToStr(i)); - } - if(rt->getClass() == rcStatic) { - int cost= p->getCost(i)->getAmount(); - if(cost > 0) { - incResourceAmount(rt, -cost); + bool ignoreResourceCosts = false; + if(ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = dynamic_cast(ct); + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + + if(ignoreResourceCosts == false) { + //decrease static resources + for(int i=0; i < p->getCostCount(); ++i) { + const ResourceType *rt= p->getCost(i)->getType(); + //assert(rt != NULL); + if(rt == NULL) { + throw runtime_error(string(__FUNCTION__) + " rt == NULL for ProducibleType [" + p->getName() + "] index: " + intToStr(i)); } - } - } + if(rt->getClass() == rcStatic) { + int cost= p->getCost(i)->getAmount(); + if(cost > 0) { + incResourceAmount(rt, -cost); + } + } + } + } } //apply static production (when a mana source is done) -void Faction::applyStaticProduction(const ProducibleType *p) -{ +void Faction::applyStaticProduction(const ProducibleType *p,const CommandType *ct) { assert(p != NULL); - //decrease static resources - for(int i=0; igetCostCount(); ++i) - { - const ResourceType *rt= p->getCost(i)->getType(); - assert(rt != NULL); - if(rt->getClass() == rcStatic) - { - int cost= p->getCost(i)->getAmount(); - if(cost < 0) - { - incResourceAmount(rt, -cost); + + bool ignoreResourceCosts = false; + if(ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = dynamic_cast(ct); + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + + if(ignoreResourceCosts == false) { + //decrease static resources + for(int i=0; igetCostCount(); ++i) { + const ResourceType *rt= p->getCost(i)->getType(); + assert(rt != NULL); + if(rt->getClass() == rcStatic) { + int cost= p->getCost(i)->getAmount(); + if(cost < 0) { + incResourceAmount(rt, -cost); + } } - } - } + } + } } //deapply all costs except static production (usually when a building is cancelled) -void Faction::deApplyCosts(const ProducibleType *p) -{ +void Faction::deApplyCosts(const ProducibleType *p,const CommandType *ct) { assert(p != NULL); - //increase resources - for(int i=0; igetCostCount(); ++i) - { - const ResourceType *rt= p->getCost(i)->getType(); - assert(rt != NULL); - int cost= p->getCost(i)->getAmount(); - if((cost > 0 || (rt->getClass() != rcStatic)) && rt->getClass() != rcConsumable) - { - incResourceAmount(rt, cost); - } - } + bool ignoreResourceCosts = false; + if(ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = dynamic_cast(ct); + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + + if(ignoreResourceCosts == false) { + //increase resources + for(int i=0; igetCostCount(); ++i) { + const ResourceType *rt= p->getCost(i)->getType(); + assert(rt != NULL); + int cost= p->getCost(i)->getAmount(); + if((cost > 0 || (rt->getClass() != rcStatic)) && rt->getClass() != rcConsumable) { + incResourceAmount(rt, cost); + } + } + } } //deapply static costs (usually when a unit dies) -void Faction::deApplyStaticCosts(const ProducibleType *p) -{ +void Faction::deApplyStaticCosts(const ProducibleType *p,const CommandType *ct) { assert(p != NULL); - //decrease resources - for(int i=0; igetCostCount(); ++i) - { - const ResourceType *rt= p->getCost(i)->getType(); - assert(rt != NULL); - if(rt->getClass() == rcStatic) - { - if(rt->getRecoup_cost() == true) - { - int cost= p->getCost(i)->getAmount(); - incResourceAmount(rt, cost); - } - } - } + + bool ignoreResourceCosts = false; + if(ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = dynamic_cast(ct); + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + + if(ignoreResourceCosts == false) { + //decrease resources + for(int i=0; igetCostCount(); ++i) { + const ResourceType *rt= p->getCost(i)->getType(); + assert(rt != NULL); + if(rt->getClass() == rcStatic) { + if(rt->getRecoup_cost() == true) { + int cost= p->getCost(i)->getAmount(); + incResourceAmount(rt, cost); + } + } + } + } } //deapply static costs, but not negative costs, for when building gets killed -void Faction::deApplyStaticConsumption(const ProducibleType *p) -{ +void Faction::deApplyStaticConsumption(const ProducibleType *p,const CommandType *ct) { assert(p != NULL); - //decrease resources - for(int i=0; igetCostCount(); ++i) - { - const ResourceType *rt= p->getCost(i)->getType(); - assert(rt != NULL); - if(rt->getClass() == rcStatic) - { - int cost= p->getCost(i)->getAmount(); - if(cost>0) - { - incResourceAmount(rt, cost); + + bool ignoreResourceCosts = false; + if(ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = dynamic_cast(ct); + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + + if(ignoreResourceCosts == false) { + //decrease resources + for(int i=0; igetCostCount(); ++i) { + const ResourceType *rt= p->getCost(i)->getType(); + assert(rt != NULL); + if(rt->getClass() == rcStatic) { + int cost= p->getCost(i)->getAmount(); + if(cost > 0) { + incResourceAmount(rt, cost); + } } - } - } + } + } } //apply resource on interval (cosumable resouces) @@ -898,19 +933,29 @@ void Faction::applyCostsOnInterval(const ResourceType *rtApply) { } } -bool Faction::checkCosts(const ProducibleType *pt){ +bool Faction::checkCosts(const ProducibleType *pt,const CommandType *ct) { assert(pt != NULL); - //for each unit cost check if enough resources - for(int i=0; igetCostCount(); ++i){ - const ResourceType *rt= pt->getCost(i)->getType(); - int cost= pt->getCost(i)->getAmount(); - if(cost > 0) { - int available= getResource(rt)->getAmount(); - if(cost > available){ - return false; + + bool ignoreResourceCosts = false; + if(ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = dynamic_cast(ct); + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + //printf("Checking costs = %d for commandtype:\n%s\n",ignoreResourceCosts,mct->getDesc(NULL).c_str()); + } + + if(ignoreResourceCosts == false) { + //for each unit cost check if enough resources + for(int i = 0; i < pt->getCostCount(); ++i) { + const ResourceType *rt= pt->getCost(i)->getType(); + int cost= pt->getCost(i)->getAmount(); + if(cost > 0) { + int available= getResource(rt)->getAmount(); + if(cost > available){ + return false; + } } } - } + } return true; } diff --git a/source/glest_game/type_instances/faction.h b/source/glest_game/type_instances/faction.h index 3f14cdf4..43e2a57a 100644 --- a/source/glest_game/type_instances/faction.h +++ b/source/glest_game/type_instances/faction.h @@ -201,15 +201,15 @@ public: void finishUpgrade(const UpgradeType *ut); //cost application - bool applyCosts(const ProducibleType *p); + bool applyCosts(const ProducibleType *p,const CommandType *ct); void applyDiscount(const ProducibleType *p, int discount); - void applyStaticCosts(const ProducibleType *p); - void applyStaticProduction(const ProducibleType *p); - void deApplyCosts(const ProducibleType *p); - void deApplyStaticCosts(const ProducibleType *p); - void deApplyStaticConsumption(const ProducibleType *p); + void applyStaticCosts(const ProducibleType *p,const CommandType *ct); + void applyStaticProduction(const ProducibleType *p,const CommandType *ct); + void deApplyCosts(const ProducibleType *p,const CommandType *ct); + void deApplyStaticCosts(const ProducibleType *p,const CommandType *ct); + void deApplyStaticConsumption(const ProducibleType *p,const CommandType *ct); void applyCostsOnInterval(const ResourceType *rtApply); - bool checkCosts(const ProducibleType *pt); + bool checkCosts(const ProducibleType *pt,const CommandType *ct); //reqs bool reqsOk(const RequirableType *rt) const; diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 3c74bcef..e72fcbff 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -1501,15 +1501,15 @@ CommandResult Unit::cancelCommand() { // =================== route stack =================== -void Unit::create(bool startingUnit){ +void Unit::create(bool startingUnit) { faction->addUnit(this); map->putUnitCells(this, pos); - if(startingUnit){ - faction->applyStaticCosts(type); + if(startingUnit) { + faction->applyStaticCosts(type,NULL); } } -void Unit::born() { +void Unit::born(const CommandType *ct) { if(type == NULL) { char szBuf[4096]=""; sprintf(szBuf,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str()); @@ -1517,7 +1517,7 @@ void Unit::born() { } faction->addStore(type); - faction->applyStaticProduction(type); + faction->applyStaticProduction(type,ct); setCurrSkill(scStop); checkItemInVault(&this->hp,this->hp); @@ -1528,10 +1528,10 @@ void Unit::born() { void Unit::kill() { //no longer needs static resources if(isBeingBuilt()) { - faction->deApplyStaticConsumption(type); + faction->deApplyStaticConsumption(type,(getCurrCommand() != NULL ? getCurrCommand()->getCommandType() : NULL)); } else { - faction->deApplyStaticCosts(type); + faction->deApplyStaticCosts(type,(getCurrCommand() != NULL ? getCurrCommand()->getCommandType() : NULL)); } //do the cleaning @@ -2673,9 +2673,9 @@ bool Unit::morph(const MorphCommandType *mct){ Field morphUnitField=fLand; if(morphUnitType->getField(fAir)) morphUnitField=fAir; if(morphUnitType->getField(fLand)) morphUnitField=fLand; - if(map->isFreeCellsOrHasUnit(pos, morphUnitType->getSize(), morphUnitField, this,morphUnitType)){ + if(map->isFreeCellsOrHasUnit(pos, morphUnitType->getSize(), morphUnitField, this,morphUnitType)) { map->clearUnitCells(this, pos); - faction->deApplyStaticCosts(type); + faction->deApplyStaticCosts(type,mct); checkItemInVault(&this->hp,this->hp); hp += morphUnitType->getMaxHp() - type->getMaxHp(); @@ -2689,7 +2689,7 @@ bool Unit::morph(const MorphCommandType *mct){ map->putUnitCells(this, pos); faction->applyDiscount(morphUnitType, mct->getDiscount()); faction->addStore(type); - faction->applyStaticProduction(morphUnitType); + faction->applyStaticProduction(morphUnitType,mct); level= NULL; checkUnitLevel(); @@ -2821,12 +2821,13 @@ CommandResult Unit::checkCommand(Command *command) const { } const ProducibleType *produced= command->getCommandType()->getProduced(); - if(produced!=NULL) { + if(produced != NULL) { if(ignoreCheckCommand == false && faction->reqsOk(produced) == false) { return crFailReqs; } - if(ignoreCheckCommand == false && faction->checkCosts(produced) == false) { + if(ignoreCheckCommand == false && + faction->checkCosts(produced,command->getCommandType()) == false) { return crFailRes; } } @@ -2844,7 +2845,7 @@ CommandResult Unit::checkCommand(Command *command) const { if(faction->reqsOk(builtUnit) == false) { return crFailReqs; } - if(faction->checkCosts(builtUnit) == false) { + if(faction->checkCosts(builtUnit,NULL) == false) { return crFailRes; } } @@ -2882,12 +2883,12 @@ void Unit::applyCommand(Command *command){ //check produced const ProducibleType *produced= command->getCommandType()->getProduced(); if(produced!=NULL) { - faction->applyCosts(produced); + faction->applyCosts(produced,command->getCommandType()); } //build command specific if(command->getCommandType()->getClass()==ccBuild){ - faction->applyCosts(command->getUnitType()); + faction->applyCosts(command->getUnitType(),command->getCommandType()); } //upgrade command specific else if(command->getCommandType()->getClass()==ccUpgrade){ @@ -2919,20 +2920,19 @@ CommandResult Unit::undoCommand(Command *command){ //return cost const ProducibleType *produced= command->getCommandType()->getProduced(); if(produced!=NULL){ - faction->deApplyCosts(produced); + faction->deApplyCosts(produced,command->getCommandType()); } //return building cost if not already building it or dead if(command->getCommandType()->getClass() == ccBuild){ if(currSkill->getClass() != scBuild && currSkill->getClass() != scDie) { - faction->deApplyCosts(command->getUnitType()); + faction->deApplyCosts(command->getUnitType(),command->getCommandType()); } } //upgrade command cancel from list if(command->getCommandType()->getClass() == ccUpgrade){ const UpgradeCommandType *uct= static_cast(command->getCommandType()); - if(uct == NULL) { char szBuf[4096]=""; sprintf(szBuf,"In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str()); diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 458766f9..d6165913 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -550,7 +550,7 @@ public: //lifecycle void create(bool startingUnit= false); - void born(); + void born(const CommandType *ct); void kill(); void undertake(); diff --git a/source/glest_game/types/command_type.cpp b/source/glest_game/types/command_type.cpp index 83ec8c9d..2815aebf 100644 --- a/source/glest_game/types/command_type.cpp +++ b/source/glest_game/types/command_type.cpp @@ -761,6 +761,7 @@ MorphCommandType::MorphCommandType(){ morphSkillType=NULL; morphUnit=NULL; discount=0; + ignoreResourceRequirements=false; } void MorphCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const { @@ -783,6 +784,13 @@ void MorphCommandType::load(int id, const XmlNode *n, const string &dir, //discount discount= n->getChild("discount")->getAttribute("value")->getIntValue(); + ignoreResourceRequirements = false; + if(n->hasChild("ignore-resource-requirements") == true) { + ignoreResourceRequirements= n->getChild("ignore-resource-requirements")->getAttribute("value")->getBoolValue(); + + //printf("ignoreResourceRequirements = %d\n",ignoreResourceRequirements); + } + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } @@ -806,8 +814,9 @@ string MorphCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{ str+= lang.get("Discount")+": "+intToStr(discount)+"%\n"; } - str+= "\n"+getProduced()->getReqDesc(); + str+= "\n"+getProduced()->getReqDesc(ignoreResourceRequirements); str+=morphSkillType->getBoostDesc(); + return str; } diff --git a/source/glest_game/types/command_type.h b/source/glest_game/types/command_type.h index a7d70895..0211e873 100644 --- a/source/glest_game/types/command_type.h +++ b/source/glest_game/types/command_type.h @@ -363,6 +363,7 @@ private: const MorphSkillType* morphSkillType; const UnitType* morphUnit; int discount; + bool ignoreResourceRequirements; public: MorphCommandType(); @@ -380,6 +381,7 @@ public: const MorphSkillType *getMorphSkillType() const {return morphSkillType;} const UnitType *getMorphUnit() const {return morphUnit;} int getDiscount() const {return discount;} + bool getIgnoreResourceRequirements() const {return ignoreResourceRequirements;} }; // =============================== diff --git a/source/glest_game/types/element_type.cpp b/source/glest_game/types/element_type.cpp index d3f7ec3b..4ad63046 100644 --- a/source/glest_game/types/element_type.cpp +++ b/source/glest_game/types/element_type.cpp @@ -121,14 +121,19 @@ const Resource *ProducibleType::getCost(const ResourceType *rt) const{ return NULL; } -string ProducibleType::getReqDesc() const{ +string ProducibleType::getReqDesc() const { + return getReqDesc(false); +} +string ProducibleType::getReqDesc(bool ignoreResourceRequirements) const { string str= getName()+" "+Lang::getInstance().get("Reqs")+":\n"; - for(int i=0; igetAmount()!=0){ - str+= getCost(i)->getType()->getName(); - str+= ": "+ intToStr(getCost(i)->getAmount()); - str+= "\n"; - } + if(ignoreResourceRequirements == false) { + for(int i=0; igetAmount()!=0){ + str+= getCost(i)->getType()->getName(); + str+= ": "+ intToStr(getCost(i)->getAmount()); + str+= "\n"; + } + } } for(int i=0; icreate(); - spawned->born(); + spawned->born(command->getCommandType()); world->getStats()->produce(unit->getFactionIndex()); const CommandType *ct= spawned->computeCommandType(command->getPos(),command->getUnit()); if(ct != NULL){ @@ -877,7 +877,7 @@ void UnitUpdater::updateBuild(Unit *unit, int frameIndex) { unit->finishCommand(); unit->setCurrSkill(scStop); - builtUnit->born(); + builtUnit->born(command->getCommandType()); scriptManager->onUnitCreated(builtUnit); if(unit->getFactionIndex() == world->getThisFactionIndex() || (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { @@ -1742,7 +1742,7 @@ void UnitUpdater::updateRepair(Unit *unit, int frameIndex) { if(repaired != NULL && repaired->isBuilt() == false) { if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - repaired->born(); + repaired->born(command->getCommandType()); scriptManager->onUnitCreated(repaired); } @@ -1806,7 +1806,7 @@ void UnitUpdater::updateProduce(Unit *unit, int frameIndex) { } else{ produced->create(); - produced->born(); + produced->born(command->getCommandType()); world->getStats()->produce(unit->getFactionIndex()); const CommandType *ct= produced->computeCommandType(unit->getMeetingPos()); if(ct!=NULL){ diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 8a2b5899..8625f9fa 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -897,7 +897,7 @@ void World::createUnit(const string &unitName, int factionIndex, const Vec2i &po if(placeUnit(pos, generationArea, unit, spaciated)) { unit->create(true); - unit->born(); + unit->born(NULL); scriptManager->onUnitCreated(unit); } else { @@ -1180,7 +1180,9 @@ Vec2i World::getStartLocation(int factionIndex) { return map.getStartLocation(faction->getStartLocationIndex()); } else { - throw runtime_error("Invalid faction index in getStartLocation: " + intToStr(factionIndex)); + printf("\n=================================================\n%s\n",game->getGameSettings()->toString().c_str()); + + throw runtime_error("Invalid faction index in getStartLocation: " + intToStr(factionIndex) + " : " + intToStr(factions.size())); } } @@ -1479,7 +1481,7 @@ void World::initUnitsForScenario() { void World::placeUnitAtLocation(const Vec2i &location, int radius, Unit *unit, bool spaciated) { if(placeUnit(location, generationArea, unit, spaciated)) { unit->create(true); - unit->born(); + unit->born(NULL); } else { string unitName = unit->getType()->getName();