Worst-case scenario: the UEd Goblin wipes the map and burns down your house.
Legacy:EONSBioRifle
Status: Incomplete Functionality. Feel free to help me finish this weapon!
Description: The EONS Bio Rifle is intended as an improved version of the UT2004 Bio Rifle, primarily for use in the ONS gametype where long engagement ranges and the interaction of biogoo with vehicles makes the weapon subpar.
New Features:
1. Single Fire Primary is gone. Primary fire now charges up on hold. Single glob fire can be achieved via tapping the fire button.
2. (Does not work) Using the charged fire mode, the EONS Bio Rifle can be alternated between firing a single concentrated glob and a horizontal line of blobs (number of blobs determined by current charge level).
3. (Currently disabled, seeking a solution to 2.) When the aiming reticle is held on a target for a short period of time, the Bio Rifle automatically primes itself to launch glob projectiles at a higher velocity, giving the weapon additional effectiveness at longer ranges.
4. Secondary fire unleashes a stream of aerosolized bio goo, providing effective destruction in a short range at the expense of quickly expending the weapon's ammo.*
- This firing mode has a minor error that shows up in UT2004's log,
Current code is provided below.
//=================== // EONSBioRifle // Alternate Fire uses code modified from Mr. Pants' Excessive Overkill FlamethrowerEX written by Dan 'MadNad' Woodall //=================== class EONSBioRifle extends BioRifle; var Pawn SeekTarget; var float LockTime, UnLockTime, SeekCheckTime; var bool bLockedOn, bBreakLock; var bool bLineSpread; var Sound LockOnSound, LockBrokenSound; var() float SeekCheckFreq, SeekRange; var() float LockRequiredTime, UnLockRequiredTime; var() float LockAim; var() Color CrosshairColor; var() float CrosshairX, CrosshairY; replication { reliable if (Role == ROLE_Authority && bNetOwner) bLockedOn; reliable if (Role < ROLE_Authority) ServerSetLineSpread, ServerClearLineSpread; } function Tick(float dt) { local Pawn Other; local Vector StartTrace; local Rotator Aim; local float BestDist, BestAim; if (Instigator == None || Instigator.Weapon != self) return; if ( Role < ROLE_Authority ) return; if ( !Instigator.IsHumanControlled() ) return; if (Level.TimeSeconds > SeekCheckTime) { if (bBreakLock) { bBreakLock = false; bLockedOn = false; SeekTarget = None; } StartTrace = Instigator.Location + Instigator.EyePosition(); Aim = Instigator.GetViewRotation(); BestAim = LockAim; Other = Instigator.Controller.PickTarget(BestAim, BestDist, Vector(Aim), StartTrace, SeekRange); if ( CanLockOnTo(Other) ) { if (Other == SeekTarget) { LockTime += SeekCheckFreq; if (!bLockedOn && LockTime >= LockRequiredTime) { bLockedOn = true; PlayerController(Instigator.Controller).ClientPlaySound(LockOnSound); } } else { SeekTarget = Other; LockTime = 0.0; } UnLockTime = 0.0; } else { if (SeekTarget != None) { UnLockTime += SeekCheckFreq; if (UnLockTime >= UnLockRequiredTime) { SeekTarget = None; if (bLockedOn) { bLockedOn = false; PlayerController(Instigator.Controller).ClientPlaySound(LockBrokenSound); } } } else bLockedOn = false; } SeekCheckTime = Level.TimeSeconds + SeekCheckFreq; } } function bool CanLockOnTo(Actor Other) { local Pawn P; P = Pawn(Other); if (P == None || P == Instigator || !P.bProjTarget) return false; if (!Level.Game.bTeamGame) return true; if ( (Instigator.Controller != None) && Instigator.Controller.SameTeamAs(P.Controller) ) return false; return ( (P.PlayerReplicationInfo == None) || (P.PlayerReplicationInfo.Team != Instigator.PlayerReplicationInfo.Team) ); } simulated event RenderOverlays( Canvas Canvas ) { if (bLockedOn) { Canvas.DrawColor = CrosshairColor; Canvas.DrawColor.A = 255; Canvas.Style = ERenderStyle.STY_Alpha; Canvas.SetPos(Canvas.SizeX*0.5-CrosshairX, Canvas.SizeY*0.5-CrosshairY); Canvas.DrawTile(Texture'SniperArrows', CrosshairX*2.0, CrosshairY*2.0, 0.0, 0.0, Texture'SniperArrows'.USize, Texture'SniperArrows'.VSize); } Super.RenderOverlays(Canvas); } simulated function SetLineSpread(bool bNew, optional bool bForce) { if ( (bLineSpread != bNew) || bForce ) { bLineSpread = bNew; if ( bLineSpread ) ServerSetLineSpread(); else ServerClearLineSpread(); } } function ServerClearLineSpread() { bLineSpread = false; } function ServerSetLineSpread() { bLineSpread = true; } // //This determines Volley/Spread simulated event ClientStartFire(int Mode) { local int OtherMode; if ( EONSBioMultiFire(FireMode[Mode]) != None ) { SetLineSpread(false); } else { if ( Mode == 0 ) OtherMode = 1; else OtherMode = 0; if ( FireMode[OtherMode].bIsFiring || (FireMode[OtherMode].NextFireTime > Level.TimeSeconds) ) { //if ( FireMode[OtherMode].Load > 0 ) SetLineSpread(true); if ( bDebugging ) log("No RL reg fire because other firing "$FireMode[OtherMode].bIsFiring$" next fire "$(FireMode[OtherMode].NextFireTime - Level.TimeSeconds)); return; } } Super.ClientStartFire(Mode); } simulated function bool StartFire(int Mode) { local int OtherMode; if ( Mode == 0 ) OtherMode = 1; else OtherMode = 0; if ( FireMode[OtherMode].bIsFiring || (FireMode[OtherMode].NextFireTime > Level.TimeSeconds) ) return false; return Super.StartFire(Mode); } // defaultproperties { ItemName="EONS Bio-Rifle" FireModeClass(0)=EONSBioMultiFire FireModeClass(1)=EONSBioAltFire InventoryGroup=3 PickupClass=class'EONSBioRiflePickup' EffectOffset=(X=100.0,Y=32.0,Z=-20.0) AttachmentClass=class'BioAttachment' PutDownAnim=PutDown DisplayFOV=60 DrawScale=1.0 PlayerViewOffset=(X=7,Y=3,Z=0) SmallViewOffset=(X=19,Y=9,Z=-6) PlayerViewPivot=(Pitch=0,Roll=0,Yaw=0) SelectSound=Sound'WeaponSounds.FlakCannon.SwitchToFlakCannon' SelectForce="SwitchToFlakCannon" AIRating=+0.55 CurrentRating=+0.55 SeekCheckFreq=0.2 SeekRange=10240 LockRequiredTime=0.4 UnLockRequiredTime=0.6 LockAim=0.996 // 5 deg CustomCrosshairColor=(r=0,g=255,b=0,a=255) //Lock On Attr CrosshairColor=(R=0,G=255,B=0,A=255) CrosshairX=32 CrosshairY=32 LockOnSound=Sound'WeaponSounds.TAGRifle.TagTargetAquired' LockBrokenSound=Sound'WeaponSounds.TAGRifle.TagTargetAquired' CenteredOffsetY=-8.0 }
//=================== // EONSBioMultiFire //=================== class EONSBioMultiFire extends BioChargedFire; var() float TightSpread, LineSpread; event ModeDoFire() { if ( EONSBioRifle(Weapon).bLineSpread || ((Bot(Instigator.Controller) != None) && (FRand() < 0.65)) ) { Spread = LineSpread; SpreadStyle = SS_Line; } else { SpreadStyle = SS_Ring; Spread = TightSpread; } EONSBioRifle(Weapon).bLineSpread = false; Super(ProjectileFire).ModeDoFire(); NextFireTime = FMax(NextFireTime, Level.TimeSeconds + FireRate); } /* function DoFireEffect() { Load = GoopLoad; Super.DoFireEffect(); } */ function DoFireEffect() { local EONSBioGlob FiredGlobs[10]; local Vector StartProj, StartTrace, X,Y,Z; local Rotator Aim; local Vector HitLocation, HitNormal,FireLocation; local int p; local Actor Other; local float theta; if (SpreadStyle != SS_Line) { Log("DoFireEffect: SpreadStyle != Line"); Super.DoFireEffect(); return; } Instigator.MakeNoise(1.0); Weapon.GetViewAxes(X,Y,Z); StartTrace = Instigator.Location + Instigator.EyePosition(); StartProj = StartTrace + X*ProjSpawnOffset.X + Z*ProjSpawnOffset.Z; if ( !Weapon.WeaponCentered() ) StartProj = StartProj + Weapon.Hand * Y*ProjSpawnOffset.Y; // check if projectile would spawn through a wall and adjust start location accordingly Other = Weapon.Trace(HitLocation, HitNormal, StartProj, StartTrace, false); if (Other != None) { StartProj = HitLocation; } Aim = AdjustAim(StartProj, AimError); Log("DoFireEffect: SpreadStyle == Line"); for (p = 0; p < GoopLoad; p++) { theta = Spread*PI/32768*(p - float(GoopLoad-1)/2.0); X.X = Cos(theta); X.Y = Sin(theta); X.Z = 0.0; //SpawnProjectile(StartProj, Rotator(X >> Aim)); FiredGlobs[p] = EONSBioGlob(SpawnProjectile(FireLocation, Rotator(X >> Aim))); } } function projectile SpawnProjectile(Vector Start, Rotator Dir) { local EONSBioGlob Glob; GotoState(''); if (GoopLoad == 0) return None; if (Spread != LineSpread) //(!EONSBioRifle(Weapon).bLineSpread) { Glob = Weapon.Spawn(class'EONSBioGlob',,, Start, Dir); Log("Check 1"); if ( Glob != None ) { Glob.Damage *= DamageAtten; Glob.SetGoopLevel(GoopLoad); Glob.AdjustSpeed(); } } else { Log("Check 2"); if ( Glob != None ) { Glob.Damage *= DamageAtten; Glob.SetGoopLevel(1); Glob.AdjustSpeed(); } } GoopLoad = 0; if ( Weapon.AmmoAmount(ThisModeNum) <= 0 ) Weapon.OutOfAmmo(); return Glob; } defaultproperties { AmmoClass=class'EONSBioAmmo' AmmoPerFire=1 FireAnim=AltFire FireAnimRate=1.0 ProjectileClass=class'EONSBioGlob' FlashEmitterClass=class'XEffects.BioMuzFlash1st' SpreadStyle=SS_Line TightSpread=300 LineSpread=500 ProjSpawnOffset=(X=25,Y=6,Z=-6) FireSound=Sound'WeaponSounds.BioRifle.BioRifleFire' FireForce="RocketLauncherFire" // jdf FireRate=0.33 TweenTime=0.0 bFireOnRelease=true //MaxHoldTime=10.5 // FireRate*2 + 0.5 bSplashDamage=true bRecommendSplashDamage=true BotRefireRate=0.6 WarnTargetPct=+0.9 bSplashJump=true ShakeOffsetMag=(X=-20.0,Y=0.00,Z=0.00) ShakeOffsetRate=(X=-1000.0,Y=0.0,Z=0.0) ShakeOffsetTime=2 ShakeRotMag=(X=0.0,Y=0.0,Z=0.0) ShakeRotRate=(X=0.0,Y=0.0,Z=0.0) ShakeRotTime=2 }
//========================================================================= // EONSBioAltFire // Alternate Fire uses code modified from Mr. Pants' Excessive Overkill FlamethrowerEX written by Dan 'MadNad' Woodall // ======================================================================== class EONSBioAltFire extends ProjectileFire; var xEmitter BGas; function Projectile SpawnProjectile(Vector Start, Rotator Dir) { local Projectile P; if ( class'PlayerController'.Default.bSmallWeapons || Level.bClassicView ) ProjSpawnOffset.Z = -20; else ProjSpawnOffset.Z = default.ProjSpawnOffset.Z; if( ProjectileClass != None ) P = Spawn(ProjectileClass,,, Start, Dir); if( P == None ) return None; P.Damage *= DamageAtten; return P; } event ModeDoFire() { local Vector Dir; super.ModeDoFire(); Dir = Vector(Weapon.Rotation); if ( Weapon.AmmoAmount(0) > 1 && !Instigator.isA('Bot') ) EONSBioRifle(Weapon).SoundVolume=255; BGas=spawn(class'EONSBioGasIgnite',Owner,,,); Weapon.AttachToBone(BGas, 'tip'); BGas.mSpeedRange[0]+=Abs(VSize(Instigator.Velocity/VSize(Dir))); BGas.mSpeedRange[1]+=Abs(VSize(Instigator.Velocity/VSize(Dir))); if ( Weapon.ammoAmount(0) < 2 ) EONSBioRifle(Weapon).SoundVolume=0; } simulated function StopFiring() { EONSBioRifle(Weapon).SoundVolume=0; } defaultproperties { ProjSpawnOffset=(Y=40.000000) bPawnRapidFireAnim=True FireForce="minifireb" FireRate=0.06 AmmoClass=Class'EONSBioAmmo' AmmoPerFire=1 ShakeRotMag=(X=15.000000,Y=15.000000,Z=15.000000) ShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000) ShakeRotTime=2.000000 ShakeOffsetMag=(X=-5.000000) ShakeOffsetRate=(X=-500.000000) ShakeOffsetTime=2.000000 ProjectileClass=Class'EONSBioGasProj' BotRefireRate=0.990000 aimerror=120.000000 Spread=2000.000000 }