Using the MagdalenaMonster as our base monster that we made in a previous tutorial this will show you how to turn your monster into a melee and projectile firing monster. The magdalena base class can be downloaded from here:Magdalana Base Class
This is basically combining the projectile firing monster with the melee monster. So lets carry on! We need to set up the monsters RangedAttack function. This function controls how the monster attacks. We also need to add 3 global variables at the top of the class.
var int MeleeDamage; var class<Projectile> ProjectileClass; var int AimError; function RangedAttack(Actor A) { if ( bShotAnim ) { return; } bShotAnim = true; if ( Physics == PHYS_Swimming ) { SetAnimAction(IdleSwimAnim); } else if ( VSize(A.Location - Location) < MeleeRange + CollisionRadius + A.CollisionRadius ) { SetAnimAction('gesture_beckon'); MeleeDamageTarget(MeleeDamage, vect(0,0,0)); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); } else if ( Velocity == vect(0,0,0) ) { SetAnimAction('Gesture_Taunt01'); FireProjectile(); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); } }
This RangedAttack function will make the monster fire projectiles at the player until it gets within MeleeRange. Then it will use melee attacks. The Velocity check will allow the monster to get a bit closer each time. Otherwise if you want the monster to attack as soon as it can remove the check. The (if ( Velocity == vect(0,0,0) ) ) bit.
Now we just need to add the defaultproperties and the FireProjectile function. Don’t forget to add the FireSound to the defaultproperties if you havn’t done so already.
function FireProjectile() { local vector FireStart,X,Y,Z; if ( Controller != None ) { FireStart = GetFireStart(X,Y,Z); Spawn(ProjectileClass,,,FireStart,Controller.AdjustAim(SavedFireProperties,FireStart,AimError)); PlaySound(FireSound,SLOT_Interact); } } defaultproperties { MeleeDamage=10 MeleeRange=80 bMeleeFighter=true ProjectileClass=class'SkaarjPack.KrallBolt' AimError=600 FireSound=Sound'WeaponSounds.ShockRifleAltFire' }
Excellent. You can alter the RangedAttack function to make the monster do other things like jump towards the player when it gets close, just like the SkaarjPupae do! Or run and fire projectiles at the same time just like Skaarj do! Take a look at the SkaarjPupae and Skaarj code to see how this was accomplished.
Your monster class should look something like this.
class MagdalenaMonster extends Monster; var int MeleeDamage; var class<Projectile> ProjectileClass; var int AimError; function RangedAttack(Actor A) { if ( bShotAnim ) { return; } bShotAnim = true; if ( Physics == PHYS_Swimming ) { SetAnimAction(IdleSwimAnim); } else if ( VSize(A.Location - Location) < MeleeRange + CollisionRadius + A.CollisionRadius ) { SetAnimAction('gesture_beckon'); MeleeDamageTarget(MeleeDamage, vect(0,0,0)); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); } else if ( Velocity == vect(0,0,0) ) { SetAnimAction('Gesture_Taunt01'); FireProjectile(); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); } } function FireProjectile() { local vector FireStart,X,Y,Z; if ( Controller != None ) { FireStart = GetFireStart(X,Y,Z); Spawn(ProjectileClass,,,FireStart,Controller.AdjustAim(SavedFireProperties,FireStart,AimError)); PlaySound(FireSound,SLOT_Interact); } } 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 { MeleeDamage=10 MeleeRange=80 bMeleeFighter=true ProjectileClass=class'SkaarjPack.KrallBolt' AimError=600 FireSound=Sound'WeaponSounds.ShockRifleAltFire' 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 – Look for monsters to your left then right, then left again before crossing a road.
Recent Comments