Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: consistent attack damage in each direction #346

Open
Gerwin2k opened this issue Nov 16, 2020 · 5 comments
Open

Enhancement: consistent attack damage in each direction #346

Gerwin2k opened this issue Nov 16, 2020 · 5 comments

Comments

@Gerwin2k
Copy link

Attack damage is in several (all?) cases very dependent on the location of the attacker and the target.
For example: A quad vehicle firing on another quad vertically (north/south) does full damage.
A quad firing on a quad horizontally (east/west) does only half that damage. Often this means that the attacker has a longer time to stay in 'the green', and therefore keep full attack power, amplifying this difference.

This was pointed out in the "Dune II insiders Guide", Page 279, here:
http://nyerguds.arsaneus-design.com/manuals/Dune%20II/Dune%20II%20-%20Insider's%20Guide.pdf

This behavior is obviously retained in OpenDUNE and Dune Dynasty.
Question 1: Where does the code reside that is responsible for this typical behavior?
Question 2: Should this qualify for an optional enhancement, where directional effect is removed? My vote would be yes.

Thanks

@miniupnp
Copy link
Contributor

@Gerwin2k
Copy link
Author

Gerwin2k commented Jan 3, 2021

Thanks,
but AFAIK this Unit_Damage procedure is called in only three places. One call in map.c is map explosion related, the other two calls are in unit.c, these are specific to movement and then again specific to sonic_blast.

It must be somewhere else...

@Gerwin2k
Copy link
Author

Gerwin2k commented Jan 9, 2021

Correction. The call in map.c is the one

if (!(u->o.type == UNIT_SANDWORM && type == EXPLOSION_SANDWORM_SWALLOW) && u->o.type != UNIT_FRIGATE) {
Unit_Damage(u, hitpoints >> (distance >> 2), 0);
}

@Gerwin2k
Copy link
Author

Gerwin2k commented Jan 10, 2021

In Dune Dynasty, I added some text output to the damage function, like below. But now it seems there is another oddity messing up my intentions. A normal tank shot results in two different calls to this damage section, with often a different amount of damage. The first call will be of type UNIT_BULLET, the second one will be the type no. of the target. A Quad, that by design shoots twice, will lead to four calls.

My intention was to filter out damage done by guns such as on quads and tanks, and make these unaffected by any distance. The distance seemed to be rather small anyways. It is not about the distance from attacking vehicle to target vehicle, but the distance between the visible small bullet impact point and the center of the target vehicle.

if (unit->o.hitpoints >= damage) {
 GUI_DisplayText("Damage:%u Range:%u", 2, (unsigned int) damage, (unsigned int) range);
unit->o.hitpoints -= damage;
} 

Edit, I found some method that makes the gun type weapons consistent in every direction, without affecting 1) other types of explosions and 2) the damage to vehicles adjacent to the target. For this I used "unitOriginEncoded" to source the origin of the damage. If it matches the listed units, and the explosion is pretty close, then full damage is done.
This makes the listed units stronger compared to the non-listed ones, so I substracted 1 damage (hitpoints--) to compensate this a bit.

const Unit *unit_origin = Tools_Index_GetUnit(unitOriginEncoded);
uint16 origin=255;
....
if (!(u->o.type == UNIT_SANDWORM && type == EXPLOSION_SANDWORM_SWALLOW) && u->o.type != UNIT_FRIGATE) {
if (unit_origin != NULL) origin=unit_origin->o.type;
if (origin==UNIT_INFANTRY     || 
    origin==UNIT_SOLDIER      || 
    origin==UNIT_TANK         || 
    origin==UNIT_SIEGE_TANK   || 
    origin==UNIT_DEVASTATOR   || 
    origin==UNIT_TRIKE        || 
    origin==UNIT_RAIDER_TRIKE ||  
    origin==UNIT_QUAD) {if ((distance >> 2)==1) {distance=0; hitpoints--;}}

   Unit_Damage(u, hitpoints >> (distance >> 2), 0);

@Gerwin2k
Copy link
Author

Gerwin2k commented Jan 10, 2021

Much better modification of the map.c section is below. This is for the Dune Dynasty fork. The "enhancement_attack_dir_consistency" configuration variable needs to be defined and handled properly elsewhere, of course.

Test with Harkonnen Quad on Quad: Original East to West attack takes 23 double shots. Original North to South takes 10 shots. With this enhancement it always takes 17 shots.
Test with Harkonnen Tank on Tank: Original East to West attack takes 17 shots. Original North to South takes 8 shots. With this enhancement it always takes 13 shots.
Test with Atreides Trike on Trike: Original East to West attack takes 25 shots. Original North to South takes 10 shots. With this enhancement it always takes 17 shots.

Damage to units adjacent to the target should be the same as it was. This enhancement does not affect stationary turret guns, because I cannot easily identify them in the current procedure.

  /* GB 2021: 4x new lines for enhancement_attack_dir_consistency */
  const Unit *unit_origin = Tools_Index_GetUnit(unitOriginEncoded);
  uint16 dist_adjust;
  uint16 origin = UNIT_INVALID;
  if (unit_origin != NULL) origin=unit_origin->o.type;

  if (!s_debugNoExplosionDamage && hitpoints != 0) {
      PoolFindStruct find;

      for (Unit *u = Unit_FindFirst(&find, HOUSE_INVALID, UNIT_INVALID);
              u != NULL;
              u = Unit_FindNext(&find)) {
          const UnitInfo *ui = &g_table_unitInfo[u->o.type];
          uint16 distance;
          Team *t;
          Unit *us;
          Unit *attack;

          distance = Tile_GetDistance(position, u->o.position) >> 4;
          if (distance >= reactionDistance) continue;

          /* GB 2021: 2x new lines for enhancement_attack_dir_consistency */
          uint16 hp_adjust = hitpoints;
          dist_adjust=distance >> 2;

          if (!(u->o.type == UNIT_SANDWORM && type == EXPLOSION_SANDWORM_SWALLOW) && u->o.type != UNIT_FRIGATE) {

             /* GB 2021: 24x new and adjusted lines for enhancement_attack_dir_consistency */
             if (enhancement_attack_dir_consistency == true)
             {
               if (origin == UNIT_INFANTRY     ||
                   origin == UNIT_SOLDIER      ||
                   origin == UNIT_TANK         ||
                   origin == UNIT_SIEGE_TANK   ||
                   origin == UNIT_DEVASTATOR   ||
                   origin == UNIT_TRIKE        ||
                   origin == UNIT_RAIDER_TRIKE ||
                   origin == UNIT_QUAD)
                   /* Gun turret identifies as UNIT_INVALID */
               {
                 if ((Tile_Center(position).x==Tile_Center(u->o.position).x) && (Tile_Center(position).y==Tile_Center(u->o.position).y))
                 {
                   if (hitpoints>10) {hp_adjust-=6;} /* Tanks */
                   if (hitpoints> 5) {hp_adjust-=1;} /* Quads, Tanks again */
                   if (hitpoints> 4) {hp_adjust-=2;} /* Trikes, Quads, Tanks again */
                   dist_adjust = 0;
                 }
               }
             }

             /* GUI_DisplayText("hitpoints-adj.:%u, distance-adj:%u, type:%u, origin-type:%u", 2, (unsigned int) hp_adjust, dist_adjust ,(unsigned int)u->o.type, (unsigned int) origin );*/

             Unit_Damage(u, hp_adjust >> dist_adjust, 0);

             /* Originally it was just this:  Unit_Damage(u, hitpoints >> (distance >> 2), 0); */
          }  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants