Ok, for this
tutorial I'll show you how to code a near-perfect pipebomb cannon and a
pipebomb. The whole thing is relatively simple so I'll just go straight
into the basics with the code.
For the weapon, we'll have it fire out multiple pipebombs
and have alt-fire detonate them. Here's the code for the weapon complete
with comments:
class PipebombCannon expands TournamentWeapon;
var
bool bAlreadyFiring;
// Don't really need this but I'm a
lefty so it's nice to see a left handed model :-) function
setHand(float
Hand) { Super.SetHand(Hand); if (
Hand == 1 ) Mesh =
mesh(DynamicLoadObject("Botpack.PulseGunL",
class'Mesh')); else Mesh =
mesh'PulseGunR'; }
// Could use rateself but the bots
didn't use the gun right
function PlayFiring() // Plays the
firing animation { Owner.PlaySound(FireSound,
SLOT_Misc,2.0*Pawn(Owner).SoundDampening); PlayAnim(
'Boltend', 0.3 ); bWarnTarget
= (FRand() < 0.2); }
function AltFire( float Value ) //
This is the main core of the gun { local Vector
Start, X,Y,Z; local Pipebomb
PB; ForEach AllActors(class'PipeBomb', PB) // Calls
all pipebomb actors { //
Used settimer() because Explosion() blows player
up PB.Settimer(0.000001,
false); } // Necessary otherwise the
gun gets
jammed GoToState('AltFiring2'); }
////////////////////////////////////////////////// //
Normal projectile stuff state
NormalFire { function Projectile
ProjectileFire(class ProjClass, float ProjSpeed, bool
bWarn) { local Projectile
D; local int
i; local vector
Start,X,Y,Z; local Rotator StartRot,
AltRotation;
D =
Global.ProjectileFire(ProjClass, ProjSpeed,
bWarn); StartRot =
D.Rotation; Start =
D.Location; // Try changing 4 to 15 for
ultimate carnage for (i = 0; i< 4;
i++) { if
(AmmoType.UseAmmo(1))
{ AltRotation
=
StartRot; AltRotation.Pitch
+=
FRand()*3000-1500; AltRotation.Yaw
+=
FRand()*3000-1500; AltRotation.Roll
+=
FRand()*9000-4500; D
= Spawn(ProjectileClass,,, Start - 2 * VRand(),
AltRotation); } } }
Begin: FinishAnim(); PlayAnim('Still'); Sleep(0.4); //
Turns the pulsegun barrel at the end of
firing PlayPostSelect(); Finish() }
/////////////////////////////////////////////////// //
This just makes sure that the gun doesn't jam up state
AltFiring2 { function
EndState() { Finish(); }
function
AnimEnd() { Finish(); }
Begin: GotoState('Idle'); }
/////////////////////////////////////////////////// function
PlayIdleAnim() { PlayAnim('Still'); }
defaultproperties { AmmoName=Class'Botpack.PAmmo' PickupAmmoCount=40 bAltWarnTarget=True FireOffset=(X=15.000000,Y=-15.000000,Z=2.000000) ProjectileClass=Class'Pipebomb' AltProjectileClass=Class'Botpack.Plasmasphere'br>
shakemag=120.000000 AIRating=0.400000 RefireRate=0.800000 FireSound=Sound'UnrealShare.ASMD.TazerFire' SelectSound=Sound'Botpack.PulseGun.PulsePickup' Misc1Sound=Sound'UnrealShare.Stinger.EndFire' DeathMessage="%o
was boomed by %k's
%w" AutoSwitchPriority=6 InventoryGroup=6 PickupMessage="You
picked up the Pipebomb
cannon" ItemName="Pipebomb
cannon" PlayerViewOffset=(X=1.700000,Z=-2.000000) PlayerViewMesh=LodMesh'Botpack.PulseGunR' PickupViewMesh=LodMesh'Botpack.PulsePickup' ThirdPersonMesh=LodMesh'Botpack.PulseGun3rd' ThirdPersonScale=0.400000 PickupSound=Sound'UnrealShare.Pickups.WeaponPickup' Mesh=LodMesh'Botpack.PulsePickup' bNoSmooth=False SoundRadius=64 SoundVolume=255 CollisionRadius=27.000000 CollisionHeight=8.000000 }
|
Ok, so as you can see, altfire is where the real difference
is. Now all we need is a pipebomb. Here's the code, the projectile doesn't
have to be anything special:
class Pipebomb expands Projectile;
var bool
bCanHitOwner, bHitWater; var float Count, SmokeRate; var
ScriptedPawn WarnTarget; var int
NumExtraGrenades;
simulated function
PostBeginPlay() { local vector
X,Y,Z; local rotator
RandRot;
Super.PostBeginPlay(); if
( Level.NetMode != NM_DedicatedServer
) PlayAnim('WingIn'); //This'll
take a while to blow
up SetTimer(999999+FRand()*1,false);
if
( Role == ROLE_Authority
) { GetAxes(Instigator.ViewRotation,X,Y,Z); Velocity
= X * (Instigator.Velocity Dot X)*0.4 +
Vector(Rotation)
* (Speed + FRand() * 100); Velocity.z +=
210; RandRot.Pitch = FRand() * 1400 -
700; RandRot.Yaw = FRand() * 1400 -
700; RandRot.Roll = FRand() * 1400 -
700; MaxSpeed =
1000; Velocity = Velocity >>
RandRot; RandSpin(50000); bCanHitOwner
= False; if
(Instigator.HeadRegion.Zone.bWaterZone) { bHitWater
=
True; Disable('Tick'); Velocity=0.6*Velocity; } } }
simulated
function ZoneChange( Zoneinfo NewZone ) { local
waterring w; if (!NewZone.bWaterZone
|| bHitWater) Return;
bHitWater =
True; w =
Spawn(class'WaterRing',,,,rot(16384,0,0)); w.DrawScale
= 0.2; w.RemoteRole =
ROLE_None; Velocity=0.6*Velocity; }
simulated
function Timer() { // Try to use Explosion in the
alt-fire and for some reason the owner blows
up Explosion(Location+Vect(0,0,1)*16); }
simulated
function Landed( vector HitNormal ) { HitWall(
HitNormal, None ); }
simulated function ProcessTouch(
actor Other, vector HitLocation ) { if (
(Other!=instigator) || bCanHitOwner
) Explosion(HitLocation); }
simulated
function HitWall( vector HitNormal, actor Wall
) { bCanHitOwner = True; // Reflect
off Wall w/damping Velocity = 0.8*(( Velocity dot
HitNormal ) * HitNormal * (-2.0) +
Velocity); RandSpin(100000); speed =
VSize(Velocity); if ( Level.NetMode !=
NM_DedicatedServer
) PlaySound(ImpactSound, SLOT_Misc,
FMax(0.5, speed/800) ); if ( Velocity.Z > 400
) Velocity.Z = 0.5 * (400 +
Velocity.Z); else if ( speed < 20 )
{ bBounce =
False; SetPhysics(PHYS_None); } }
/////////////////////////////////////////////////////// function
BlowUp(vector HitLocation) { // Basic damage
stuff HurtRadius(damage, 200, 'corroded',
MomentumTransfer,
HitLocation); MakeNoise(1.0); }
simulated
function Explosion(vector HitLocation) { local
UT_FlameExplosion
s;
BlowUp(HitLocation); s =
spawn(class'UT_FlameExplosion',,,HitLocation); Spawn(Class'UT_Ringexplosion'); s.RemoteRole
=
ROLE_None; Destroy(); }
defaultproperties { speed=600.000000 MaxSpeed=1000.000000 Damage=90.000000 MomentumTransfer=50000 ImpactSound=Sound'UnrealShare.ASMD.TazerFire' Physics=PHYS_Falling RemoteRole=ROLE_SimulatedProxy AnimSequence=WingIn Texture=Texture'Botpack.ASMDAlt.ASMDAlt_a00' DrawScale=0.400000 DrawType=DT_Sprite Style=STY_Translucent AmbientGlow=64 bUnlit=True bBounce=True bFixedRotationDir=True DesiredRotation=(Pitch=12000,Yaw=5666,Roll=2334) }
|
Ok, so basically what we have is a pulsegun that fires out a
bunch of pipebombs. You can then use alt-fire to detonate them
prematurely. This can probably be improved, for example there's no code to
distinquish the owner of the pipebombs. So in theory any pipebombs on the
level shot by anybody can be blown up. However this is just a simple
example of a pipebomb weapon. Hope it helps.
|