UE2 - UT2kX Damage Over Time

  • Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
Does anybody know how to make a weapon do damage over time? I'm trying to make an poison dart sort of gun, that will fire a round and when it hits the person, causes i dunno, probably 10 damage over a period of 5 seconds. It will be a super weapon so no worries on overpoweredness. Im a noob at coding and it would be much appreciated if somebody could point me the right way. Thanks!

-Phoenix
 

War_Master

Member
May 27, 2005
702
0
16
The ChaosUT2 has a FlameThrower and a Crossbow. I think both of those weapons do damage by second after it hits. The flamethrower should do a burning over second damage while the crossbow shoots a poisoning darts.

There's also a FlameThrower in the ExcessiveOverkill mod but I dont remember if it does damage by second.

You can check those mods to see how they coded a weapon or projectile to do that kind of damage by seconds.
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Maybe you can you can give a player an inventory item that does damage to it's owner using a timer.
 

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
Im not sure on who to contact on the mods, i know Ballistics still has an active forum and they used a flamethrower with DoT. Hey Azura you wouldnt know how to do that or any example i could look at? I have the source code for Ut but no idea where to start looking
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Make an Actor or Inventory item that has a tick or timer that inflicts damage to it's owner over time. Then use some code to spawn it and set it's owner to whatever player got hit by a projectile.

Here's how to spawn something :
http://wiki.beyondunreal.com/Legacy:Creating_Actors_And_Objects

And for damage, look in whatever represents the Pawn class in UT2K4 (PlayHit() ? TakeDamage() ?).
 
Last edited:

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
That seems simple enough, though im not sure on what to use for the code to attach it to the player that was hit. Would it be spawn the actor at the location of the place where it hit the person, they pick it up (going to make it a pickup class) and it causes damage. Might try that
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
For inventory there is a standard function that allows to add inventory directly to any pawn without having to create a pickup. As for spawning an Actor (DamageActor extends Actor), set the location to that of the player (not sure if this is important) and make sure the pawn is the owner too. In your custom Actor, check if Owner != none and then use a timer to deal damage over time. Make sure your custom class is hidden (bHidden = true).
 
Last edited:

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
Ok, i think i understand almost everything now. The only thing left is what to do to find the location of the hit player. Its going to based off of the classic sniper rifle, and im going to insert it in the checks for HeadShot, well just below the HS check there is a check for a non headshot and that shall do (well i think it will work there). I'll add it into the HS code later. Im very fuzzy on UnrealScript as i only started a few weeks ago, so sorry for the mass of questions. Then would it work like this for the take damage actor?

.....
function TakeDamage()
{
Pawn.TakeDamage DamageMax, Instigator, HitLocation, Momentum*X, DamageType);
}

well something like that? Not sure what the ticks are or how to make it wait a certain amount of time. Thanks for all your help Azura
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Think objects. The weapon fires, if it hits a player it gives that player something that will deal damage over time. That something is the object you need to make. The player then simply receives that damage from that something. And this describes more or less the messages that will be going between objects.

Take a look at the code of the original Weapon to find whatever corresponds to weapon fire ( function Fire() ? ). Follow the calls from this function to other functions and you should find a variable that refers to another Pawn or player. This is where you can change the code so it gives something to the other player instead of doing damage directly.

After that, all that needs to be done is to create the actor that will deal damage to it's owner over time before destroying itself. That's where a Timer() will come in handy.

http://www.unrealwiki.com/Legacy:Actor/Methods
 

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
Ok that explanation helped me a lot. Thanks Azura. I've managed to get the damageactor finished although i haven't tested it. The problem though i still have is assigning the owner of the damageactor. I've taken the code from when it fires as you said and replace it with this
Code:
 else
// Old code used to be here to damage instead of spawn
                native(278) final function actor Spawn
            {
                class<actor>     DartPoison,
                optional actor   SpawnOwner,
            }
I have no idea what to set the SpawnOwner value as. I know i may seem rather stupid to keep asking this but i just can't think of what to set this to.

Lastly if you have time could you tell me if this would work for the damage actor? I think i have the basics but i can't help feeling that something is wrong in there
Code:
class DartPoison extends Actor

var DamageNum;

function TimeStart()
{
   SetTimer(1.5, true);
}

function Timer()
{
   Damage = (DamageMin + Rand(DamageMax - DamageMin)) * DamageAtten;
   if (owner != none)
   {
      Other.TakeDamage(Damage, Instigator, DamageType);
      DamageNum ++ 1;
       }
   else Destroy
   }
}
function CheckNum()
{
   if (DamageNum > 5)
     { 
        Destroy
        }
}

defaultproperties
{
   DamageMin=17
   DamageMax=25
   DamageType=Class'DamTypeDart'
}
 
Last edited:

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Code:
 else
// Old code used to be here to damage instead of spawn
                native(278) final function actor Spawn
            {
                class<actor>     DartPoison,
                optional actor   SpawnOwner,
            }

I have no idea what to set the SpawnOwner value as. I know i may seem rather stupid to keep asking this but i just can't think of what to set this to.

That doesn't look right. For an instant hit weapon like the sniper rifle, there should be a function somewhere that mentions something about tracing and maybe a parameter that points to a Pawn called Other. Other or whatever it's name is is what you're looking for. Once you've got that reference, you can easily spawn your Actor and set it's owner to the other Pawn.

Lastly if you have time could you tell me if this would work for the damage actor? I think i have the basics but i can't help feeling that something is wrong in there
Code:
class DartPoison extends Actor

var DamageNum;

function TimeStart()
{
   SetTimer(1.5, true);
}

function Timer()
{
   Damage = (DamageMin + Rand(DamageMax - DamageMin)) * DamageAtten;
   if (owner != none)
   {
      Other.TakeDamage(Damage, Instigator, DamageType);
      DamageNum ++ 1;
       }
   else Destroy
   }
}
function CheckNum()
{
   if (DamageNum > 5)
     { 
        Destroy
        }
}

defaultproperties
{
   DamageMin=17
   DamageMax=25
   DamageType=Class'DamTypeDart'
}


That looks more or less right except TimeStart() should be a standard Actor event like Spawned() or Begin().

For the actual damage cycle, you can do something like this :

Code:
DamageNum++; // Increment damage counter

if( DamageNum >= 5 ) // Perhaps test a variable so the number of times damage is dealt is configurable
self.Destroy(); // Destroy the Actor

To add some spice, you could send a message to the player the first time he's hit, telling him/her that he's been poisoned. Something like :

Code:
Ower.ClientMessage( "You have been hit by a poison dart !" );
 
Last edited:

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
Thanks again Azura, changed the Dart code to this to make it more tidy
Code:
class DartPoison extends Actor

var DamageNum;

function Spawned()
{
   SetTimer(1.5, true);
   Owner.ClientMessage( "You have been hit by a Poison Dart" )
}

function Timer()
{
   Damage = (DamageMin + Rand(DamageMax - DamageMin)) * DamageAtten;
   if (owner != none)
   {
      Other.TakeDamage(Damage, Instigator, DamageType);
      DamageNum++;
       }
   else self.Destroy();
   if ( DamageNum >= 5 )
     self.Destroy
}

defaultproperties
{
   DamageMin=17
   DamageMax=25
   DamageType=Class'DamTypeDart'
}
And for the part that didnt look right it is in the function DoTrace where it is checking for HeadShots on the Hit Location, the Else is when it isn't a Head Shot and just a normal head shot. For the owner could it be set by the HitLocation? So it would look like this?
Code:
else
                native(278) final function actor Spawn

                class<actor>     DartPoison,
                optional actor    HitLocation,
If that works it would be perfect. If not theres a variable that refers to Pawn(Other) so it hits both vehicles and people and perhaps that would work well for it? Since when it hits the vehicle/person it assigns them the Pawn(other) value so they get damaged right? Either way i dont mind. Thanks again
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
And for the part that didnt look right it is in the function DoTrace where it is checking for HeadShots on the Hit Location, the Else is when it isn't a Head Shot and just a normal head shot. For the owner could it be set by the HitLocation? So it would look like this?
Code:
else
                native(278) final function actor Spawn

                class<actor>     DartPoison,
                optional actor    HitLocation,

Please post all the code of the unmodified version of this function.
 

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
Here it is:
Code:
function DoTrace(Vector Start, Rotator Dir)
{
    local Vector X,Y,Z, End, HitLocation, HitNormal, ArcEnd;
    local Actor Other;
    local SniperWallHitEffect S;
    local Pawn HeadShotPawn;

    Weapon.GetViewAxes(X, Y, Z);
    if ( Weapon.WeaponCentered() )
        ArcEnd = (Instigator.Location +
			Weapon.EffectOffset.X * X +
			1.5 * Weapon.EffectOffset.Z * Z);
	else
        ArcEnd = (Instigator.Location +
			Instigator.CalcDrawOffset(Weapon) +
			Weapon.EffectOffset.X * X +
			Weapon.Hand * Weapon.EffectOffset.Y * Y +
			Weapon.EffectOffset.Z * Z);

    X = Vector(Dir);
    End = Start + TraceRange * X;
    Other = Weapon.Trace(HitLocation, HitNormal, End, Start, true);
    if ( (Level.NetMode != NM_Standalone) || (PlayerController(Instigator.Controller) == None) )
		Weapon.Spawn(class'TracerProjectile',Instigator.Controller,,Start,Dir);
    if ( Other != None && (Other != Instigator) )
    {
        if ( !Other.bWorldGeometry )
        {
            if (Vehicle(Other) != None)
                HeadShotPawn = Vehicle(Other).CheckForHeadShot(HitLocation, X, 1.0);

            if (HeadShotPawn != None)
                HeadShotPawn.TakeDamage(DamageMax * HeadShotDamageMult, Instigator, HitLocation, Momentum*X, DamageTypeHeadShot);
 			else if ( (Pawn(Other) != None) && Pawn(Other).IsHeadShot(HitLocation, X, 1.0))
                Other.TakeDamage(DamageMax * HeadShotDamageMult, Instigator, HitLocation, Momentum*X, DamageTypeHeadShot);
            else
                Other.TakeDamage(DamageMax, Instigator, HitLocation, Momentum*X, DamageType);
[b] Was putting code here and was going to removed Head Shot part [/b]
        }
        else
				HitLocation = HitLocation + 2.0 * HitNormal;
    }
    else
    {
        HitLocation = End;
        HitNormal = Normal(Start - End);
    }

    if ( (HitNormal != Vect(0,0,0)) && (HitScanBlockingVolume(Other) == None) )
    {
		S = Weapon.Spawn(class'SniperWallHitEffect',,, HitLocation, rotator(-1 * HitNormal));
		if ( S != None )
			S.FireStart = Start;
	}
}
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Ok, here's where to get a reference to the player that gets hit. Trace in the Weapon class is a function that "traces" a sort of line from Start to End and returns the first Pawn that intersects.
Code:
Other = Weapon.Trace(HitLocation, HitNormal, End, Start, true);

You can try this :
Code:
else
{
Spawn(class'DartPoison', Other, , Other.Location ) // Spawn DartPoison Actor and set it's owner as Other
}

And in DartPoison, make sure references are made with respect to Owner which is an in-built attribute/variable in the Actor class.

Code:
 Owner.TakeDamage(Damage, self, DamageType);
 
Last edited:

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
Just tried compiling the final files and its finding an error with the DartPoison class at the
Code:
Owner.TakeDamage(DamageMax, Instigator, DamageType);
it says
"Error, Call to 'TakeDamage': bad or missing parameter 1
By 1 does it mean the DamageMax? I've set that in the defaultproperties to 25, so i wonder why its getting an error.
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Default variables need to be defined in the same way as other variables (var ...).

Also, here's the parameters needed for TakeDamage. Put none for InstigatedBy.

TakeDamage( int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Momentum, name DamageType );
 

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
Ok its gotten past the 1st Parameter and now its complaining about the 2nd parameter. Same error as last time but with a 2. by "put none for InstigatedBy" do you mean after or before it? Also do i need to call InstigatedBy as a variable? I tried making it a Var Name InstigatedBy; but that didnt really fix anything.
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
none is what replaces the InstigatedBy parameter since your Actor is doing the damage and it isn't a Pawn (Pawn is a special type of Actor).

The line above is what is called a prototype. It describes the parameters a function expects and what their type should be. When you call a function, all that needs doing is to make replace those parameters with values or variables and make sure they correspond with the type that is required.
 
Last edited:

Phoenix_Wing

Official Kantham Stalker
Mar 28, 2008
386
0
0
California
So i should delete the InstigatedBy and put None where it used to be? Hm, just tried compiling that and it still says the same thing. Sorry that i've dragged this out so long, but im pretty useless with languages.