/* Splash damage the two units directly infront and behind the unit that is being hit */ void hitAdjacentUnits (Tower tower, UnitListHeader* units, Path* path) { Unit* prevUnit; Unit* currUnit = findFurthestUnit (tower, units, path); prevUnit = units->first; /* Only have to loop through list if the unit we are hitting isn't the * first in the list, in which case we don't damage prevUnit or we are * damaging one unit twice */ if (prevUnit != currUnit) { while (prevUnit->next != NULL) { if (prevUnit->next == currUnit) break; prevUnit = prevUnit->next; } } /* Don't need to check anything as we know this unit is hit for sure */ damageUnit (currUnit, tower.damage); /* Damage the three units, make sure the next one exists and is on gameboard */ /* Can use this function on the previous unit and it will check if it * directly behind the currentUnit, and make sure that currUnit isn't the * first in the list * The adjoining units are hit for half tower damage */ if (nextUnitIsValid(prevUnit) && prevUnit != currUnit) { damageUnit (prevUnit, tower.damage / 2); } /*Make sure the next unit is directly ahead of the current unit*/ if (nextUnitIsValid(currUnit)) { damageUnit (currUnit->next, tower.damage / 2); } }
void World::damageUnitArea(int src,int x,int y,int range,int amount,int dmgtype,int flags) { int myowner = units.at(src).Owner; for(int i = x-range;i<=x+range;i++) { for(int j = y-range;j<=y+range;j++) { int uid = getUnitAt(i,j); if(uid!=-1 && (uid!=src || !(flags&TARGET_NONSELF))) { if(isUnitAvatar(uid)==0 || !(flags&TARGET_NONAVATAR)) { int owner = units.at(uid).Owner; if(flags&TARGET_ALLY && !(flags&TARGET_ENEMY) && owner==myowner) //damage only allies damageUnit(src,uid,amount); else if(!(flags&TARGET_ALLY) && flags&TARGET_ENEMY && owner!=myowner) //damage only enemies damageUnit(src,uid,amount); else if(!(flags&TARGET_ALLY) && !(flags&TARGET_ENEMY)) //damage both damageUnit(src,uid,amount); else if(flags&TARGET_ALLY && flags&TARGET_ENEMY) //damage both damageUnit(src,uid,amount); } } } } }
void Unit::attackUnit(Game* g,float damage,Unit* u){ damageUnit(damage); if(alertCooldown<=0){ b2World* world=g->getGSM()->getPhysics()->getWorld(); b2AABB alertRct; float x=getWorldX(),y=getWorldY(); alertRct.lowerBound.x=x-20; alertRct.lowerBound.y=y-20; alertRct.upperBound.x=x+20; alertRct.upperBound.y=y+20; AlertUnitsCallback cb; cb.attackingUnit=u; cb.me=this; world->QueryAABB(&cb,alertRct); alertCooldown=100; } FXParticleSprite *bloodpool=(FXParticleSprite*)g->getGSM()->getFXSys()->getParticle(BloodPoolParticleID); b2Vec2 vec= u->getBody()->GetPosition()-getBody()->GetPosition(); bloodpool->x=getX()+(rand()%50-25); bloodpool->y=getY()+(rand()%50-25); bloodpool->r=rand()/50; g->getGSM()->getWorld()->addLowerParticle(bloodpool); FXParticleSprite *blood=(FXParticleSprite*)g->getGSM()->getFXSys()->getParticle(BloodParticleID); vec= u->getBody()->GetPosition()-getBody()->GetPosition(); blood->x=getX(); blood->y=getY(); g->getGSM()->getWorld()->addParticle(blood); if(state==standby) targetUnit=u; }
/* * Chains the hits to the two units behind the hit unit, do half * damage to units hit by splash damage */ void chainHits (Tower tower, UnitListHeader* units, Path* path) { int i; Unit* unitNode = findFurthestUnit (tower, units, path); damageUnit (unitNode, tower.damage); /* Damage units behind the hit units */ for (i = 0; i < CHAINLENGTH; i++) { /* If there is no more units to hit, break. Damage for half health */ if (nextUnitIsValid(unitNode)) { unitNode = unitNode->next; damageUnit (unitNode, tower.damage / 2); } else { break; } } }
/* Hits all the units in the tower's range */ void hitAllUnits (Tower tower, UnitListHeader* units, Path* path) { Unit* currUnit = units->first; /* Traverse list and hit all in range */ while (currUnit != NULL) { if ((currUnit->pathLocation > 0) && inRange(tower, currUnit, path)) { damageUnit (currUnit, tower.damage); } currUnit = currUnit->next; } }
/* Hits the single furthest unit along the path that is within the tower's range */ void hitFurthestUnit (Tower tower, UnitListHeader* units, Path* path) { Unit* hitUnit = findFurthestUnit(tower, units, path); damageUnit (hitUnit, tower.damage); }
int World::handleMessage(Message& msg) { std::string type = msg.getString("msgtype"); if(type=="startturn") { int plyr = msg.getInt("player"); ManaCap[plyr] += 1; Mana[plyr] = ManaCap[plyr]; for(int i = 0;i<VerticalTileCount;i++) { for(int j = 0;j<HorizontalTileCount;j++) { int id = getUnitAt(j,i); if(id!=-1) { if(plyr==units.at(id).Owner) { for(int k = 0;k<units.at(id).abilityCount;k++) //lower cooldowns { if(units.at(id).abilities.at(k).currCooldown>0) { units.at(id).abilities.at(k).currCooldown -= 1; } } if(getUnitCanReady(id)) { Message msg("unitready"); msg.addValue("unit",std::to_string(id)); MsgMngr.sendMessage(msg); } } } } } } else if(type=="endturn") { int plyr = msg.getInt("player"); for(int i = 0;i<VerticalTileCount;i++) { for(int j = 0;j<HorizontalTileCount;j++) { int id = getUnitAt(j,i); if(id!=-1) { for(int i = 0;i<units.at(id).buffs.size();i++) { if(units.at(id).buffs.at(i).Duration!=-1) { units.at(id).buffs.at(i).Duration--; //reduce buff duration if(units.at(id).buffs.at(i).Duration==0) { units.at(id).buffs.erase(units.at(id).buffs.begin()+i); i--; } } } if(units.at(id).timedLife>0) { units.at(id).timedLife--; } } } } deadUnitCheck(); } else if(type=="unitcast") { castSpell(msg.getInt("caster"),msg.getInt("spell"),msg.getInt("targetx"),msg.getInt("targety")); } else if(type=="dodeadunitcheck") { deadUnitCheck(); } else if(type=="unitsummon") { summonUnit(msg.getString("unittype"),msg.getInt("x"),msg.getInt("y"),msg.getInt("owner")); } else if(type=="unitmove") { int uid = msg.getInt("unit"); int j = msg.getInt("targetx"); int i = msg.getInt("targety"); units.at(uid).MovePoints -= getUnitTileEnterCost(uid,units.at(uid).x,units.at(uid).y,j,i) + getUnitTileExitCost(uid,units.at(uid).x,units.at(uid).y,j,i); moveUnit(uid,j,i); } else if(type=="unitattack") { int uid = msg.getInt("unit"); int target = msg.getInt("target"); int attack = getUnitAttack(uid); if(attack>0) { Message msg("unitdamage"); msg.addValue("source",uid); msg.addValue("target",target); msg.addValue("amount",attack); msg.addValue("damagetype",DAMAGETYPE_ATTACK); MsgMngr.sendMessage(msg); } units.at(uid).hasAttacked = 1; units.at(uid).MovePoints -= getUnitAttackCost(uid); Animation a("Attack1","Attack",getSpritePos(units.at(target).x,units.at(target).y),1); ActiveAnimations.push_back(a); ActiveAnimations.at(ActiveAnimations.size()-1).play(); } else if(type=="unitdamage") { int src = msg.getInt("source"); int target = msg.getInt("target"); int amt = msg.getInt("amount"); damageUnit(src,target,amt); deadUnitCheck(); } else if(type=="unitdamagearea") { int src = msg.getInt("source"); int tx = msg.getInt("targetx"); int ty = msg.getInt("targety"); int range = msg.getInt("range"); int amt = msg.getInt("amount"); int dmgtype = msg.getInt("damagetype"); int flags = msg.getInt("targetflags"); damageUnitArea(src,tx,ty,range,amt,dmgtype,flags); deadUnitCheck(); } else if(type=="unitheal") { healUnit(msg.getInt("source"),msg.getInt("target"),msg.getInt("amount")); deadUnitCheck(); } else if(type=="unithealarea") { int src = msg.getInt("source"); int tx = msg.getInt("targetx"); int ty = msg.getInt("targety"); int range = msg.getInt("range"); int amt = msg.getInt("amount"); int flags = msg.getInt("targetflags"); healUnitArea(src,tx,ty,range,amt,flags); deadUnitCheck(); } else if(type=="unitdestroy") { units.at(msg.getInt("unit")).Life = 0; deadUnitCheck(); } else if(type=="unitteleport") { moveUnit(msg.getInt("unit"),msg.getInt("targetx"),msg.getInt("targety")); } else if(type=="unitdeath") { int uid = msg.getInt("unit"); tiles[units.at(uid).x][units.at(uid).y].isOccupied = false; //units.erase(uid); units.at(uid).UniqueId = -1; if(SelectionId == uid) { SelectionId = -1; } } else if(type=="unitready") { units.at(msg.getInt("unit")).hasAttacked = 0; //refresh attack status units.at(msg.getInt("unit")).MovePoints = 6; } else if(type=="unitsetlife") { units.at(msg.getInt("unit")).Life = msg.getInt("amount"); } else if(type=="unitsetmaxlife") { units.at(msg.getInt("unit")).maxLife = msg.getInt("amount"); } else if(type=="unitsetbaseattack") { units.at(msg.getInt("unit")).Attack = msg.getInt("amount"); } else if(type=="unitsetmovepoints") { units.at(msg.getInt("unit")).MovePoints = msg.getInt("amount"); } else if(type=="unitchangeowner") { units.at(msg.getInt("unit")).Owner = msg.getInt("owner"); } else if(type=="unitsettimedlife") { units.at(msg.getInt("unit")).timedLife = msg.getInt("amount"); } else if(type=="buffcreate") { Buff b(msg.getInt("bufftype"),msg.getInt("target"),msg.getInt("duration"),msg.getInt("owner"),msg.getInt("ispermanent"),0,0); units.at(msg.getInt("target")).buffs.push_back(b); } else if(type=="buffremove") { int uid = msg.getInt("target"); int bid = msg.getInt("bufftype"); for(int i = 0;i<world.units.at(uid).buffs.size();i++) { if(world.units.at(uid).buffs.at(i).BuffType==bid) { units.at(uid).buffs.erase(world.units.at(uid).buffs.begin()+i); i--; } } } else if(type=="buffdispel") { dispelUnit(msg.getInt("unit"),msg.getInt("targetflags")); } else if(type=="buffsetduration") { units.at(msg.getInt("unit")).buffs.at(msg.getInt("buff")).Duration = msg.getInt("duration"); } else if(type=="spellsetcurrentcooldown") { units.at(msg.getInt("unit")).abilities.at(msg.getInt("spell")).currCooldown = msg.getInt("cooldown"); } else if(type=="tiletypechange") { world.tiles[msg.getInt("x")][msg.getInt("y")].setType(msg.getInt("tiletype")); } else if(type=="playanimation") { Animation a(msg.getString("animation"),msg.getString("sound"),getSpritePos(msg.getInt("x"),msg.getInt("y")),atof(msg.getString("scalingfactor").c_str())); ActiveAnimations.push_back(a); ActiveAnimations.at(ActiveAnimations.size()-1).play(); } else if(type=="playsound") { ActiveAnimations.push_back(Animation("Attack1",msg.getString("sound"),0,0,1.0,1)); ActiveAnimations.at(ActiveAnimations.size()-1).play(); } return 0; }