From 51c1afe4e4b96d8a9b683120a5487b1972742346 Mon Sep 17 00:00:00 2001 From: titison Date: Sun, 27 Jul 2014 21:41:40 +0200 Subject: [PATCH] Added the ability for SpawnAttacks to let the units spawn when the projectile arrives at the targetpos. Unit will always try to attack if it has an attack command. Unit attacks the target POS and not the target UNIT of the attacker. --- source/glest_game/types/projectile_type.cpp | 20 ++++ source/glest_game/types/projectile_type.h | 8 ++ source/glest_game/world/unit_updater.cpp | 119 +++++++++++--------- source/glest_game/world/unit_updater.h | 1 + 4 files changed, 94 insertions(+), 54 deletions(-) diff --git a/source/glest_game/types/projectile_type.cpp b/source/glest_game/types/projectile_type.cpp index fb10075e..672c2dc2 100644 --- a/source/glest_game/types/projectile_type.cpp +++ b/source/glest_game/types/projectile_type.cpp @@ -24,6 +24,10 @@ ProjectileType::ProjectileType() { projectileParticleSystemType=NULL; attackStartTime=0.0f; + spawnUnit=""; + spawnUnitcount=0; + spawnUnitAtTarget=false; + shake=false; shakeIntensity=0; shakeDuration=0; @@ -70,6 +74,22 @@ void ProjectileType::load(const XmlNode *projectileNode, const string &dir, cons loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleNode->getAttribute("path")->getRestrictedValue())); setProjectileParticleSystemType(projectileParticleSystemType); + //spawnattack + if (projectileNode->hasChild("unit")) { + spawnUnit = projectileNode->getChild("unit")->getAttribute("value")->getValue(); + spawnUnitcount = projectileNode->getChild("unit")->getAttribute("amount")->getIntValue(); + if(projectileNode->getChild("unit")->hasAttribute("spawnAtTarget")) { + spawnUnitAtTarget = projectileNode->getChild("unit")->getAttribute("spawnAtTarget")->getBoolValue(); + } else { + spawnUnitAtTarget = false; + } + } else { + spawnUnit = ""; + spawnUnitcount = 0; + spawnUnitAtTarget = false; + } + + if(projectileNode->hasChild("hitshake")){ const XmlNode *hitShakeNode= projectileNode->getChild("hitshake"); shake=hitShakeNode->getAttribute("enabled")->getBoolValue(); diff --git a/source/glest_game/types/projectile_type.h b/source/glest_game/types/projectile_type.h index 27aaeb48..d3871ef1 100644 --- a/source/glest_game/types/projectile_type.h +++ b/source/glest_game/types/projectile_type.h @@ -41,6 +41,10 @@ protected: SoundContainer hitSounds; float attackStartTime; + string spawnUnit; + int spawnUnitcount; + bool spawnUnitAtTarget; + bool shake; int shakeIntensity; int shakeDuration; @@ -64,6 +68,10 @@ public: float getAttackStartTime() const {return attackStartTime;} void setAttackStartTime(float value) {attackStartTime=value;} + string getSpawnUnit() const{return spawnUnit;} + int getSpawnUnitcount() const{return spawnUnitcount;} + bool getSpawnUnitAtTarget() const{return spawnUnitAtTarget;} + bool isShake() const{return shake;} bool isShakeCameraDistanceAffected() const{return shakeCameraDistanceAffected;} int getShakeDuration() const{return shakeDuration;} diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 67ba4266..775d8afa 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -270,62 +270,9 @@ bool UnitUpdater::updateUnit(Unit *unit) { else if(unit->getCommandSize() > 0) { Command *command= unit->getCurrCommand(); if(command != NULL) { - const CommandType *ct = command->getCommandType(); const AttackCommandType *act= dynamic_cast(command->getCommandType()); - if( act != NULL && act->getAttackSkillType() != NULL && - act->getAttackSkillType()->getSpawnUnit() != "" && act->getAttackSkillType()->getSpawnUnitCount() > 0) { - - const FactionType *ft= unit->getFaction()->getType(); - const UnitType *spawnUnitType = ft->getUnitType(act->getAttackSkillType()->getSpawnUnit()); - int spawnCount = act->getAttackSkillType()->getSpawnUnitCount(); - for (int y=0; y < spawnCount; ++y) { - if(spawnUnitType->getMaxUnitCount() > 0) { - if(spawnUnitType->getMaxUnitCount() <= unit->getFaction()->getCountForMaxUnitCount(spawnUnitType)) { - break; - } - } - UnitPathInterface *newpath = NULL; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - newpath = new UnitPathBasic(); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - Unit *spawned= new Unit(world->getNextUnitId(unit->getFaction()), newpath, - Vec2i(0), spawnUnitType, unit->getFaction(), - world->getMap(), CardinalDir::NORTH); - //SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to place unit for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,spawned->toString().c_str()); - bool placedSpawnUnit=false; - if(act->getAttackSkillType()->getSpawnUnitAtTarget()) { - placedSpawnUnit=world->placeUnit(unit->getTargetPos(), 10, spawned); - } else { - placedSpawnUnit=world->placeUnit(unit->getCenteredPos(), 10, spawned); - } - if(!placedSpawnUnit) { - //SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] COULD NOT PLACE UNIT for unitID [%d]\n",__FILE__,__FUNCTION__,__LINE__,spawned->getId()); - - // This will also cleanup newPath - delete spawned; - spawned = NULL; - } - else { - spawned->create(); - spawned->born(ct); - world->getStats()->produce(unit->getFactionIndex(),spawned->getType()->getCountUnitProductionInStats()); - const CommandType *ct= spawned->computeCommandType(unit->getTargetPos(),map->getCell(unit->getTargetPos())->getUnit(unit->getTargetField())); - if(ct != NULL){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - spawned->giveCommand(new Command(ct, unit->getTargetPos())); - } - scriptManager->onUnitCreated(spawned); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - } - } + spawnAttack(unit,act->getAttackSkillType()->getSpawnUnit(),act->getAttackSkillType()->getSpawnUnitCount(),act->getAttackSkillType()->getSpawnUnitAtTarget()); } } @@ -362,6 +309,65 @@ bool UnitUpdater::updateUnit(Unit *unit) { return processUnitCommand; } +void UnitUpdater::spawnAttack(Unit *unit,string spawnUnit,int spawnUnitcount,bool spawnUnitAtTarget,Vec2i targetPos) { + if(spawnUnit != "" && spawnUnitcount > 0) { + + const FactionType *ft= unit->getFaction()->getType(); + const UnitType *spawnUnitType = ft->getUnitType(spawnUnit); + int spawnCount = spawnUnitcount; + for (int y=0; y < spawnCount; ++y) { + if(spawnUnitType->getMaxUnitCount() > 0) { + if(spawnUnitType->getMaxUnitCount() <= unit->getFaction()->getCountForMaxUnitCount(spawnUnitType)) { + break; + } + } + UnitPathInterface *newpath = NULL; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + Unit *spawned= new Unit(world->getNextUnitId(unit->getFaction()), newpath, + Vec2i(0), spawnUnitType, unit->getFaction(), + world->getMap(), CardinalDir::NORTH); + //SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to place unit for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,spawned->toString().c_str()); + bool placedSpawnUnit=false; + if(targetPos==Vec2i(-10,-10)) { + targetPos=unit->getTargetPos(); + } + if(spawnUnitAtTarget) { + placedSpawnUnit=world->placeUnit(targetPos, 10, spawned); + } else { + placedSpawnUnit=world->placeUnit(unit->getCenteredPos(), 10, spawned); + } + if(!placedSpawnUnit) { + //SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] COULD NOT PLACE UNIT for unitID [%d]\n",__FILE__,__FUNCTION__,__LINE__,spawned->getId()); + + // This will also cleanup newPath + delete spawned; + spawned = NULL; + } + else { + spawned->create(); + spawned->born(NULL); + world->getStats()->produce(unit->getFactionIndex(),spawned->getType()->getCountUnitProductionInStats()); + const CommandType *ct= spawned->getType()->getFirstAttackCommand(unit->getTargetField()); + if(ct == NULL){ + ct= spawned->computeCommandType(targetPos,map->getCell(targetPos)->getUnit(unit->getTargetField())); + } + if(ct != NULL){ + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + spawned->giveCommand(new Command(ct, targetPos)); + } + scriptManager->onUnitCreated(spawned); + } + } + } +} + // ==================== progress commands ==================== //VERY IMPORTANT: compute next state depending on the first order of the list @@ -3304,6 +3310,11 @@ void ParticleDamager::update(ParticleSystem *particleSystem) { SoundRenderer::getInstance().playFx(projSound, attacker->getCurrVector(), gameCamera->getPos()); } + //check for spawnattack + if(projectileType->getSpawnUnit()!=""){ + unitUpdater->spawnAttack(attacker,projectileType->getSpawnUnit(),projectileType->getSpawnUnitcount(),projectileType->getSpawnUnitAtTarget(),targetPos); + } + // check for shake and shake if(projectileType->isShake()==true){ World *world=attacker->getFaction()->getWorld(); diff --git a/source/glest_game/world/unit_updater.h b/source/glest_game/world/unit_updater.h index b40060fd..fae218b8 100644 --- a/source/glest_game/world/unit_updater.h +++ b/source/glest_game/world/unit_updater.h @@ -103,6 +103,7 @@ public: //update skills bool updateUnit(Unit *unit); + void spawnAttack(Unit *unit,string spawnUnit,int spawnUnitcount,bool spawnUnitAtTarget,Vec2i targetPos=Vec2i(-10,-10)); //update commands void updateUnitCommand(Unit *unit, int frameIndex);