Merge pull request #22 from titison/feature/spawnattack_at_enemy
Feature/spawnattack at enemy
This commit is contained in:
commit
c2dcda0969
|
@ -24,6 +24,10 @@ ProjectileType::ProjectileType() {
|
||||||
projectileParticleSystemType=NULL;
|
projectileParticleSystemType=NULL;
|
||||||
attackStartTime=0.0f;
|
attackStartTime=0.0f;
|
||||||
|
|
||||||
|
spawnUnit="";
|
||||||
|
spawnUnitcount=0;
|
||||||
|
spawnUnitAtTarget=false;
|
||||||
|
|
||||||
shake=false;
|
shake=false;
|
||||||
shakeIntensity=0;
|
shakeIntensity=0;
|
||||||
shakeDuration=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()));
|
loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleNode->getAttribute("path")->getRestrictedValue()));
|
||||||
setProjectileParticleSystemType(projectileParticleSystemType);
|
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")){
|
if(projectileNode->hasChild("hitshake")){
|
||||||
const XmlNode *hitShakeNode= projectileNode->getChild("hitshake");
|
const XmlNode *hitShakeNode= projectileNode->getChild("hitshake");
|
||||||
shake=hitShakeNode->getAttribute("enabled")->getBoolValue();
|
shake=hitShakeNode->getAttribute("enabled")->getBoolValue();
|
||||||
|
|
|
@ -41,6 +41,10 @@ protected:
|
||||||
SoundContainer hitSounds;
|
SoundContainer hitSounds;
|
||||||
float attackStartTime;
|
float attackStartTime;
|
||||||
|
|
||||||
|
string spawnUnit;
|
||||||
|
int spawnUnitcount;
|
||||||
|
bool spawnUnitAtTarget;
|
||||||
|
|
||||||
bool shake;
|
bool shake;
|
||||||
int shakeIntensity;
|
int shakeIntensity;
|
||||||
int shakeDuration;
|
int shakeDuration;
|
||||||
|
@ -64,6 +68,10 @@ public:
|
||||||
float getAttackStartTime() const {return attackStartTime;}
|
float getAttackStartTime() const {return attackStartTime;}
|
||||||
void setAttackStartTime(float value) {attackStartTime=value;}
|
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 isShake() const{return shake;}
|
||||||
bool isShakeCameraDistanceAffected() const{return shakeCameraDistanceAffected;}
|
bool isShakeCameraDistanceAffected() const{return shakeCameraDistanceAffected;}
|
||||||
int getShakeDuration() const{return shakeDuration;}
|
int getShakeDuration() const{return shakeDuration;}
|
||||||
|
|
|
@ -834,6 +834,7 @@ AttackSkillType::AttackSkillType() {
|
||||||
splashRadius= 0;
|
splashRadius= 0;
|
||||||
spawnUnit="";
|
spawnUnit="";
|
||||||
spawnUnitcount=0;
|
spawnUnitcount=0;
|
||||||
|
spawnUnitAtTarget=false;
|
||||||
splashParticleSystemType= NULL;
|
splashParticleSystemType= NULL;
|
||||||
|
|
||||||
for(int i = 0; i < fieldCount; ++i) {
|
for(int i = 0; i < fieldCount; ++i) {
|
||||||
|
@ -886,11 +887,16 @@ void AttackSkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
||||||
|
|
||||||
if (sn->hasChild("unit")) {
|
if (sn->hasChild("unit")) {
|
||||||
spawnUnit = sn->getChild("unit")->getAttribute("value")->getValue();
|
spawnUnit = sn->getChild("unit")->getAttribute("value")->getValue();
|
||||||
spawnUnitcount
|
spawnUnitcount = sn->getChild("unit")->getAttribute("amount")->getIntValue();
|
||||||
= sn->getChild("unit")->getAttribute("amount")->getIntValue();
|
if(sn->getChild("unit")->hasAttribute("spawnAtTarget")) {
|
||||||
|
spawnUnitAtTarget = sn->getChild("unit")->getAttribute("spawnAtTarget")->getBoolValue();
|
||||||
|
} else {
|
||||||
|
spawnUnitAtTarget = false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
spawnUnit = "";
|
spawnUnit = "";
|
||||||
spawnUnitcount = 0;
|
spawnUnitcount = 0;
|
||||||
|
spawnUnitAtTarget = false;
|
||||||
}
|
}
|
||||||
//attack fields
|
//attack fields
|
||||||
const XmlNode *attackFieldsNode= sn->getChild("attack-fields");
|
const XmlNode *attackFieldsNode= sn->getChild("attack-fields");
|
||||||
|
@ -1055,6 +1061,8 @@ void AttackSkillType::saveGame(XmlNode *rootNode) {
|
||||||
attackSkillTypeNode->addAttribute("spawnUnit",spawnUnit, mapTagReplacements);
|
attackSkillTypeNode->addAttribute("spawnUnit",spawnUnit, mapTagReplacements);
|
||||||
// int spawnUnitcount;
|
// int spawnUnitcount;
|
||||||
attackSkillTypeNode->addAttribute("spawnUnitcount",intToStr(spawnUnitcount), mapTagReplacements);
|
attackSkillTypeNode->addAttribute("spawnUnitcount",intToStr(spawnUnitcount), mapTagReplacements);
|
||||||
|
// bool spawnUnitAtTarget;
|
||||||
|
attackSkillTypeNode->addAttribute("spawnUnitAtTarget",intToStr(spawnUnitAtTarget), mapTagReplacements);
|
||||||
// bool projectile;
|
// bool projectile;
|
||||||
attackSkillTypeNode->addAttribute("projectile",intToStr(projectile), mapTagReplacements);
|
attackSkillTypeNode->addAttribute("projectile",intToStr(projectile), mapTagReplacements);
|
||||||
// ParticleSystemTypeProjectile* projectileParticleSystemType;
|
// ParticleSystemTypeProjectile* projectileParticleSystemType;
|
||||||
|
|
|
@ -292,6 +292,7 @@ private:
|
||||||
|
|
||||||
string spawnUnit;
|
string spawnUnit;
|
||||||
int spawnUnitcount;
|
int spawnUnitcount;
|
||||||
|
bool spawnUnitAtTarget;
|
||||||
bool projectile;
|
bool projectile;
|
||||||
//ParticleSystemTypeProjectile* projectileParticleSystemType;
|
//ParticleSystemTypeProjectile* projectileParticleSystemType;
|
||||||
SoundContainer projSounds;
|
SoundContainer projSounds;
|
||||||
|
@ -318,6 +319,7 @@ public:
|
||||||
inline float getAttackStartTime() const {return attackStartTime;}
|
inline float getAttackStartTime() const {return attackStartTime;}
|
||||||
inline string getSpawnUnit() const {return spawnUnit;}
|
inline string getSpawnUnit() const {return spawnUnit;}
|
||||||
inline int getSpawnUnitCount() const {return spawnUnitcount;}
|
inline int getSpawnUnitCount() const {return spawnUnitcount;}
|
||||||
|
inline bool getSpawnUnitAtTarget() const {return spawnUnitAtTarget;}
|
||||||
|
|
||||||
//get proj
|
//get proj
|
||||||
inline bool getProjectile() const {return projectile;}
|
inline bool getProjectile() const {return projectile;}
|
||||||
|
|
|
@ -270,56 +270,9 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
||||||
else if(unit->getCommandSize() > 0) {
|
else if(unit->getCommandSize() > 0) {
|
||||||
Command *command= unit->getCurrCommand();
|
Command *command= unit->getCurrCommand();
|
||||||
if(command != NULL) {
|
if(command != NULL) {
|
||||||
const CommandType *ct = command->getCommandType();
|
|
||||||
|
|
||||||
const AttackCommandType *act= dynamic_cast<const AttackCommandType*>(command->getCommandType());
|
const AttackCommandType *act= dynamic_cast<const AttackCommandType*>(command->getCommandType());
|
||||||
if( act != NULL && act->getAttackSkillType() != NULL &&
|
spawnAttack(unit,act->getAttackSkillType()->getSpawnUnit(),act->getAttackSkillType()->getSpawnUnitCount(),act->getAttackSkillType()->getSpawnUnitAtTarget());
|
||||||
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());
|
|
||||||
if(!world->placeUnit(unit->getCenteredPos(), 10, spawned)) {
|
|
||||||
//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(command->getPos(),command->getUnit());
|
|
||||||
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->getMeetingPos()));
|
|
||||||
}
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,6 +309,65 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
||||||
return processUnitCommand;
|
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 ====================
|
// ==================== progress commands ====================
|
||||||
|
|
||||||
//VERY IMPORTANT: compute next state depending on the first order of the list
|
//VERY IMPORTANT: compute next state depending on the first order of the list
|
||||||
|
@ -3298,6 +3310,11 @@ void ParticleDamager::update(ParticleSystem *particleSystem) {
|
||||||
SoundRenderer::getInstance().playFx(projSound, attacker->getCurrVector(), gameCamera->getPos());
|
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
|
// check for shake and shake
|
||||||
if(projectileType->isShake()==true){
|
if(projectileType->isShake()==true){
|
||||||
World *world=attacker->getFaction()->getWorld();
|
World *world=attacker->getFaction()->getWorld();
|
||||||
|
|
|
@ -103,6 +103,7 @@ public:
|
||||||
|
|
||||||
//update skills
|
//update skills
|
||||||
bool updateUnit(Unit *unit);
|
bool updateUnit(Unit *unit);
|
||||||
|
void spawnAttack(Unit *unit,string spawnUnit,int spawnUnitcount,bool spawnUnitAtTarget,Vec2i targetPos=Vec2i(-10,-10));
|
||||||
|
|
||||||
//update commands
|
//update commands
|
||||||
void updateUnitCommand(Unit *unit, int frameIndex);
|
void updateUnitCommand(Unit *unit, int frameIndex);
|
||||||
|
|
Loading…
Reference in New Issue