Author Topic: [fixed] 3.7.1, L64 - Splash attacks do incorrect damage  (Read 1303 times)

ctz

  • Summoner
  • **
  • Posts: 46
  • aka cathaur, formerly lyra
    • View Profile
[fixed] 3.7.1, L64 - Splash attacks do incorrect damage
« on: 14 January 2013, 07:18:37 »
I'm a fairly new player, and I have spent some time playing by myself (attacking my own units) to get the hang of game mechanics and stuff.  One thing I noticed was that if a unit fires a splash attack, then moves before the attack hits the target, the target will suffer less damage than usual.

Today I also noticed that archmages, when doing "hold position", always seem to do the damage of a direct hit to their targets, while units that were closer to the splash center than the target received less damage than the target.

Since I know some programming and this bug was starting to bother me, I decided to look at the source code.

The problem appears to be an incorrect splash center.  If the attacking unit moves, the splash center, for the purpose of calculating damage, becomes the attacking unit's position.  If the attacking unit targets another thing in its range, the splash center is the position of that other thing.  The area of effect, however, is still centered on the attack impact position.  If the attacker does not move, the splash center is the position of the targeted unit.

As a test, I put an archmage at range 4 from its target (another archmage), and fired an ice nova at the target.  By reducing the game speed and pausing frequently, I was able to tell the attacking archmage to move as soon as it fired its attack.  When the attack hit, the attacking archmage had <100 health left (out of 450), and the target had >300.

What I believe is the offending code, in source/glest_game/world/unit_updater.cpp, starting at line 1900:
Code: [Select]
void UnitUpdater::hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField){
   //hit attack positions
   if(ast->getSplash()){
      PosCircularIterator pci(map, targetPos, ast->getSplashRadius());
      while(pci.next()) {
         Unit *attacked= map->getCell(pci.getPos())->getUnit(targetField);
         if(attacked != NULL) {
            if(ast->getSplashDamageAll()
               || attacker->isAlly(attacked) == false
               || ( targetPos.x==pci.getPos().x && targetPos.y==pci.getPos().y )) {
               attacker->setLastAttackedUnitId(attacked->getId());
               scriptManager->onUnitAttacking(attacker);

               damage(attacker, ast, attacked, pci.getPos().dist(attacker->getTargetPos())); // BUG IS HERE
              }
         }
      }
   }
   else{
      Unit *attacked= map->getCell(targetPos)->getUnit(targetField);
      if(attacked!=NULL){
         damage(attacker, ast, attacked, 0.f);
      }
   }
}

Unit::getTargetPos() returns the target position.  In source/glest_game/world/world.cpp, Unit::setTargetPos is called in World::setUnitPosition:
Code: [Select]
void World::setUnitPosition(int unitId, Vec2i pos) {
   Unit* unit= findUnitById(unitId);
   if(unit == NULL) {
      throw megaglest_runtime_error("Can not find unit to set position unitId = " + intToStr(unitId));
   }
   unit->setTargetPos(pos);
   //unit->setPos(pos,true);
   this->moveUnitCells(unit);
}

I didn't look for where this function is called, but I am guessing it is called whenever a unit moves into a new cell.  Basically, we can't use the attacker's getTargetPos() to determine the splash center.

But the area of effect center is still the projectile impact position, because it uses the function's targetPos argument:
Code: [Select]
PosCircularIterator pci(map, targetPos, ast->getSplashRadius());

Non-splash projectiles also use targetPos to determine impact position.

So replacing attacker->getTargetPos() with targetPos should fix the bug.

Also, http://megaglest.org/linux-packages.html doesn't list Gentoo.  Running emerge megaglest as root will install MegaGlest on Gentoo.
« Last Edit: 25 May 2013, 23:16:10 by tomreyn »

softcoder

  • MegaGlest Team
  • Battle Machine
  • ********
  • Posts: 2,239
    • View Profile
Re: [bug], 3.7.1, L64 - Splash attacks do incorrect damage
« Reply #1 on: 15 January 2013, 05:03:24 »
Thanks for helping out. Your analysis is correct for splashes its using the wrong target and the correct way is to indeed switch as mentioned.

Since this change will not be backwards compatible with 3.7.1 we will need to determine when to patch the code in svn.

Thanks

titi

  • MegaGlest Team
  • Airship
  • ********
  • Posts: 4,240
    • View Profile
    • http://www.titusgames.de
Re: [bug], 3.7.1, L64 - Splash attacks do incorrect damage
« Reply #2 on: 3 May 2013, 10:40:09 »
pop
Try Megaglest! Improved Engine / New factions / New tilesets / New maps / New scenarios

softcoder

  • MegaGlest Team
  • Battle Machine
  • ********
  • Posts: 2,239
    • View Profile
Re: 3.7.1, L64 - Splash attacks do incorrect damage
« Reply #3 on: 21 May 2013, 21:20:34 »
Fixed in svn rev#: 4300

*NOTE: THIS IS NOT BACKWARD COMPATIBLE WITH OTHER DEV VERSIONS!

 

anything