Using the MagdalenaMonster as our base monster that we made in a previous tutorial this will show you how to turn your monster into an instant it monster. The magdalena base class can be downloaded from here:Magdalana Base Class
It’s possible to make your monsters fire instant hit effects at players, like lightning bolts or shock beams. This page will show you how to do that. There are a few things we need to declare as global and set in the defaults. In this example I will be making Magdalena shoot lightning bolts. But feel free to change the BeamEffectClass to anything you want. (xEmitter).
var class<xEmitter> BeamEffectClass; var int BeamDamage; var int AimError; var class<DamageType> BeamDamageType; defaultproperties { BeamEffectClass=class'XWeapons.NewLightningBolt' BeamDamageType=class'DamTypeSniperShot' BeamDamage=20 AimError=600 }
Just set BeamDamage to the amount of damage you want the lightning bolt to do. Set the AimError to how accurate you want the monster to be. A lower value will make your monster more accurate. Choose your BeamEffectClass (this is the visual effect you see in game).And set the damage type. In this case DamTypeSniperShot fits quite well with a lightning bolt. Check out the other damage types and choose a suitable one or create your own. Next we just need to add the RangedAttack function, this function tells the monster how to attack. And we need to include our own instant hit function. This function simply performs a trace to see what it hits first, if it hits a player then they will take damage and the effect will spawn. I have included code to bounce off the player without harming them if they have a ShieldGun active. Ok, so add the following to your monster class.
function RangedAttack(Actor A) { if ( bShotAnim ) { return; } bShotAnim = true; if ( Physics == PHYS_Swimming ) { SetAnimAction(IdleSwimAnim); } else if (FastTrace(A.Location,Location) == true) { SetAnimAction('Gesture_Taunt01'); FireBeam(); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); } } function FireBeam() { local Vector X,Y,Z, End, HitLocation, HitNormal, RefNormal; local Actor Other, mainArcHitTarget; local float TraceRange; local vector Start; local rotator Dir; Local xEmitter Beam; local bool bReflect; GetAxes(Rotation,X,Y,Z); Start = GetFireStart(X,Y,Z); Dir = Controller.AdjustAim(SavedFireProperties,Start,AimError); TraceRange = 10000; while(true) { bReflect = false; X = Vector(Dir); End = Start + TraceRange * X; Other = Trace(HitLocation, HitNormal, End, Start, true); if ( Other != None && Other != Instigator) { if (Other.IsA('xPawn') && xPawn(Other).CheckReflect(HitLocation, RefNormal, BeamDamage * 0.25)) { bReflect = true; } else if ( Other != mainArcHitTarget ) { if ( !Other.bWorldGeometry ) { if ( (Pawn(Other) != None)) { HitLocation = Other.Location; Other.TakeDamage(BeamDamage, Instigator, HitLocation, X, BeamDamageType); } } else { HitLocation = HitLocation + 2.0 * HitNormal; } } } else { HitLocation = End; HitNormal = Normal(Start - End); } Beam = Spawn(BeamEffectClass ,,, Start,); Beam.mSpawnVecA = HitLocation; if(bReflect == true) { Start = HitLocation; Dir = Rotator( X - 2.0*RefNormal*(X dot RefNormal) ); } else { break; } } }
Excellent. You can alter the RangedAttack function to make monster do other things like jump towards the player when it gets close. Just like the SkaarjPupae do! Take a look at the SkaarjPupae code to see how this was accomplished. Don’t forget to change the animation name in the RangedAttack function to something that matches your chosen skins animations.
Your monster class should look something like this.
class MagdalenaMonster extends Monster; var class<xEmitter> BeamEffectClass; var int BeamDamage; var int AimError; var class<DamageType> BeamDamageType; function RangedAttack(Actor A) { if ( bShotAnim ) { return; } bShotAnim = true; if ( Physics == PHYS_Swimming ) { SetAnimAction(IdleSwimAnim); } else if (FastTrace(A.Location,Location) == true) { SetAnimAction('Gesture_Taunt01'); FireBeam(); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); } } function FireBeam() { local Vector X,Y,Z, End, HitLocation, HitNormal, RefNormal; local Actor Other, mainArcHitTarget; local float TraceRange; local vector Start; local rotator Dir; Local xEmitter Beam; local bool bReflect; GetAxes(Rotation,X,Y,Z); Start = GetFireStart(X,Y,Z); Dir = Controller.AdjustAim(SavedFireProperties,Start,AimError); TraceRange = 10000; while(true) { bReflect = false; X = Vector(Dir); End = Start + TraceRange * X; Other = Trace(HitLocation, HitNormal, End, Start, true); if ( Other != None && Other != Instigator) { if (Other.IsA('xPawn') && xPawn(Other).CheckReflect(HitLocation, RefNormal, BeamDamage * 0.25)) { bReflect = true; } else if ( Other != mainArcHitTarget ) { if ( !Other.bWorldGeometry ) { if ( (Pawn(Other) != None)) { HitLocation = Other.Location; Other.TakeDamage(BeamDamage, Instigator, HitLocation, X, BeamDamageType); } } else { HitLocation = HitLocation + 2.0 * HitNormal; } } } else { HitLocation = End; HitNormal = Normal(Start - End); } Beam = Spawn(BeamEffectClass ,,, Start,); Beam.mSpawnVecA = HitLocation; if(bReflect == true) { Start = HitLocation; Dir = Rotator( X - 2.0*RefNormal*(X dot RefNormal) ); } else { break; } } } simulated function PlayDirectionalDeath(Vector HitLoc) { local float Decision; Decision = fRand(); if(Decision < 0.25) { PlayAnim('DeathF',, 0.1); } else if ( Decision > 0.25 && Decision < 0.50) { PlayAnim('DeathB',, 0.1); } else if ( Decision > 0.50 && Decision < 0.75) { PlayAnim('DeathL',, 0.1); } else { PlayAnim('DeathR',, 0.1); } } simulated function PlayDirectionalHit(Vector HitLoc) { local float Decision; Decision = fRand(); if(Decision < 0.25) { PlayAnim('TurnL',, 0.1); } else if ( Decision > 0.25 && Decision < 0.50) { PlayAnim('TurnR',, 0.1); } else if ( Decision > 0.50 && Decision < 0.75) { PlayAnim('TurnL',, 0.1); } else { PlayAnim('TurnR',, 0.1); } } defaultproperties { BeamEffectClass=class'XWeapons.NewLightningBolt' BeamDamageType=class'DamTypeSniperShot' BeamDamage=20 AimError=600 Mesh=SkeletalMesh'Magdalena.Magdalena' Skins(0)=Texture'MagdalenaTextures.magdalena_body' Skins(1)=Texture'MagdalenaTextures.magdalena_head' IdleWeaponAnim="Idle_Biggun" IdleHeavyAnim="Idle_Biggun" IdleRifleAnim="Idle_Rifle" TurnRightAnim="TurnR" TurnLeftAnim="TurnL" CrouchAnims(0)="CrouchF" CrouchAnims(1)="CrouchB" CrouchAnims(2)="CrouchL" CrouchAnims(3)="CrouchR" CrouchTurnRightAnim="Crouch_TurnR" CrouchTurnLeftAnim="Crouch_TurnL" AirStillAnim="Jump_Mid" AirAnims(0)="JumpF_Mid" AirAnims(1)="JumpB_Mid" AirAnims(2)="JumpL_Mid" AirAnims(3)="JumpR_Mid" TakeoffStillAnim="Jump_Takeoff" TakeoffAnims(0)="JumpF_Takeoff" TakeoffAnims(1)="JumpB_Takeoff" TakeoffAnims(2)="JumpL_Takeoff" TakeoffAnims(3)="JumpR_Takeoff" LandAnims(0)="JumpF_Land" LandAnims(1)="JumpB_Land" LandAnims(2)="JumpL_Land" LandAnims(3)="JumpR_Land" DodgeAnims(0)="DodgeF" DodgeAnims(1)="DodgeB" DodgeAnims(2)="DodgeL" DodgeAnims(3)="DodgeR" DoubleJumpAnims(0)="DoubleJumpF" DoubleJumpAnims(1)="DoubleJumpB" DoubleJumpAnims(2)="DoubleJumpL" DoubleJumpAnims(3)="DoubleJumpR" MovementAnims(0)="RunF" MovementAnims(1)="RunB" MovementAnims(2)="RunL" MovementAnims(3)="RunR" SwimAnims(0)="SwimF" SwimAnims(1)="SwimB" SwimAnims(2)="SwimL" SwimAnims(3)="SwimR" WalkAnims(0)="WalkF" WalkAnims(1)="WalkB" WalkAnims(2)="WalkL" WalkAnims(3)="WalkR" WallDodgeAnims(0)="WallDodgeF" WallDodgeAnims(1)="WallDodgeB" WallDodgeAnims(2)="WallDodgeL" WallDodgeAnims(3)="WallDodgeR" IdleRestAnim="Idle_Rest" IdleCrouchAnim="Crouch" IdleSwimAnim="Swim_Thread" IdleChatAnim="idle_chat" FireHeavyRapidAnim="Biggun_Aimed" FireHeavyBurstAnim="Biggun_Burst" FireRifleRapidAnim="Rifle_Aimed" FireRifleBurstAnim="Rifle_Burst" HitSound(0)=Sound'SkaarjPack_rc.injur1sk' HitSound(1)=Sound'SkaarjPack_rc.injur1sk' HitSound(2)=Sound'SkaarjPack_rc.injur1sk' HitSound(3)=Sound'SkaarjPack_rc.injur1sk' DeathSound(0)=Sound'SkaarjPack_rc.death1br' DeathSound(1)=Sound'SkaarjPack_rc.death1br' DeathSound(2)=Sound'SkaarjPack_rc.death1br' DeathSound(3)=Sound'SkaarjPack_rc.death1br' ChallengeSound(0)=Sound'SkaarjPack_rc.scuttle1pp' ChallengeSound(1)=Sound'SkaarjPack_rc.scuttle1pp' ChallengeSound(2)=Sound'SkaarjPack_rc.scuttle1pp' ChallengeSound(3)=Sound'SkaarjPack_rc.scuttle1pp' }
TIP – Randomize things! It makes everything more fun.
Recent Comments