- 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:
<ignore-resource-requirements value="true" />
This commit is contained in:
Mark Vejvoda 2012-03-27 03:23:03 +00:00
parent 163271203d
commit c0f3658faa
14 changed files with 274 additions and 170 deletions

View File

@ -632,8 +632,8 @@ bool AiInterface::reqsOk(const CommandType *ct){
return world->getFaction(factionIndex)->reqsOk(ct); return world->getFaction(factionIndex)->reqsOk(ct);
} }
bool AiInterface::checkCosts(const ProducibleType *pt){ bool AiInterface::checkCosts(const ProducibleType *pt, const CommandType *ct) {
return world->getFaction(factionIndex)->checkCosts(pt); return world->getFaction(factionIndex)->checkCosts(pt,ct);
} }
bool AiInterface::isFreeCells(const Vec2i &pos, int size, Field field){ bool AiInterface::isFreeCells(const Vec2i &pos, int size, Field field){

View File

@ -98,7 +98,7 @@ public:
bool isAlly(int factionIndex) const; bool isAlly(int factionIndex) const;
bool reqsOk(const RequirableType *rt); bool reqsOk(const RequirableType *rt);
bool reqsOk(const CommandType *ct); 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); bool isFreeCells(const Vec2i &pos, int size, Field field);
const Unit *getFirstOnSightEnemyUnit(Vec2i &pos, Field &field, int radius); const Unit *getFirstOnSightEnemyUnit(Vec2i &pos, Field &field, int radius);
Map * getMap(); Map * getMap();

View File

@ -821,13 +821,49 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
//if unit meets requirements //if unit meets requirements
if(aiInterface->reqsOk(pt->getUnitType())) { 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()); const CommandType *ctypeForCostCheck = NULL;
//aiInterface->printLog(4, "produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]",aiInterface->checkCosts(pt->getUnitType()), this->getName().c_str()); //for each unit
sprintf(szBuf,"produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]",aiInterface->checkCosts(pt->getUnitType()), this->getName().c_str()); for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
//for each command
const UnitType *ut= aiInterface->getMyUnit(i)->getType();
for(int j=0; j<ut->getCommandTypeCount(); ++j){
const CommandType *ct= ut->getCommandType(j);
//if the command is produce
if(ct->getClass()==ccProduce || ct->getClass()==ccMorph){
const UnitType *producedUnit= static_cast<const UnitType*>(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<const MorphCommandType *>(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); aiInterface->printLog(4, szBuf);
//if unit doesnt meet resources retry //if unit doesnt meet resources retry
if(aiInterface->checkCosts(pt->getUnitType()) == false) { if(aiInterface->checkCosts(pt->getUnitType(),ctypeForCostCheck) == false) {
sprintf(szBuf,"Check costs FAILED."); sprintf(szBuf,"Check costs FAILED.");
aiInterface->printLog(4, szBuf); aiInterface->printLog(4, szBuf);
@ -1291,7 +1327,7 @@ void AiRuleBuild::buildSpecific(const BuildTask *bt) {
if(aiInterface->reqsOk(bt->getUnitType())) { if(aiInterface->reqsOk(bt->getUnitType())) {
//retry if not enough resources //retry if not enough resources
if(aiInterface->checkCosts(bt->getUnitType()) == false) { if(aiInterface->checkCosts(bt->getUnitType(),NULL) == false) {
ai->retryTask(bt); ai->retryTask(bt);
return; return;
} }
@ -1555,7 +1591,7 @@ void AiRuleUpgrade::upgradeSpecific(const UpgradeTask *upgt){
if(aiInterface->reqsOk(upgt->getUpgradeType())){ if(aiInterface->reqsOk(upgt->getUpgradeType())){
//if resources dont meet retry //if resources dont meet retry
if(!aiInterface->checkCosts(upgt->getUpgradeType())){ if(!aiInterface->checkCosts(upgt->getUpgradeType(), NULL)) {
ai->retryTask(upgt); ai->retryTask(upgt);
return; return;
} }

View File

@ -2874,10 +2874,12 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force
if(forceCloseUnusedSlots == true && (ct == ctNetworkUnassigned || ct == ctNetwork)) { if(forceCloseUnusedSlots == true && (ct == ctNetworkUnassigned || ct == ctNetwork)) {
if(serverInterface->getSlot(i) == NULL || if(serverInterface->getSlot(i) == NULL ||
serverInterface->getSlot(i)->isConnected() == false) { serverInterface->getSlot(i)->isConnected() == false) {
if(checkBoxScenario.getValue() == false) {
//printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); //printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str());
listBoxControls[i].setSelectedItemIndex(ctClosed); listBoxControls[i].setSelectedItemIndex(ctClosed);
ct = ctClosed; ct = ctClosed;
}
} }
} }
else if(ct == ctNetworkUnassigned && i < mapInfo.players) { else if(ct == ctNetworkUnassigned && i < mapInfo.players) {
@ -3475,19 +3477,21 @@ void MenuStateCustomGame::updateControlers() {
void MenuStateCustomGame::closeUnusedSlots(){ void MenuStateCustomGame::closeUnusedSlots(){
try { try {
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); if(checkBoxScenario.getValue() == false) {
for(int i= 0; i<mapInfo.players; ++i){ ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
if(listBoxControls[i].getSelectedItemIndex() == ctNetwork || for(int i= 0; i<mapInfo.players; ++i){
listBoxControls[i].getSelectedItemIndex() == ctNetworkUnassigned) { if(listBoxControls[i].getSelectedItemIndex() == ctNetwork ||
if(serverInterface->getSlot(i) == NULL || listBoxControls[i].getSelectedItemIndex() == ctNetworkUnassigned) {
serverInterface->getSlot(i)->isConnected() == false) { if(serverInterface->getSlot(i) == NULL ||
//printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); 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) { catch(const std::exception &ex) {
char szBuf[4096]=""; char szBuf[4096]="";

View File

@ -682,36 +682,43 @@ bool Faction::reqsOk(const CommandType *ct) const {
// ================== cost application ================== // ================== cost application ==================
//apply costs except static production (start building/production) //apply costs except static production (start building/production)
bool Faction::applyCosts(const ProducibleType *p){ bool Faction::applyCosts(const ProducibleType *p,const CommandType *ct) {
bool ignoreResourceCosts = false;
if(!checkCosts(p)){ if(ct != NULL && ct->getClass() == ccMorph) {
return false; const MorphCommandType *mct = dynamic_cast<const MorphCommandType *>(ct);
ignoreResourceCosts = mct->getIgnoreResourceRequirements();
} }
assert(p != NULL); if(ignoreResourceCosts == false) {
//for each unit cost spend it if(checkCosts(p,ct) == false) {
//pass 2, decrease resources, except negative static costs (ie: farms) return false;
for(int i=0; i<p->getCostCount(); ++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));
} }
} assert(p != NULL);
//for each unit cost spend it
//pass 2, decrease resources, except negative static costs (ie: farms)
for(int i=0; i<p->getCostCount(); ++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; return true;
} }
@ -733,100 +740,128 @@ void Faction::applyDiscount(const ProducibleType *p, int discount)
} }
//apply static production (for starting units) //apply static production (for starting units)
void Faction::applyStaticCosts(const ProducibleType *p) { void Faction::applyStaticCosts(const ProducibleType *p,const CommandType *ct) {
assert(p != NULL); assert(p != NULL);
//decrease static resources bool ignoreResourceCosts = false;
for(int i=0; i < p->getCostCount(); ++i) { if(ct != NULL && ct->getClass() == ccMorph) {
const ResourceType *rt= p->getCost(i)->getType(); const MorphCommandType *mct = dynamic_cast<const MorphCommandType *>(ct);
//assert(rt != NULL); ignoreResourceCosts = mct->getIgnoreResourceRequirements();
if(rt == NULL) { }
throw runtime_error(string(__FUNCTION__) + " rt == NULL for ProducibleType [" + p->getName() + "] index: " + intToStr(i));
} if(ignoreResourceCosts == false) {
if(rt->getClass() == rcStatic) { //decrease static resources
int cost= p->getCost(i)->getAmount(); for(int i=0; i < p->getCostCount(); ++i) {
if(cost > 0) { const ResourceType *rt= p->getCost(i)->getType();
incResourceAmount(rt, -cost); //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) //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); assert(p != NULL);
//decrease static resources
for(int i=0; i<p->getCostCount(); ++i) bool ignoreResourceCosts = false;
{ if(ct != NULL && ct->getClass() == ccMorph) {
const ResourceType *rt= p->getCost(i)->getType(); const MorphCommandType *mct = dynamic_cast<const MorphCommandType *>(ct);
assert(rt != NULL); ignoreResourceCosts = mct->getIgnoreResourceRequirements();
if(rt->getClass() == rcStatic) }
{
int cost= p->getCost(i)->getAmount(); if(ignoreResourceCosts == false) {
if(cost < 0) //decrease static resources
{ for(int i=0; i<p->getCostCount(); ++i) {
incResourceAmount(rt, -cost); 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) //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); assert(p != NULL);
//increase resources
for(int i=0; i<p->getCostCount(); ++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<const MorphCommandType *>(ct);
ignoreResourceCosts = mct->getIgnoreResourceRequirements();
}
if(ignoreResourceCosts == false) {
//increase resources
for(int i=0; i<p->getCostCount(); ++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) //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); assert(p != NULL);
//decrease resources
for(int i=0; i<p->getCostCount(); ++i) bool ignoreResourceCosts = false;
{ if(ct != NULL && ct->getClass() == ccMorph) {
const ResourceType *rt= p->getCost(i)->getType(); const MorphCommandType *mct = dynamic_cast<const MorphCommandType *>(ct);
assert(rt != NULL); ignoreResourceCosts = mct->getIgnoreResourceRequirements();
if(rt->getClass() == rcStatic) }
{
if(rt->getRecoup_cost() == true) if(ignoreResourceCosts == false) {
{ //decrease resources
int cost= p->getCost(i)->getAmount(); for(int i=0; i<p->getCostCount(); ++i) {
incResourceAmount(rt, cost); 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 //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); assert(p != NULL);
//decrease resources
for(int i=0; i<p->getCostCount(); ++i) bool ignoreResourceCosts = false;
{ if(ct != NULL && ct->getClass() == ccMorph) {
const ResourceType *rt= p->getCost(i)->getType(); const MorphCommandType *mct = dynamic_cast<const MorphCommandType *>(ct);
assert(rt != NULL); ignoreResourceCosts = mct->getIgnoreResourceRequirements();
if(rt->getClass() == rcStatic) }
{
int cost= p->getCost(i)->getAmount(); if(ignoreResourceCosts == false) {
if(cost>0) //decrease resources
{ for(int i=0; i<p->getCostCount(); ++i) {
incResourceAmount(rt, cost); 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) //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); assert(pt != NULL);
//for each unit cost check if enough resources
for(int i=0; i<pt->getCostCount(); ++i){ bool ignoreResourceCosts = false;
const ResourceType *rt= pt->getCost(i)->getType(); if(ct != NULL && ct->getClass() == ccMorph) {
int cost= pt->getCost(i)->getAmount(); const MorphCommandType *mct = dynamic_cast<const MorphCommandType *>(ct);
if(cost > 0) { ignoreResourceCosts = mct->getIgnoreResourceRequirements();
int available= getResource(rt)->getAmount(); //printf("Checking costs = %d for commandtype:\n%s\n",ignoreResourceCosts,mct->getDesc(NULL).c_str());
if(cost > available){ }
return false;
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; return true;
} }

View File

@ -201,15 +201,15 @@ public:
void finishUpgrade(const UpgradeType *ut); void finishUpgrade(const UpgradeType *ut);
//cost application //cost application
bool applyCosts(const ProducibleType *p); bool applyCosts(const ProducibleType *p,const CommandType *ct);
void applyDiscount(const ProducibleType *p, int discount); void applyDiscount(const ProducibleType *p, int discount);
void applyStaticCosts(const ProducibleType *p); void applyStaticCosts(const ProducibleType *p,const CommandType *ct);
void applyStaticProduction(const ProducibleType *p); void applyStaticProduction(const ProducibleType *p,const CommandType *ct);
void deApplyCosts(const ProducibleType *p); void deApplyCosts(const ProducibleType *p,const CommandType *ct);
void deApplyStaticCosts(const ProducibleType *p); void deApplyStaticCosts(const ProducibleType *p,const CommandType *ct);
void deApplyStaticConsumption(const ProducibleType *p); void deApplyStaticConsumption(const ProducibleType *p,const CommandType *ct);
void applyCostsOnInterval(const ResourceType *rtApply); void applyCostsOnInterval(const ResourceType *rtApply);
bool checkCosts(const ProducibleType *pt); bool checkCosts(const ProducibleType *pt,const CommandType *ct);
//reqs //reqs
bool reqsOk(const RequirableType *rt) const; bool reqsOk(const RequirableType *rt) const;

View File

@ -1501,15 +1501,15 @@ CommandResult Unit::cancelCommand() {
// =================== route stack =================== // =================== route stack ===================
void Unit::create(bool startingUnit){ void Unit::create(bool startingUnit) {
faction->addUnit(this); faction->addUnit(this);
map->putUnitCells(this, pos); map->putUnitCells(this, pos);
if(startingUnit){ if(startingUnit) {
faction->applyStaticCosts(type); faction->applyStaticCosts(type,NULL);
} }
} }
void Unit::born() { void Unit::born(const CommandType *ct) {
if(type == NULL) { if(type == NULL) {
char szBuf[4096]=""; char szBuf[4096]="";
sprintf(szBuf,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str()); 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->addStore(type);
faction->applyStaticProduction(type); faction->applyStaticProduction(type,ct);
setCurrSkill(scStop); setCurrSkill(scStop);
checkItemInVault(&this->hp,this->hp); checkItemInVault(&this->hp,this->hp);
@ -1528,10 +1528,10 @@ void Unit::born() {
void Unit::kill() { void Unit::kill() {
//no longer needs static resources //no longer needs static resources
if(isBeingBuilt()) { if(isBeingBuilt()) {
faction->deApplyStaticConsumption(type); faction->deApplyStaticConsumption(type,(getCurrCommand() != NULL ? getCurrCommand()->getCommandType() : NULL));
} }
else { else {
faction->deApplyStaticCosts(type); faction->deApplyStaticCosts(type,(getCurrCommand() != NULL ? getCurrCommand()->getCommandType() : NULL));
} }
//do the cleaning //do the cleaning
@ -2673,9 +2673,9 @@ bool Unit::morph(const MorphCommandType *mct){
Field morphUnitField=fLand; Field morphUnitField=fLand;
if(morphUnitType->getField(fAir)) morphUnitField=fAir; if(morphUnitType->getField(fAir)) morphUnitField=fAir;
if(morphUnitType->getField(fLand)) morphUnitField=fLand; 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); map->clearUnitCells(this, pos);
faction->deApplyStaticCosts(type); faction->deApplyStaticCosts(type,mct);
checkItemInVault(&this->hp,this->hp); checkItemInVault(&this->hp,this->hp);
hp += morphUnitType->getMaxHp() - type->getMaxHp(); hp += morphUnitType->getMaxHp() - type->getMaxHp();
@ -2689,7 +2689,7 @@ bool Unit::morph(const MorphCommandType *mct){
map->putUnitCells(this, pos); map->putUnitCells(this, pos);
faction->applyDiscount(morphUnitType, mct->getDiscount()); faction->applyDiscount(morphUnitType, mct->getDiscount());
faction->addStore(type); faction->addStore(type);
faction->applyStaticProduction(morphUnitType); faction->applyStaticProduction(morphUnitType,mct);
level= NULL; level= NULL;
checkUnitLevel(); checkUnitLevel();
@ -2821,12 +2821,13 @@ CommandResult Unit::checkCommand(Command *command) const {
} }
const ProducibleType *produced= command->getCommandType()->getProduced(); const ProducibleType *produced= command->getCommandType()->getProduced();
if(produced!=NULL) { if(produced != NULL) {
if(ignoreCheckCommand == false && faction->reqsOk(produced) == false) { if(ignoreCheckCommand == false && faction->reqsOk(produced) == false) {
return crFailReqs; return crFailReqs;
} }
if(ignoreCheckCommand == false && faction->checkCosts(produced) == false) { if(ignoreCheckCommand == false &&
faction->checkCosts(produced,command->getCommandType()) == false) {
return crFailRes; return crFailRes;
} }
} }
@ -2844,7 +2845,7 @@ CommandResult Unit::checkCommand(Command *command) const {
if(faction->reqsOk(builtUnit) == false) { if(faction->reqsOk(builtUnit) == false) {
return crFailReqs; return crFailReqs;
} }
if(faction->checkCosts(builtUnit) == false) { if(faction->checkCosts(builtUnit,NULL) == false) {
return crFailRes; return crFailRes;
} }
} }
@ -2882,12 +2883,12 @@ void Unit::applyCommand(Command *command){
//check produced //check produced
const ProducibleType *produced= command->getCommandType()->getProduced(); const ProducibleType *produced= command->getCommandType()->getProduced();
if(produced!=NULL) { if(produced!=NULL) {
faction->applyCosts(produced); faction->applyCosts(produced,command->getCommandType());
} }
//build command specific //build command specific
if(command->getCommandType()->getClass()==ccBuild){ if(command->getCommandType()->getClass()==ccBuild){
faction->applyCosts(command->getUnitType()); faction->applyCosts(command->getUnitType(),command->getCommandType());
} }
//upgrade command specific //upgrade command specific
else if(command->getCommandType()->getClass()==ccUpgrade){ else if(command->getCommandType()->getClass()==ccUpgrade){
@ -2919,20 +2920,19 @@ CommandResult Unit::undoCommand(Command *command){
//return cost //return cost
const ProducibleType *produced= command->getCommandType()->getProduced(); const ProducibleType *produced= command->getCommandType()->getProduced();
if(produced!=NULL){ if(produced!=NULL){
faction->deApplyCosts(produced); faction->deApplyCosts(produced,command->getCommandType());
} }
//return building cost if not already building it or dead //return building cost if not already building it or dead
if(command->getCommandType()->getClass() == ccBuild){ if(command->getCommandType()->getClass() == ccBuild){
if(currSkill->getClass() != scBuild && currSkill->getClass() != scDie) { if(currSkill->getClass() != scBuild && currSkill->getClass() != scDie) {
faction->deApplyCosts(command->getUnitType()); faction->deApplyCosts(command->getUnitType(),command->getCommandType());
} }
} }
//upgrade command cancel from list //upgrade command cancel from list
if(command->getCommandType()->getClass() == ccUpgrade){ if(command->getCommandType()->getClass() == ccUpgrade){
const UpgradeCommandType *uct= static_cast<const UpgradeCommandType*>(command->getCommandType()); const UpgradeCommandType *uct= static_cast<const UpgradeCommandType*>(command->getCommandType());
if(uct == NULL) { if(uct == NULL) {
char szBuf[4096]=""; char szBuf[4096]="";
sprintf(szBuf,"In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str()); sprintf(szBuf,"In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str());

View File

@ -550,7 +550,7 @@ public:
//lifecycle //lifecycle
void create(bool startingUnit= false); void create(bool startingUnit= false);
void born(); void born(const CommandType *ct);
void kill(); void kill();
void undertake(); void undertake();

View File

@ -761,6 +761,7 @@ MorphCommandType::MorphCommandType(){
morphSkillType=NULL; morphSkillType=NULL;
morphUnit=NULL; morphUnit=NULL;
discount=0; discount=0;
ignoreResourceRequirements=false;
} }
void MorphCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const { 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
discount= n->getChild("discount")->getAttribute("value")->getIntValue(); 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__); 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+= lang.get("Discount")+": "+intToStr(discount)+"%\n";
} }
str+= "\n"+getProduced()->getReqDesc(); str+= "\n"+getProduced()->getReqDesc(ignoreResourceRequirements);
str+=morphSkillType->getBoostDesc(); str+=morphSkillType->getBoostDesc();
return str; return str;
} }

View File

@ -363,6 +363,7 @@ private:
const MorphSkillType* morphSkillType; const MorphSkillType* morphSkillType;
const UnitType* morphUnit; const UnitType* morphUnit;
int discount; int discount;
bool ignoreResourceRequirements;
public: public:
MorphCommandType(); MorphCommandType();
@ -380,6 +381,7 @@ public:
const MorphSkillType *getMorphSkillType() const {return morphSkillType;} const MorphSkillType *getMorphSkillType() const {return morphSkillType;}
const UnitType *getMorphUnit() const {return morphUnit;} const UnitType *getMorphUnit() const {return morphUnit;}
int getDiscount() const {return discount;} int getDiscount() const {return discount;}
bool getIgnoreResourceRequirements() const {return ignoreResourceRequirements;}
}; };
// =============================== // ===============================

View File

@ -121,14 +121,19 @@ const Resource *ProducibleType::getCost(const ResourceType *rt) const{
return NULL; 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"; string str= getName()+" "+Lang::getInstance().get("Reqs")+":\n";
for(int i=0; i<getCostCount(); ++i){ if(ignoreResourceRequirements == false) {
if(getCost(i)->getAmount()!=0){ for(int i=0; i<getCostCount(); ++i){
str+= getCost(i)->getType()->getName(); if(getCost(i)->getAmount()!=0){
str+= ": "+ intToStr(getCost(i)->getAmount()); str+= getCost(i)->getType()->getName();
str+= "\n"; str+= ": "+ intToStr(getCost(i)->getAmount());
} str+= "\n";
}
}
} }
for(int i=0; i<getUnitReqCount(); ++i){ for(int i=0; i<getUnitReqCount(); ++i){

View File

@ -115,6 +115,7 @@ public:
void checkCostStrings(TechTree *techTree); void checkCostStrings(TechTree *techTree);
virtual string getReqDesc() const; virtual string getReqDesc() const;
string getReqDesc(bool ignoreResourceRequirements) const;
// virtual void saveGame(XmlNode *rootNode) const; // virtual void saveGame(XmlNode *rootNode) const;
// void loadGame(const XmlNode *rootNode); // void loadGame(const XmlNode *rootNode);

View File

@ -244,7 +244,7 @@ void UnitUpdater::updateUnit(Unit *unit) {
} }
else { else {
spawned->create(); spawned->create();
spawned->born(); spawned->born(command->getCommandType());
world->getStats()->produce(unit->getFactionIndex()); world->getStats()->produce(unit->getFactionIndex());
const CommandType *ct= spawned->computeCommandType(command->getPos(),command->getUnit()); const CommandType *ct= spawned->computeCommandType(command->getPos(),command->getUnit());
if(ct != NULL){ if(ct != NULL){
@ -877,7 +877,7 @@ void UnitUpdater::updateBuild(Unit *unit, int frameIndex) {
unit->finishCommand(); unit->finishCommand();
unit->setCurrSkill(scStop); unit->setCurrSkill(scStop);
builtUnit->born(); builtUnit->born(command->getCommandType());
scriptManager->onUnitCreated(builtUnit); scriptManager->onUnitCreated(builtUnit);
if(unit->getFactionIndex() == world->getThisFactionIndex() || if(unit->getFactionIndex() == world->getThisFactionIndex() ||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { (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(repaired != NULL && repaired->isBuilt() == false) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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); scriptManager->onUnitCreated(repaired);
} }
@ -1806,7 +1806,7 @@ void UnitUpdater::updateProduce(Unit *unit, int frameIndex) {
} }
else{ else{
produced->create(); produced->create();
produced->born(); produced->born(command->getCommandType());
world->getStats()->produce(unit->getFactionIndex()); world->getStats()->produce(unit->getFactionIndex());
const CommandType *ct= produced->computeCommandType(unit->getMeetingPos()); const CommandType *ct= produced->computeCommandType(unit->getMeetingPos());
if(ct!=NULL){ if(ct!=NULL){

View File

@ -897,7 +897,7 @@ void World::createUnit(const string &unitName, int factionIndex, const Vec2i &po
if(placeUnit(pos, generationArea, unit, spaciated)) { if(placeUnit(pos, generationArea, unit, spaciated)) {
unit->create(true); unit->create(true);
unit->born(); unit->born(NULL);
scriptManager->onUnitCreated(unit); scriptManager->onUnitCreated(unit);
} }
else { else {
@ -1180,7 +1180,9 @@ Vec2i World::getStartLocation(int factionIndex) {
return map.getStartLocation(faction->getStartLocationIndex()); return map.getStartLocation(faction->getStartLocationIndex());
} }
else { 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) { void World::placeUnitAtLocation(const Vec2i &location, int radius, Unit *unit, bool spaciated) {
if(placeUnit(location, generationArea, unit, spaciated)) { if(placeUnit(location, generationArea, unit, spaciated)) {
unit->create(true); unit->create(true);
unit->born(); unit->born(NULL);
} }
else { else {
string unitName = unit->getType()->getName(); string unitName = unit->getType()->getName();