From 589962868bd44b9be50f41ec9a552d0878955f96 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Tue, 12 Feb 2013 08:44:12 +0000 Subject: [PATCH] - added ability for units to return harvested resources in an emergency by clicking a store house when a unit has a load --- source/glest_game/type_instances/unit.cpp | 48 ++++++++++++--- source/glest_game/type_instances/unit.h | 5 ++ source/glest_game/types/command_type.cpp | 38 ++++++++++++ source/glest_game/types/command_type.h | 22 +++++++ source/glest_game/types/unit_type.cpp | 17 ++++++ source/glest_game/types/unit_type.h | 3 + source/glest_game/world/unit_updater.cpp | 71 ++++++++++++++++++++++- source/glest_game/world/unit_updater.h | 1 + 8 files changed, 195 insertions(+), 10 deletions(-) diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index fb015a6f..7e85fdf3 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -1796,14 +1796,44 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target throw megaglest_runtime_error(szBuf); } + //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)")); if(targetUnit != NULL) { //attack enemies if(isAlly(targetUnit) == false) { commandType= type->getFirstAttackCommand(targetUnit->getCurrField()); } //repair allies - else{ - commandType= type->getFirstRepairCommand(targetUnit->getType()); + else { + if(targetUnit->isBuilt() == false || targetUnit->isDamaged() == true) { + commandType= type->getFirstRepairCommand(targetUnit->getType()); + } + + //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s] commandType [%p]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)"),commandType); + + if(commandType == NULL && targetUnit != NULL) { + Command *command= this->getCurrCommand(); + const HarvestCommandType *hct= dynamic_cast((command != NULL ? command->getCommandType() : NULL)); + + // Check if we can return whatever resources we have + if(targetUnit->getFactionIndex() == this->getFactionIndex() && + targetUnit->isOperative() == true && + this->getLoadType() != NULL && this->getLoadCount() != 0 && + targetUnit->getType() != NULL && + targetUnit->getType()->getStore(this->getLoadType()) > 0) { + + const HarvestCommandType *previousHarvestCmd = this->getType()->getFirstHarvestCommand(this->getLoadType(),this->getFaction()); + if(previousHarvestCmd != NULL) { + //printf("\n#1 return harvested resources\n\n"); + //this->setCurrSkill(previousHarvestCmd->getStopLoadedSkillType()); // make sure we use the right harvest animation + commandType = type->getFirstHarvestEmergencyReturnCommand(); + } + else { + //printf("\n#2 return harvested resources\n\n"); + //this->setCurrSkill(hct->getStopLoadedSkillType()); + commandType = type->getFirstHarvestEmergencyReturnCommand(); + } + } + } } } else { @@ -1814,18 +1844,20 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target } } - // Check if we want to help build (repair) any buildings instead of just moving if(targetUnit == NULL && commandType == NULL) { const Vec2i unitTargetPos = pos; Cell *cell= map->getCell(unitTargetPos); if(cell != NULL && cell->getUnit(this->getCurrField()) != NULL) { Unit *targetUnit = cell->getUnit(this->getCurrField()); - if(targetUnit != NULL && targetUnit->getFactionIndex() == this->getFactionIndex() && + if(targetUnit != NULL) { + // Check if we want to help build (repair) any buildings instead of just moving + if(targetUnit->getFactionIndex() == this->getFactionIndex() && (targetUnit->isBuilt() == false || targetUnit->isDamaged() == true)) { - const RepairCommandType *rct= this->getType()->getFirstRepairCommand(targetUnit->getType()); - if(rct != NULL) { - commandType= type->getFirstRepairCommand(targetUnit->getType()); - //printf("************ Unit will repair building built = %d, repair = %d\n",targetUnit->isBuilt(),targetUnit->isDamaged()); + const RepairCommandType *rct= this->getType()->getFirstRepairCommand(targetUnit->getType()); + if(rct != NULL) { + commandType= type->getFirstRepairCommand(targetUnit->getType()); + //printf("************ Unit will repair building built = %d, repair = %d\n",targetUnit->isBuilt(),targetUnit->isDamaged()); + } } } } diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 1d21f497..cd37f8c5 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -459,6 +459,8 @@ private: FowAlphaCellsLookupItem cachedFow; Vec2i cachedFowPos; + Vec2i lastHarvestedResourcePos; + public: Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); virtual ~Unit(); @@ -575,6 +577,9 @@ public: void setMorphFieldsBlocked ( bool value ) {this->morphFieldsBlocked=value;} bool getMorphFieldsBlocked() const { return morphFieldsBlocked; } + inline void setLastHarvestedResourcePos(Vec2i pos) { this->lastHarvestedResourcePos = pos; } + inline Vec2i getLastHarvestedResourcePos() const { return this->lastHarvestedResourcePos; } + inline void setLoadCount(int loadCount) {this->loadCount= loadCount;} inline void setLoadType(const ResourceType *loadType) {this->loadType= loadType;} inline void setProgress2(int progress2) {this->progress2= progress2;} diff --git a/source/glest_game/types/command_type.cpp b/source/glest_game/types/command_type.cpp index a27673d0..022f4322 100644 --- a/source/glest_game/types/command_type.cpp +++ b/source/glest_game/types/command_type.cpp @@ -563,6 +563,43 @@ bool HarvestCommandType::canHarvest(const ResourceType *resourceType) const{ return find(harvestedResources.begin(), harvestedResources.end(), resourceType) != harvestedResources.end(); } + +// ===================================================== +// class HarvestCommandType +// ===================================================== + +//varios +HarvestEmergencyReturnCommandType::HarvestEmergencyReturnCommandType(){ + commandTypeClass= ccHarvestEmergencyReturn; + clicks= cTwo; + + this->id= -10; +} + +void HarvestEmergencyReturnCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const { + unitUpdater->updateHarvestEmergencyReturn(unit, frameIndex); +} + +void HarvestEmergencyReturnCommandType::load(int id, const XmlNode *n, const string &dir, + const TechTree *tt, const FactionType *ft, const UnitType &ut, + std::map > > &loadedFileList, string parentLoader) { +// CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, parentLoader); +} + +string HarvestEmergencyReturnCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{ + + Lang &lang= Lang::getInstance(); + string str; + + str=getName(true)+"\n"; + return str; +} + +string HarvestEmergencyReturnCommandType::toString() const{ + Lang &lang= Lang::getInstance(); + return lang.get("Harvest"); +} + // ===================================================== // class RepairCommandType // ===================================================== @@ -926,6 +963,7 @@ CommandTypeFactory::CommandTypeFactory(){ registerClass("upgrade"); registerClass("morph"); registerClass("switch_team"); + registerClass("harvest_return"); } CommandTypeFactory &CommandTypeFactory::getInstance(){ diff --git a/source/glest_game/types/command_type.h b/source/glest_game/types/command_type.h index 743d4e84..f2daec86 100644 --- a/source/glest_game/types/command_type.h +++ b/source/glest_game/types/command_type.h @@ -48,6 +48,7 @@ enum CommandClass { ccUpgrade, ccMorph, ccSwitchTeam, + ccHarvestEmergencyReturn, ccCount, ccNull @@ -294,6 +295,27 @@ public: virtual bool usesPathfinder() const { return true; } }; +// =============================== +// class HarvestEmergencyReturnCommandType +// =============================== + +class HarvestEmergencyReturnCommandType: public CommandType { +private: + +public: + HarvestEmergencyReturnCommandType(); + virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const; + virtual void load(int id, const XmlNode *n, const string &dir, + const TechTree *tt, const FactionType *ft, const UnitType &ut, + std::map > > &loadedFileList, string parentLoader); + virtual string getDesc(const TotalUpgrade *totalUpgrade) const; + virtual string toString() const; + virtual Queueability isQueuable() const {return qOnRequest;} + + //get + virtual bool usesPathfinder() const { return true; } +}; + // =============================== // class RepairCommandType diff --git a/source/glest_game/types/unit_type.cpp b/source/glest_game/types/unit_type.cpp index e7d7e7ce..67c01521 100644 --- a/source/glest_game/types/unit_type.cpp +++ b/source/glest_game/types/unit_type.cpp @@ -36,6 +36,7 @@ using namespace Shared::Util; namespace Glest{ namespace Game{ +auto_ptr UnitType::ctHarvestEmergencyReturnCommandType(new HarvestEmergencyReturnCommandType()); // =============================== // class Level // =============================== @@ -732,6 +733,11 @@ const HarvestCommandType *UnitType::getFirstHarvestCommand(const ResourceType *r return NULL; } +const HarvestEmergencyReturnCommandType *UnitType::getFirstHarvestEmergencyReturnCommand() const { + const HarvestEmergencyReturnCommandType *result = dynamic_cast(ctHarvestEmergencyReturnCommandType.get()); + return result; +} + const AttackCommandType *UnitType::getFirstAttackCommand(Field field) const{ //printf("$$$ Unit [%s] commandTypes.size() = %d\n",this->getName().c_str(),(int)commandTypes.size()); @@ -925,6 +931,12 @@ bool UnitType::hasSkillClass(SkillClass skillClass) const { bool UnitType::hasCommandType(const CommandType *commandType) const { assert(commandType!=NULL); + + const HarvestEmergencyReturnCommandType *result = dynamic_cast(ctHarvestEmergencyReturnCommandType.get()); + if(commandType == result) { + return true; + } + for(int i=0; i(ctHarvestEmergencyReturnCommandType.get()); + if(id == result->getId()) { + return result; + } + for(int i=0; igetId()==id){ diff --git a/source/glest_game/types/unit_type.h b/source/glest_game/types/unit_type.h index 148668b1..761901fc 100644 --- a/source/glest_game/types/unit_type.h +++ b/source/glest_game/types/unit_type.h @@ -156,6 +156,8 @@ private: UnitCountsInVictoryConditions countInVictoryConditions; + static auto_ptr ctHarvestEmergencyReturnCommandType; + public: //creation and loading UnitType(); @@ -215,6 +217,7 @@ public: const SkillType *getFirstStOfClass(SkillClass skillClass) const; const CommandType *getFirstCtOfClass(CommandClass commandClass) const; const HarvestCommandType *getFirstHarvestCommand(const ResourceType *resourceType,const Faction *faction) const; + const HarvestEmergencyReturnCommandType *getFirstHarvestEmergencyReturnCommand() const; const AttackCommandType *getFirstAttackCommand(Field field) const; const AttackStoppedCommandType *getFirstAttackStoppedCommand(Field field) const; const RepairCommandType *getFirstRepairCommand(const UnitType *repaired) const; diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 7cc65230..9a2a3379 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -911,15 +911,80 @@ void UnitUpdater::updateBuild(Unit *unit, int frameIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); } - // ==================== updateHarvest ==================== +void UnitUpdater::updateHarvestEmergencyReturn(Unit *unit, int frameIndex) { + if(frameIndex >= 0) { + return; + } + + //printf("\n#1 updateHarvestEmergencyReturn\n"); + + Command *command= unit->getCurrCommand(); + if(command != NULL) { + //printf("\n#2 updateHarvestEmergencyReturn\n"); + + //const HarvestCommandType *hct= dynamic_cast((command != NULL ? command->getCommandType() : NULL)); + //if(hct != NULL) { + { + //printf("\n#3 updateHarvestEmergencyReturn\n"); + + const Vec2i unitTargetPos = command->getPos(); + Cell *cell= map->getCell(unitTargetPos); + if(cell != NULL && cell->getUnit(unit->getCurrField()) != NULL) { + //printf("\n#4 updateHarvestEmergencyReturn\n"); + + Unit *targetUnit = cell->getUnit(unit->getCurrField()); + if(targetUnit != NULL) { + //printf("\n#5 updateHarvestEmergencyReturn\n"); + + // Check if we can return whatever resources we have + if(targetUnit->getFactionIndex() == unit->getFactionIndex() && + targetUnit->isOperative() == true && unit->getLoadType() != NULL && + targetUnit->getType() != NULL && targetUnit->getType()->getStore(unit->getLoadType()) > 0) { + + //printf("\n#6 updateHarvestEmergencyReturn\n"); + + const HarvestCommandType *previousHarvestCmd = unit->getType()->getFirstHarvestCommand(unit->getLoadType(),unit->getFaction()); + if(previousHarvestCmd != NULL) { + //printf("\n\n#1a return harvested resources\n\n"); + NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), previousHarvestCmd->getId(), unit->getLastHarvestedResourcePos(), + -1, Unit::invalidId, -1, false, cst_None, -1, -1); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + Command* new_command= this->game->getCommander()->buildCommand(&networkCommand); + std::pair cr= unit->checkCommand(new_command); + if(cr.first == crSuccess) { + //printf("\n\n#1b return harvested resources\n\n"); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + unit->replaceCurrCommand(new_command); + + unit->setCurrSkill(previousHarvestCmd->getStopLoadedSkillType()); // make sure we use the right harvest animation + } + else { + //printf("\n\n#1c return harvested resources\n\n"); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + delete new_command; + + unit->setCurrSkill(scStop); + unit->finishCommand(); + } + } + } + } + } + } + } +} void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) { Chrono chrono; if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); Command *command= unit->getCurrCommand(); - const HarvestCommandType *hct= static_cast(command->getCommandType()); + const HarvestCommandType *hct= dynamic_cast(command->getCommandType()); Vec2i targetPos(-1); TravelState tsValue = tsImpossible; @@ -1266,6 +1331,8 @@ void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) { // if there is a resource, continue working, until loaded unit->update2(); + unit->setLastHarvestedResourcePos(unitTargetPos); + if (unit->getProgress2() >= hct->getHitsPerUnit()) { if (unit->getLoadCount() < hct->getMaxLoad()) { unit->setProgress2(0); diff --git a/source/glest_game/world/unit_updater.h b/source/glest_game/world/unit_updater.h index 078714bd..909ad459 100644 --- a/source/glest_game/world/unit_updater.h +++ b/source/glest_game/world/unit_updater.h @@ -112,6 +112,7 @@ public: void updateAttackStopped(Unit *unit, int frameIndex); void updateBuild(Unit *unit, int frameIndex); void updateHarvest(Unit *unit, int frameIndex); + void updateHarvestEmergencyReturn(Unit *unit, int frameIndex); void updateRepair(Unit *unit, int frameIndex); void updateProduce(Unit *unit, int frameIndex); void updateUpgrade(Unit *unit, int frameIndex);