[Logo]
 
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
Retaliation Modifier  XML
Forum Index -> UnrealScript, Coding, Mapping, and 3rd party Mods
Author Message
Wail

Rampage

Joined: 09/20/2007 21:14:41
Messages: 183
Offline

Figured I'd post this here since I might be able to get some fresh perspectives on this problem.

Awhile back I created a new magic modifier for weapons called the Retaliation modifier, the idea being the same as the Retaliation skill, but more powerful since using a Retaliation weapon is a sacrifice of other useful modifier effects and not a passive ability.

My initial attempt to create this weapon "worked" in that it would return damage taken to creatures. However, at the same time it also reduced the damage reduction of a player wielding it, a rather unintended side effect.*

* I suspect that the reason why damage reduction was being ignored is because when a creature dies before its attack is resolved, it seems to ignore a player's damage reduction. So the effect here may have been a result of weapon-retaliation damage killing the creature, causing their attacks to ignore damage reduction.

With more recent versions I tried a new approach, which works as follows:
When the player takes damage, a temporary actor is given to the actor which caused the damage. This actor stores the amount of damage that was inflicted on the player by its attack (as modified by the weapon). When the actor dies (its lifespan is .1 seconds), it inflicts this damage to the creature.

The idea being that since the retaliation was causing the damage reduction issues due to the sequence of events, that using another actor with an enforced delay (its lifespan) would ensure that the player's damage reduction processing is done before the monster takes the damage.

I've noticed that this approach has fixed the issue with monster attacks ignoring damage reduction, but now the retaliation damage doesn't seem to work. I'm thinking perhaps the inventory's charge isn't being set properly (replication issue). I'm also not sure if I should be taking this approach, since I'd much rather not create another actor to achieve this effect, but I don't know that it's possible to work this without it.

My current code is pasted below if you'd like to check it out and offer suggestions.

Code:
class RW_DWRetaliating extends RW_DWRPGWeapon
 	HideDropDown
 	CacheExempt
   config(UT2004RPG);
 
 
 function AdjustPlayerDamage(out int Damage, Pawn InstigatedBy, Vector HitLocation, out Vector Momentum, class<DamageType> DamageType)
 {
 	local int TempDamage;
 	local Inventory MyInv;
 
   if (!bIdentified)
 		Identify();
 
 	if (Pawn(Owner).Controller.bGodMode != true)
 	{
      //Retaliation effects only apply against Monsters who aren't on our team
      if ( Monster(InstigatedBy) != none && InstigatedBy.GetTeamNum() != Pawn(Owner).GetTeamNum() && InstigatedBy != Pawn(Owner))       // Added check here to prevent the retaliation target from being the player because it was happening too often in play
 	   {
         TempDamage = Damage * (1.5 + Modifier/2); //Simplified calculation here
 
         if (TempDamage > Modifier * 2000)
            TempDamage = Modifier * 2000;
 
         MyInv = spawn(class'Status_RetaliationInv',,, InstigatedBy.Location);
         MyInv.Charge = TempDamage;
         MyInv.GiveTo(InstigatedBy);
      }
 	}
 
   Super.AdjustPlayerDamage(Damage, InstigatedBy, HitLocation, Momentum, DamageType);
 
 }



Code:
class Status_RetaliationInv extends Inventory;
 
 function Destroyed()
 {
     local Actor A;
 
     // Apply the damage (set as this inventory item's Charge in the Retaliation Weapon), then remove from owner's inventory.
     if( Pawn(Owner)!=None )
     {
         if (Pawn(Owner).Health > 0)
         {
            Pawn(Owner).TakeDamage(Charge, Pawn(Owner), vect(0,0,0), vect(0,0,0), class'DamTypeRetaliation');
 
            A = spawn(class'FX_RetaliationDamage',,, Owner.Location);
     		   if (A != None)
     		   {
     		      A.RemoteRole = ROLE_SimulatedProxy;
     		      A.PlaySound(sound'ONSVehicleSounds-S.LaserSounds.Laser17',,2.5*Owner.TransientSoundVolume,,Owner.TransientSoundRadius);
     		   }
         }
         Pawn(Owner).DeleteInventory( Self );
     }
     if ( ThirdPersonActor != None )
        ThirdPersonActor.Destroy();
 }



Szlat

Wicked Sick!

Joined: 05/18/2005 18:32:41
Messages: 2124
Location: UK
Offline

At a quick glance I can't see the problem. I often find the easiest way to debug these things is to stick loads of Log statements in, then see which variable had the unexpected value.

You could try putting a default on Charge and see if it does that much damage? Perhaps it is destroying itself before the Charge gets set.

And if it is doing zero retaliation damage, you do not know if the bug is fixed, as you will not be killing the monsters

The key bit of code is Pawn.TakeDamage. This calls Weapon.AdjustPlayerDamage which is where your retaliation is being done, before it calls Level.Game.ReduceDamage, where is where the NetDamage is called which uses the DB/DR. And since in the initial version you kill the attacker in the AdjustPlayerDamage, by the time you get to the NetDamage code, you have no attacker, so it just processes the attack using normal non-RPG code and does not use the bulk of the RPG NetDamage code.

A few side points:
  • in AdjustPlayerDamage you ought to check that the damage is not Relatiation damage - you should not generate retaliation off retaliation damage
  • it doesn't look like the person with the weapon will get credit for the kill or damage
  • I think at the AdjustPlayerDamage part it has not yet taken into account the attackers udamage status - so if the attacker has a triple, you will be retaliating on the single damage rather than the triple

    I think if you tone down the retaliation so you never kill the attacker, you will be ok with the original code. As it is, it looks like you are trying to go for too powerful an effect. Personally, I would prefer the xp from half a kill rather than nothing from a kill.
  • Wail

    Rampage

    Joined: 09/20/2007 21:14:41
    Messages: 183
    Offline

    Thanks for the suggestions Szlat. After posting that I made some changes per your suggestions:

    -Retaliation damage won't be retaliated against - Initially I had not done this as the weapon modifier is only intended to work against Monsters, however I may eventually introduce a Monster with Retaliation, so I may as well.
    -Adjusted the inventory item to receive the Retaliation weapon's owner for damage instigation / experience purposes
    -Retaliation now takes into account the triggering attack's UDamage status

    I also adjusted the way the weapon works so that the inventory approach is only triggered if the damage you'll be doing exceeds the monster's health -- I would prefer not to be spawning additional actors to achieve the effect, so it's probably better to check and use the direct Monster.TakeDamage way when possible.

    I'm thinking as an additional balancing factor I may want to add in some kind of time limit on how often the effect can trigger, but I need to do some testing before I do this.
     
    Forum Index -> UnrealScript, Coding, Mapping, and 3rd party Mods
    Go to: