*Z  d NP> _giM㋃9j7> G G G G G G G G G Y Y [ [ | |       ! % & * + , ; A K U W X Y Z_ p < w @ w A w B w C y J y K y L y M y N y O S T U V W X Y Z NoneCore XWeaponsEngineAddPrecacheMaterialSystemVectorGfx Destroyed DrawTypeMeshFireModeClass StaticMeshBlowUp DrawScale ItemName UnrealGame FireRateBotRefireRateColorClientPlayForceFeedbackPutDown AmmoClassPostBeginPlay PickupClass PickupSoundTimerPickupMessageInventoryType PickupForce ShakeRotTime IconCoordsY2X2Y1X1IntBox IconMaterialAddPrecacheStaticMesh LightHueSpawnProjectile DeathStringShakeOffsetTime TakeDamageShakeOffsetMag FireSoundFemaleSuicideRotatorShakeOffsetRate MaleSuicidePlayerControllerLightBrightnessUsertip LightType WeaponClass PlayFiring IonCannon LightRadius AmmoPerFire AdjustAimMaxDesireability LightEffect FireForceXGameCollisionHeight BeginStateTickExplode EffectOffset AIRating StopFiringEffectIsRelevantSetBrightnessLightSaturationInitialAmountMaxAmmo BobDamping BestModeNone DisplayFOVAttachmentClassCurrentRatingNone SelectForce SelectSound PutDownAnimPlayerViewOffsetThirdPersonEffectsSkins BallLauncherFlashEmitterClass GetAIRatingbDetonatesGoopInventoryGroupProjSpawnOffset InitEffectsHitWallLanded HitEffect ProcessTouchMomentumTransferStopForceFeedback MinigunFire SoundRadius DoFireEffect UpdateRollProjectileClassDamage MyDamageType AmbientGlow FireEndAnim ShakeRotMag EyePositionAssaultGrenade ShakeRotRate AmbientSoundIsFirstPersonStaticPrecache SoundVolume GetViewAxesBioGlob SniperFirePlayerViewPivot ShakeViewSpeedRocketLauncherbSplashDamageWarnTargetPct DamageTypeHasAmmoUpdatePrecacheMaterials LifeSpan SetLinkToGetHitEffects SpawnEffects EndStateSuggestAttackStylebHeavy LightPeriod AmmoAmount LinkFire PainterFirebRecommendSplashDamage mColorRange StartBerserk StopBerserk DamageRadiusAltFireIdle ModeTick Bone_FlashCollisionRadiusBringUpRedeemerProjectileIsLocallyControlledGetEffectStartSetTargetStateStyleSuggestDefenseStylePostNetBeginPlayMinigunRedeemerWarheadPhysics FireAnim CheckMark AllowFire StartFire RemoteRolebDynamicLight ViewPlayer ForceRadius CheckReflectbNetTemporary ForceTypeFlashMuzzleFlash DamageMinDrawMuzzleFlashAnimEnd WeaponLight DamageMaxPickupRenderOverlaysUseAmmo SelectAnimbFireOnReleasePawnTriggerExplosionDecalSetZoomBlendColorEndZoomClientPlaySoundBeginShockProjectileEndMonitoring ForceScaleFlashPlayAmbientSound FireAnimRateFlying bCanThrowPainterBeamEffect WindDown FireLoopAnim PlayLoad mSizeRangeTranslauncher ReplaceWithbWaitForReleasebModeExclusiveBioChargedFireSpawnBeamEffect TransFire PreBeginPlay ReturnToIdle TraceRangeGetTipLocation LinkScaleClientStopFireClientStartFire RocketProjbReplicateInstigator OutOfAmmo MaxSpeed IsFiring StartFiring RotationRatePlayStartHoldbFixedRotationDir SpreadStyleSpreadbPawnRapidFireAnim PlayFireEndTouch SetGoopLevelRelinquishController bProjTargetmParticleTypemMaxParticles mRegenDistPhysicsVolumeChangeTransientSoundVolume mAttenKa BeamSoundsIsIdle ModeDoFirebUnlitBotFireClientSwitchToBestWeapon MaxRange GetFireStart MomentumFire ImpactSoundIncrementFlashCountGibPerterbationDamageOverlayTimeDamageOverlayMaterialDyingUpdatePrecacheStaticMeshesDoTrace Cancelled aimerrorxPawnAimAtLinkGun ConsumeAmmobTossed DoAutoSwitch PlayIdleDestroyTrailsUpdateRollTimeTossZClientWeaponThrownbSwitchToZeroCollisionAquired GetHitEffect NoAmmoSoundWindUpLimits FireHackFocusOnLeader LinkAdjustRangedAttackTime ChargeBar SniperRiflemMuzFlashClass TracePartbShowChargingBar IdleAnimRate ServerBlowUp TweenTime RemoveFear SplashGlobsDestroyEffectsMergeWithGlobStartMuzzleSmoke Projectile PlayPreFireDesiredRotation SpawnShellsbBounceborderXTransientSoundRadius StopZoom ToggleZoom mAttenuateborderYfocusX FireSequenceBotTranslocate ModeHoldFirefocusY innerArrowsXShieldAltFire innerArrowsY IsMonitoring ArrowColorRocketMultiFire FocusColor IsLinkable ChargeColor AdjustTossTransTrailClassRechargeOriginNone RechargeSizeGrenade RemoveLinkProficientWithWeapon DisruptedAddLinkIncrementKillsCalcDrawOffsetKDamageImpulseHOLD BallTargetProjectileFire BoundErrorbAlwaysSevers AnimateLoadTakeHit UpdateHitZoomSuperShockRifleInitFor bRapidFireSwitchToBestWeaponNoneHitDoCombobAltRapidFire GetHitInfo ModifyPawn Bone_Barrel Bone BarrelsbHiddenStopped TickEffects CanComboShouldTranslocatorHopFindInventoryTypeNoTargetColor TargetColor StartleBotstestYtestXSetComboTarget PrePivotClientTakeHitshell bone flash bone flashAAllowTranslocationByMinigunAttachment MutArena LoadNext Movement bArmorStops Bone_Flash02 CollisionbLocationalHitGetViewRotationtip2None SpawnEffectbCauseConvulsions bSuperWeaponbKUseOwnDeathVel FireLoopheadIsHumanControlled bOwnerNoSee Initialize KDeathVel KDeathUpKickShockBeamFire LightColorServerSetTightSpread UpdateBarrel RotateBarrel ReduceAmmoplunge CanLockOnTo mWaveLockEndmBendStrength mWaveShiftmWaveAmplitudemWaveFrequency Lighting mSpinRangeSniperAttachmentTransbeaconTeleporter TransRecall bNetNotify ViewCameraKarmaPossessForce NetPriorityWaitEncroachingOn MessageClassTransFlareClass ProjPerFireSmokeEmitterClass MarkSound bSplashJumpBeamEffectClass GroupName PreFireTime StopRollingFireLoopAnimRateSetTranslocationTargetMonitoringThrow FiringForce WeaponTick StopFireTextureReadyDropClientSetViewTargetDesiredBrightness WindUpTime Description FiringSoundBarrelRotationsPerSec SetTargetingSetWeaponStayGetRespawnTimeRespawnEffect RespawnTime KilledBy ShootHoopFirstPersonViewDoReflectEffectGetTracerStart WaitForComboload CoilClassMonitorSuperExplosion bWeaponStay UpdateTracerCharge TickTracer AquiredSound CanAttackMuzFlashClass BrightnessRecommendRangedAttackPaintDetachFromPawnRecommendWeaponGiveToDrawWeaponInfoBotTranslocation TranslocateTransMaterialsDemoReplacementChargingSound bNotInDemo bLeadTarget FriendlyName bSnipingCheckReplacement OnGroundSetPassTarget bTryHeadShot Shriveling MinDamage MaxDamageAddAmmo MaxForceSelfForceScale HealRatePassTargetLostForceBouncesSelfDamageScale MinForceAutoFireTestFreqFullyChargedTimePassTargetLockedForceChargingForceTransFailedSound bMeleeWeapon MinHoldTime ExplodeTimerbMatchWeapons ShieldRangeNoneNone ExplodeSound GoopVolume ChargeupTimeAmmoRegenTimePassTargetLost AttachLocDampenFactorParallel GetAmmoCountPassTargetLocked PassAmbient AttachRotHitEffectClassTAGAquiredForce FlockRadiusKillerMessage IsOnTeam FlakMonkeyFlockStiffness SetAITargetFlockMaxForceFlockCurlForce TAGMarkForce TAGFireForce ComboSound PTS_Aiming PTS_Marked PTS_Aquired GearRatio ReselectPTS_Cancelled ComboDamage ComboRadiusComboMomentumTransfer BreathTimer GiveAmmo GoopLevel GroupOffsetComboAmmoCost MaxGoopLevelBlendServerStopFire ReadyToFirePlayerRocketing LooseSpreadSetOverlayMaterial DripTimeAdjustPlayerDamageHitEffectDefaultHitEffectRockPlayTeleportEffectFellOutOfWorld NextWeapon TightSpread PrevWeaponHitEffectDirt bMergeGlobsmShellCaseEmitterClassHitEffectMetalHitEffectWoodTransFireSoundHitEffectPlantHitEffectFlesh HitEffectIceHitEffectSnowRecallFireSoundBotTouchDetonationDelay RestTimeNone SpecialEventDrawTargetingHitEffectWaterLinkedFireForceGloblingSpeedRoundsPerRotationHitEffectGlass WindingSound BaseDamagebDirectHitWallbHideRegularHUD UnPossessNone bSpecialHUD PlayDying PreFireAnim OldHitCountLinkedFireSoundReceiveLocalizedMessagebNoTeamBeacon GameEnded ReloadSound WindingForceMaxDistCheckFutureSightNone MaxHoldTimeNoneClientSetWeapon AirSpeedHitEmitterClassSecHitEmitterClassNumArcsSecDamageMultNoneIonEffectClass SecTraceDistHeadShotDamageMultPostNetReceive AccelRateNone bReflective EncroachedByArenaWeaponClassNamePaintDurationDamageTypeHeadShot FireWeaponAt DamageAttenBaseEyeHeight EyeHeight HoldSoundmBlendNetUpdateFrequency SameTeamAs PawnDied BaseChangeServerPlayFiringDisruptionThresholdbRotateToDesiredLandMovementStateShieldbAlwaysFaceCameraNoneReachedDestinationbBlockZeroExtentTracesNoneTransAttachment TransAmmoSuperShockRiflePickup bBlockActors mLifeRangeSuperShockBeamFiremDrumRotationsPerSecSuperShockAmmo SniperZoombCollideActorsSeekCheckFreq SeekRange MaxGoopLoad GoopUpRate SoundPitchLockRequiredTimeUnLockRequiredTimeLockAimCrossHairColor CrosshairX CrosshairY SniperAmmoShockProjFireDrawHUD bCanTeleport UnPossessedShockBeamEffectTransFireForce IsPlayerPawnShockBeamCoilBlueShockAttachment ShieldFireShieldEffect3rdRedShieldEffect3rdBLUEShieldEffect3rd ShieldEffectRecallFireForcebGameRelevantShieldAttachment GibModifier ShieldAmmomScaleSeekingRocketProj bSkeletize bSpecial bAlwaysGibs RocketFireRocketAttachment RocketAmmo bInstantHitRedeemerGuidedFire RedeemerFireRedeemerAttachment RedeemerAmmo Redeemer RedBeacon PainterZoombInitAimError Headhunter CombowhoreLinkFlexibilityPainterAttachmentPainterMutNoSuperWeaponMakeLinkForceAimConeShieldHitSound MinigunAmmoShieldHitForceMinigunAltFireGetSquadLedByMakeLinkSound WrapPostIncrLinkBeamEffectLinkBeamChildLinkAttachment LinkAmmo LinkAltFireLimitationVolume FaceRotationHitScanBlockingVolume GrenadeAmmoInCurrentCombo FlakFire ImpactJump DrawScale3DCanComboMovingDoJump EnemyVisibleFlakAttachment FlakAmmoAlternateTranslocDest IsRetreating IsStrafing MaxCamDist FlakAltFireUpdateRocketAcceleration SetHolderRelativeRotationRelativeLocation ShieldGunDamTypeTeleFragDamTypeSuperShockBeamDamTypeSniperShotDamTypeSniperHeadShotDamTypeShockBeamDamTypeShockBallDamTypeShieldImpactDamTypeRocketHomingDamTypeRedeemerDamTypeMinigunBulletDamTypeMinigunAltDamTypeLinkShaftDamTypeLinkPlasmaDamTypeIonBlastDamTypeBioGlobDamTypeAssaultGrenadeDamTypeAssaultBulletSuperShockBeamEffectBlueSuperShockBeam TransBeacon XEffects BlueBeacon AmmoChargeBioFiremScaleMultiplierBioAttachmentBioAmmo mSpeedMin BallShootBallAttachment BallAmmoUTWeaponPickup mSpeedMax Bone gear InstantFire AssaultFireAssaultAttachment UTAmmoPickup bone_shellmHoldSpeedMinmHoldSpeedMaxSuperShockRifle ShockAmmo bone_feedDamTypeFlakChunkDamTypeFlakShellDamTypeShockComboDamTypeRocketRepAmmoDied DownwardBias AimedOffsetThrowNoneNonemHoldSpeedGainPerSec mWaitTimeGetTeamLinkBreakDelaybNetInitialRotation BaseOffsetAmmoChargeMaxChargedDoTranslocateOutbUpdateSimulatedPosition Bone_DrumShrivelSlideDrip gibbedBy FlakChunk FlakShellbReplicateMovementBioAmmoPickupLinkProjectilePainterPickupRedeemerPickupFlakAmmoPickupLinkAmmoPickupMinigunAmmoPickupRocketAmmoPickupShockAmmoPickupSniperAmmoPickupAssaultAmmoPickupAssaultRiflePickupFlakCannonPickupLinkGunPickupMinigunPickupRocketLauncherPickupShieldGunPickupShockRiflePickupSniperRiflePickupBioRiflePickup mTracerClassbWorldGeometry DampenFactorAmmoChargeRateSetLinkStatusbStasis BioRifle bForceSwitch ShockRifleRecallbOnlyOwnerSee FlakCannon AssaultRifleNoneTransBeaconSparksTransFlareBlueTransFlareRedNone TransTrailTransTrailBlueTransTrailRed xbiosplat xbiosplat2 SaDScorcht XEffectMat link_muz_redLinkMuzProjGreenFBlink_spark_greenlink_muz_greenIonNoneshock_flare_ashock_sparkle Shock_ring_a shock_coreShockgoopshock_core_lowNone painter_beamLinkProjYellowFB Ion_beam Shock_Elec_aNone purple_line Shield3rdFBShieldRip3rdFB ion_greyGoopFBlink_beam_greenlink_muz_yellowlink_muz_blueLinkBeamGreenFBLinkBeamYellowFBLinkBeamRedFBLinkBeamBlueFBlink_muzmesh_greenLinkMuzProjYellowFB shock_flashshock_gradient_b RedShell BlueShellEpicParticles SmokepuffWhiteStreak01awBeams SoftFlare BurnFlare1SmokeFlares Smokepuff2IonBurnIonWave IonBurn2NoneNone FlakTrailTexpcl_BlueSpark WeaponSounds LightningGun P1GrenFloor1 PGrenFloor1Misc BExplosion3BaseImpactAndExplosionsLightningGunChargeUp BLinkedFireBLinkGunBeam3BLinkGunBeam2BLinkGunBeam4 TAGFireB TAGFireATAGTargetAquiredShieldReflectionSwitchToShockRifleShockRifleExplosionSwitchToRocketLauncherSwitchToMiniGunSwitchToLinkGunSwitchToLightningGunSwitchToFlakCannonSwitchToAssaultRifleShockRifleProjectileRocketLauncherProjectileLinkGunProjectileLinkActivatedShockComboFireRocketLauncherPlunger miniemptyLightningZoomOutLightningZoomInTranslocatorModuleRegenerationTranslocatorFireP1ShieldGunFirePShieldGunFireBLightningGunFire BShield1BFlakCannonProjectileBaseProjectileSoundsPulseRifleFire PulseRifle SeekLostLockOnBioRiflePowerUp BioRifleGoo1 BLockOn1 BSeekLost1 BReload9 BaseGunTechBaseFiringSounds minialtfirebNoneFlakCannonAltFire BioRifleFireRocketLauncherFireShockRifleAltFireShockRifleFireRocketLauncherLoadFlakCannonFireAssaultRifleFireNone P1Reload5 PReload5SmallRedeemerExplosionNoneShockProjMuzFlash3rdShockProjMuzFlashNoneShockMuzFlashB3rd TranslocatorShockMuzFlashB BioRifleGoo2 BExplosion1BLinkGunBeam1ShockMuzFlash3rdIonCannonBlast TAGRifleinstagib_rifleshotredeemer_explosionsoundtranslocator_changeshieldgun_chargeshieldgun_changeredeemer_shootredeemer_flightredeemer_changebiorifle_chargeballgun_launchballgun_changefexptExplosionFlashTexLightningBoltTLightningChargeT DesiredRegenShockMuzFlashLinkslsShellCasingTexNoneShockImpactScorch RocketFlareShockImpactRingBShockImpactRinghlhnFlareShockImpactFlareBEmitterTextures MultiFrame rockchunks02WeaponStaticMesh WeaponSkinsShockImpactFlareNoneShockExplosionCoreBShockExplosionCoreShockExplosionShockComboFlash ShockComboShockBeamMuzFlashShockBeamCoilBShockBeamCoilShockAltDecal ShieldSparks ShieldCharge ShellSpewerRocketTrailSmokeRocketSmokeRingRocketMuzFlash3rdRocketMuzFlash1st RocketMark RocketCoronaRedeemerTrailRedeemerExplosionPlayerSpawnEffect pclredsmoke FlakChunkTexNoneRocketShellTex GrenadeMeshRedeemerMissileNone FlakTex1SniperScreen2None FlakTex0SniperScreen1NoneNoneSniperScreen1Pan XWeapons_rc GoopMeshpclImpactSmokePainterBeamSpotNoneMinigunMuzzleSmoke ShockBeamTexNoneIcons SniperBorder SniperFocus SniperArrows PickupSoundsMinigunAltMuzzleSmokeAimedAttachmentSpecialKillMessage xBombFlag LinkSparksxPlayerxPlayerReplicationInfoxWeaponAttachment xWeaponBasexp flakcount combocount headcount StartEffect bBerserk LinkScorch PrevLocationxPRILinkProtSphereLinkProjSparksYellowLinkProjSparksNoneLinkMuzFlashProj3rd mHitNormal mHitActorLinkMuzFlashProj1stLinkMuzFlashBeam3rdLinkMuzFlashBeam1stLinkBoltScorch ThrowSpeed InitialDirLightningCharge3rdLightningCharge WeaponTypeNone IonEffectprojIonCore HitSmoke HitFlameBig HitFlameGrenadeSmokeTrail GoopSparks GoopSmoke ForceRingA ForceRingFlashExplosion FlakTrailFlakShellTrailFlakMuzFlash3rdFlakMuzFlash1stNoneFlakExplosionxHeavyWallHitEffect ExploWallHit WallSparksExplosionCrap DirtImpact ComboDecalChildLightningBoltBioMuzFlash1st BioDecalNoneAssaultMuzFlash3rdMinigunMuzFlash1stAssaultMuzFlash1stNoneNoneLinkHitPlayerTransRedWeaponShaders flak_flashZoomFXZoomFBPlayerShaders LightningHit fulloverlay TransCamFBScreenNoiseFB PlayerTransWeaponEnvShaderNone bio_flashshock_muzflash_1st scanline XGameShaders bInitialized enemyDir enemyDist GoalScriptNextSquadMember AcquireTime TranslocFreq ImpactTargetRealTranslocationTargetTranslocationTargetbTranslocatorHop bPlannedShotbHasImpactHammerbHasTranslocatorTranslocZOffset PassTargetBombVal SquadMembers SquadLeaderSquadZDiffSpawnProtectionTime FlackMonkeyNoneWeaponDamageTypeTranslocatorBeaconPickupMessagePlus HoldSpot JumpSpotUnrealTeamInfo DeathMatch GameObjectGameObjective UnrealPlayerTeamAISquadAILFTexPropSphereSparksAim MakeColorSetPosSizeYSizeXNoneClipX WhiteTextureBeamTrail HitCountNoneNone mSpeedRange mSpawnVecB mSpawnVecAmPosDev mRegenRangemStartParticles mRegenPausemRegeneyeDir forceMagCorona InAimError JumpSpotTag myJumpSpot FlashEmitterArenaWeaponClassArenaWeaponPickupClassNameArenaAmmoPickupClassName SmokeTrail YawAccel PitchAccelbStaticScreen bFireForceMyTeam bNowWaitingPitchThreshold bIsFiringOldSpawnHitCount NextFireTime mMuzFlash3rdmMuzFlash3rdAlt MuzFlash3rd MuzFlash HoldTime ThisModeNummTracer RandSpin WhiteColormLastTracerTimeNoneNoneNoneNone mCurrentRoll mRollIncmRollUpdateTime ShootLocmShellCaseEmittermShellEmitterOffsetDrain AmmoDrainbUpdatediff RefNormalWPNonehitDistNone bJustSpawnednewmode ForceRing3rd bFinished oldRatingbLimitTransDiscbLimitProjectilesLimitEffectClass RecommendedbLeaderFiringNoneNone ScaleFactor launchedBallCurAmmoPrimaryMaxAmmoPrimary ClientStateBotMode IdleAnim FireMode HealAccumSwitchTestTime AITargetIndoorAmbience machinery36 AmmoToAdd passTargmodeNumLinkingNone LeaderPawn StartTrace OtherWeaponsanity CurrentRoll RollSpeedShellCaseEmitterCurrentWeaponCurrentChoice CurrentModeThirdPersonActor GearOffsetSkilldt amountPerSecfogbStartLocDiffhandModeASoundStepSetViewTarget DefaultFOV DesiredFOV bBehindViewratingVel2DInLatentExecution BestDistLastFOVzoomed EndEffect MarkLocation FirstCannonbestAimclr tileScaleX tileScaleYbXbYfXfYbarOrgXbarOrgY barSizeX barSizeY Adrenaline NUM_BARRELSBARREL_ROTATION_RATEBarrelRotationFinalRotationbRotateBarrel SeekTarget LockTime UnLockTimeSeekCheckTime bLockedOn bBreakLock bTightSpread RouteGoal RouteCache LastSeenTimeTargetEnemyFocus MoveTarget MoveTimernextControllerRocketSeekingRocket bAltFirebFirefullbPreparingMove VictemHealth HitEffectsIgnored bWaterVolumeGravityReflect mHitLocationSpawnHitCountHitDirFaceDir ComboTargetbRegisterTargetbWaitForCombo ComboStartDestnewRot FearCostbDamageTriggered FiringModechargeEmittertXtY PitchChangeNone YawChange bUpdatingWallNone HitActor OldWeaponLinkTTarget TTargetLocFDamageScaling bCanHitOwner bHitWater bDamagedbNoAI DisruptionHealth Disruptor HeadVolumePendingWeapon GroundSpeed SpawnTimeAnchor FlashCountAImyHUD DrawColorVictimNoneControllerListGameNetMode bDropDetail DetailModeSurfaceNormalbCheckedSurfaceRand3bDripbNoFX bOnMover TimeSecondsFearDistanceFogColorAdditionalGoopLevelCoreGoopLevelGlob bDistanceFog DotProduct NewGoopLevel ExtraSplashL NumGloblingsNewGlobVNormHasFlag TeamIndexSize NewChunkbSuperRelevantDefaultWeaponNameDefaultWeaponLastSparkTime bTimerSetTeamRefDirbRing bWaterStartNumExtraRockets FlockIndexFlock ViewTargetKillerInvPCbCurl ForceDirCurlDirSeekingVelMagResultMN bTeamGameNoneNone instigatedBy tempStartLocOldPawnbDonePSpotframedist HurtRadius bDoReflect ReflectNumEnd LastFireTime ClickTime MaxRollSpeedHitLocDir FireTimeStartPlayOwnedSoundGun HitLocation KillType HitNormalEventInstigator DeltaTimeOtherNoneGetAnimParamsSetBoneRotation Attachment AttachToBoneAnimBlendParamsAnimNoneRate NewRotationSetDrawScale3D SetDrawScalemainArcHitTargetarcsRemaining hitEmittertmpHitEmitClasstmpTraceRangearcEnd mainArcHit eKillZType bNetOwner StartProj SpawnCounttheta mNumGrenades bNetInitial mNextRollbCollideWorld mRollPerSecmGun mCurrentSlotmNextEmptySlot SurfaceType Acceleration InstigatorRegionLastRenderTimeZone PointRegionmHoldClampMax bDeleteMe pawnSpeedincBase oldcountOwner ThrowDir WeaponPickupfell GoopLoad LocalMessageEffectsDynamicLoadObjectWarhead Possessor NewStatei FireLocationQ FiredRocketstSNoneNonebBeaconDeployedNoneClockwiseFrom_IntIntV ReturnValuebestPbestWttoPawncosdotcurwtcurdistcurdot VelocityUpTime LockedPawnLinkBreakTime Rotation LocationRGbDoHitbFeedbackDeathScalebLinkFeedbackPlaying bStartFireDesiredAimErrorCurrentAimError EndTrace bShouldStopAdjustedDamageLBZYXStarterCBLG bValidMark bInitialMarkbAlreadyMarked MarkTimeA ScriptTextNone xEmitterWeapon WeaponFire bMarkStarted LevelInfobEngageCannon GameInfo Decoration RampTime ZoneInfobHitHUDPlayerReplicationInfoAmmo Inventory Ammunition AIController ControllerPhysicsVolumeChargingEmitterVolumeBlockingVolume bAutoRelease TeamInfobStartedChargingForce EnemyAimRegen ChargeScaleInventoryAttachmentbGibMeWeaponAttachmentsuccessNavigationPointbFailedTransloc EffectNum AvoidMarker OldLinks LinkColor OldLinkColor LinkedPawnbHitSomethingPrevLocPrevRot scorchtime ProtSphere MAX_CHILDREN NumChildrenChildMutatorRotDiff WiggleMeBeamDirEPainterTargetingStateCanvasChannelLevelShader TargetState MarkForce AmbientForce FinalBlendMover SkeletalMeshHitRot EffectLocCoil TerrainInfo MaterialBitmapMaterial VertMesh KeypointActorCountVSizeUSizeYawRollPitch SoundGroupProceduralSoundSoundRoleClassPackageConstBeamDirectionDamageLocationNoneNoneAimer TestMarkRot TextBufferObjectIonBeamEffectEnum FunctionStateStructEditor StrPropertyStructPropertyArrayPropertyClassProperty NamePropertyObjectPropertyFloatProperty BoolProperty IntPropertyWeapons ByteProperty BioRifle_1st Flak_1stNoneRocketLauncher_3rdBallLauncher_1stBallLauncher_3rdShieldGun_1st Redeemer_1stNoneNoneShockRifle_1stShieldGun_3rdRocketLauncher_1st Painter_3rd Minigun_1st BioRifle_3rdNoneAssaultRifle_1stNone Minigun_3rd LinkGun_1st Flak_3rd Painter_1st Sniper_1st Redeemer_3rd Sniper_3rdshock_Energy_green_fadedNoneNone InitialStateNoneNonebResultNoneNoneNoneColorModifierSmokeAlphab_tRedSuperShockBeamBlueSuperShockTexInstagibEffectsNoneNoneNoneNoneNoneNone HudColorWeaponCenteredAttemptTranslocationSynchronizeWeaponCenteredEffectStart bCausesBloodRecommendLongRangedAttack FocalPointTeamPlayerReplicationInfo ClientWeaponUnrealMPGameInfo OtherModenewdestNoneNone DropFromStartLocationNonebDemoRecordingNoneSpawnImpactEffectsCheckOutOfAmmoMuzFlash3ClassReallyConsumeAmmobNoVoluntarySwitchbAmountNeededIsMax AmountNeeded AssaultAmmoNonebOnlyDirtyReplicationNoneServerPlayLoadingNoneNoneNoneNoneNonebRepClientDemoNoneNoneZoomSuperShockBeamDamageZoomSuperShockBeamFireNoneNonebPrevWeaponSwitchNoneNoneNoneNoneNoneSmallViewOffsetCenteredOffsetY CenteredRoll CenteredYawbDelayedDamageTranslocSucceeded xMutantGameDelayedHurtRadiusbSmallWeapons AutoHitPawn AutoHitTimeAimDir OldLocationInstigatorControllerNoneAllowMultiHitAimUpbAllowMultiHit bSpectatedNoneNoneNone blockOnNetNewLightningBoltbSkipActorPropertyReplicationNoneLightningGunImpactSmallEffectOffsetNoneNoneNoneNoneMipZeroUBitsVBitsVClampUClampPalette NewFlakSkin Palette8None FlashFogNoneNoneNoneNoneCustomCrosshairCustomCrossHairColorHighDetailOverlayStartSuperBerserkStandUpNewDrawWeaponInfoHandlePickupQueryVehicleMomentumScalingFluidSurfaceShootStrengthMod WeaponEntry OldPickupOldPlayerViewOffsetOldCenteredOffsetYMakeMuzzleFlashOldSmallViewOffsetOldPlayerViewPivotOldMeshbThrowRagdollCustomCrossHairScalebStaticbRagdollBulletSetBeamRotation AttachToPawnSetBeamLocation TeamLinkRenderDualOverlayAnnouncePickup ValidTouchOldCenteredRollOldCenteredYaw AdjustSpeed DrainChargesNonelfarm WeaponLocker LockerPickupbSimulateGravity TriggerEventPutDownAnimRateGetOffhandBoneForGetDamageTypeReadyToPickup EffectColor SetRespawnbNoInstagibReplaceDestroyableObjectiveVehicle FillPlayInfobLeaveBodyEffectGetDescriptionText LockerString LockerWeapon DetourWeightComboDamageType SpawnCopyPriorityObjectiveLoadedArenaDisplayTextSelectAnimRateReset UpdateHUD bFlamingGetHumanReadableNameBotDesireabilityPickupFunction PickupQueryGetWeaponBoneFor LockerOffsetArenaDescTextItemGameReplicationInfoNewWeapons2004NewShockRifle_3rd FatLinkGunNewAssaultRifle_3rdNewLinkGun_3rdCoords PropNameNewWeaponSoundsNewGrenadeShootNewMinigunFireNewclickgrenade BioGoopLoop ClassNameNewExplosionALastPickupTime NewScale3D bFireLeft bDualModeShadersXAxisWeaponRotationTwinGunPurpleShockFinal BlueColorWeaponBerserkExtra AimAlpha WeaponDirCopyNewWeaponStaticWeaponLockerM HUDContentMaxWait RedColorNoneHWeaponOptionsbDrawingFirstPerson Handedness LinkHealMultSetRelativeRotationNoneNewExplosionBNoneYPos xBombingRun bDraineddesireGetBoneCoordsC_T_Electricity_SGGRILastWeaponPickupTimeEventAttachmentBoneDeployableTex PathWeightRedShockFinalmOldHitLocation PreDrainAmmoNone WeaponRecord RealHand AlreadyHasRecsNoneSetBoneDirectionSetRelativeLocation NewWeapsShockRifleTex0 ExtraAmmoWeaponSpecMap2Generic CombinerNone bHuntPlayer CacheManager bDualGunInfo PlayInfoLinkedVehicleoffsetbUseOldWeaponMeshConstantColor OffhandActor FlagTarget RenderedHand bRealHiddenDualPickupTimebBallDrainsTransloc BoneNameOriginDamageCapacity ShockControlHolderbCanPickupInventoryHealObjectiveBlueShockFinal bWasDualModeNoneUT2004Weapons VictimHealthNoneNoneMinMaxRange RangeVectorGetLocalPlayerController SetLinkColor Priority GetFireModeCustomCrossHairTextureName SetTimer GetTeamNumStartSizeRangeInitialParticlesPerSecond UniformSizeStartLocationOffset MaxParticlesSpinParticlesAutomaticInitialSpawningStartSpinRange CullDistanceTriggerDisabledUpdateLinkColorVehicleDamageScaling ImpactSounds RelativeTimeBeyondViewDistancePrecacheHUDTexturesIsShootingObjectiveSetTightSpreadGetLinkVehicle DisabledPlayGlobalSoundClientDelayedAnnouncementNamed%SetDelayedDamageInstigatorController bBulletHitMaxEffectDistance HasCustomerCheckMaxEffectDistance ColorScale AmmoMaxed BeginPlay NeedAmmo AddCustomerOpacity HealDamageSpawnLockerWeaponPlayRewardAnnouncementClientTriggerShouldKeepShielding LinkedTo MinReloadPctUseColorScale PutDownTime bNoDeleteLinkedConsumeAmmoServerClearTightSpreadSecondsBeforeInactive myHasAmmo GetPlayerAimAdjustLinkDamageDelayDeniedLifetimeRangeSpawnParticleSpinsPerSecondRange EmittersBeacon BringUpTimeMinigunSoundVolumeTurnOffMaxAltitudePanRatemTracerIntervalPrimarySuperMaxOutAmmotweak ShouldCrouch AmmoStatusVelocityToAltitudePanRateBankingToScopeRotationRatioBankingResetRatebDeferRenderingYawToBankingRatioGetGameObjectbAlwaysRelevantAltitudeFinalBlend ReloadForce LinkVolumeOuterEdgeShaderbUseCollisionStaticMeshFillToInitialAmmo LC_GreenShieldSoundVolumeOuterScopeShaderSuicideLC_GoldInnerScopeShader CallForBall MakeYellowFX_WeaponLockerLC_RedCheckForHeadShotBankingDampingExplosionEffectClassbCanUsemTracerPullback mTracerSpeedChargingSoundVolumemTracerIntervalSecondary NeedWeapon CheatWalkPlayerChangedTeamCanHealNotifyLocalPlayerDead CheatGhostCheckSuperBerserk HasUDamage AmmoChargeF TranspickupHideViewBeaconVolumeMaxLoadDeathOverlayMaterialBumpLC_BlueFadeOutTranslocScaleFormat CheatFlyAllowRepeatPickupKill PawnToucher SetWalking MaxBanking IsHeadShot NewColorbCanFlylink_muzmesh_yellowNewWeaponPickupsSpriteEmitter60SpriteEmitter61 MeshEmitter3 MeshEmitter4 MeshEmitter5 MeshEmitter6 MeshEmitter7LinkGunRedShaderlink_spark_yellow NextTimerPopshock_muzflash_3rdDrivenVehicleNEWTranslauncher_3rdNewTranslauncher_1st ShockLaser RulesGroup OldMuzFlashAW-2004Explosions SetBoneScaleWbHighBeaconTrajectoryDiffusebClientTrigger bDamageableDiffZ ViewportPowerPulseShaderYellowTranslocatorCENTERPTEnergy MeshEmitter2bNew AS_FX_TX LargeFlamesfire3 spawnVelAssaultPickupSMCP FlickerFlareCrushedShockHeatDecal GoldGlowmTracerIntervalLinkGunShader Modifier HealthMaxNewLinkSelect ShockTex0 offsetadj PlasmaShaft bAimingHelpNextTranslocTimePowerPulseShaderBlue bKeyVehicleCrouchBioGoo ELinkColor AmmoPickupsStartVelocityRangeDist2D LinkPowerRed TexRotator bRealAimHelpVariableTexPannerJumpPad Impact4Snd BRInnerGoo bTimerLoop TracerShotBRInnerBubbles bShieldSelfPanRateScopeTexRotatorlink_beam_blueNewRedeemerTrail TempRotationEmitterNewMinigunMFlash bNetDirtyPowerPulseShaderRedO MeshEmitter1ShockBallEffectParticleEmitter MeshEmitter0 CustomersClipYbForceAltitudeTexPannerLinkGunYellowShaderBankingVelocityBankingbIsHealingObjectiveSentLinkVolume Impact6Snd MeshEmitterSquadObjectivebAllowVehiclesShockPickupSM Impact7Snd Laser_FlareDistanceFogEnd UnrealPawn RDM_Altitude NewTracerRDM_AltitudeFinalRDM_OuterEdgeShaderRDM_OuterScopeShaderNEWTranslocatorPUCKAW-2004Particles2K4HudWeaponFadeEffectbNewIsWalkingNextTouchTime SpawnDirCTFBasemTracerMinDistance NewbHidden FlakGlowNEWTranslocatorBLUElink_beam_yellowRedeemerInnerScope NewLinkTrail lasermistNetUpdateTimeEclipseCircle LinkPickupSMLinkGunBlueShaderTeamNum bVehicleHitPart_explode2sLinkPowerBlue bTeamSetRedeemerOuterEdge TranslocRotPlayerOldTimematShockHitShaderImpact2IsSoftwareRenderingNewTranslocScaleWeaponsLocker_01bHopRDM_InnerScopeShaderlink_beam_redbSentinelProtected ShockRipplePowerPulseShaderGlow SpawnLocbReplicateLinkColor LinkTex0NEWTranslocatorTEXImpact3RedeemerOuterScopeSpriteEmitter IntervalTimerIntervalEffect ShockBallSpawnLocationNewTransLaunBoltFB HeadShotPawnTop bOverrideImpact1TimeNewTransGlassFB bDebuggingNonePlaneColorModulateSavedCMNoneNoneNoneNone SplashEffectCheckForSplashMinSelfDamagePart_explode2 BulletSplash RDMR_MissileNoneNoneNoneNoneNoneNoneExtraBlueBeam ExtraRedBeamENoneNoneNoneNoneNoneNoneNone]#sI E9:9:$G6zVqYԄh*`*` u*`*` u*`*` u*`\ tM*`*`hhzVGB3},e,e,eh,ehV,ehV,eVV*`h E}Lh|\fF|\fFؚ||\fF||ʁ)||\fFؚ|hKi||||\fF,e|\fF||h}L*`}L}L}L|||hh*`h|\fF|\fF,e|\fF,eh|\fFh}L*`}L}L}L||h|ʁ)*`|}L||\fF| E| E Eh E*`|hh|\fF|\fF,e|\fFhh}L|}L|\fF,ehhqYԄh|\fF,ehhhhh*`h|hhzVGBhzVGB'yhh,e\fF||||h|hqYԎ|hh|||*`h uhhhhhKi\ tM\ tM*`4 r Va$o:An@vSGwT h$@X$ AA$ Al]mY%t!`N-9:9:$G6@IۉխqYuthh uҽҽҽҽҽҽҽҽҽҽҽҽ3}uthҽҽҽҽҽҽҽ3}3}hhzVGBhzVGBJh,eh uh,eh uh uh uututhh uh uh uuth uutut3}Zs3}WSF[X! hh|3}h,ehqYԄhh,ehh|3}hh|h|3}h|||||||||\fFutut||uthuth,euth,euth,euth,euth,euth,ehhututh|KiKiKi <hʁ)τhhhututhɢhhɢhʁ)ʁ)ʁ)hhʁ)hbQ uth|utututh|h|||||||3}|||\fFut||ʁ)|h||ʁ)|h||||||||ʁ)|hhh|4d $zE|!$@[ "h $@K $>g!(E"$? [ ZVa$>U T]Translocator_changeF$R$`HS{md The Translocator was originally designed by Liandri Corporation's R&D sector to facilitate the rapid recall of miners during tunnel collapses. However, rapid deresolution and reconstitution can have several unwelcome effects, including increases in aggression and paranoia.||In order to prolong the careers of today's contenders, limits have been placed on Translocator use in the lower-ranked leagues. The latest iteration of the Translocator features a remotely operated camera, exceptionally useful when scouting out areas of contention.|It should be noted that while viewing the camera's surveillance output, the user is effectively blind to their immediate surroundings.E:BAP$pBO {*m:BAn$o"["\*Q ]! Crosshairs.Hud.Crosshair_Cross3^ n+W:A@A@{:/M$ff?QV%Z$#"""!" "Y%] Translocator $L?YY  Y%^#fMf*`Ki3}3}- =13}3}- =1hhhʁ)ʁ)hhqYԄhhhV*`*`*`*`hV3}ZshhhV*`VhV*`VVVVVhhhhk VVqYԛBBBBVVVVhVVhqYk k k k hVh|\fF|\fF,e|\fF,e|\fF,eh|\fF,ehqYԅKi|\fF,ehqYԎ|\fF,eh|\fF,e||\fF,e||\fF,e||ʁ)|ʁ)||\fF,e||\fF,ehhhhhhhhhh,eh,eh,eʁ)hqYk hVVhzVGBʁ)hzVGBJhzVGBhzVGBJV\ tMV\ tMVV\ tMV\ tMk hʁ)3}ZshhzVGBhzVGBʁ) Eh EhVʁ)k Vhh}LhVV|qYVhzVGBʁ)hzVGBJk hzVGBJVhzVGBhzVGBJV\ tMV\ tMk VVV\ tMV\ tMk Vhk hk k k VV3}k kM  e $?Y?Yfff?Y?Y33?Y?F ]LinkActivatedAbl" e$DW$DB $ #? ^!s s s s gdUoY%U$=c ;"p:pBs:zE$@,:??0:zDzDzD*$@@$p}?@$L>[ Y%Y%L  Y%Y%xY%z"GQ <KihhqYԚȵhqYԄhhqYԈqYԈqYg"_: aw SU@$?Y%Y%`)Y%Y%\!Ih#v$9 X[ʁ)hhqYTq u3},e u uʁ) uʁ),e,eMhMMTqhhzVGBTqhzVGBJTqTq X[- g l"e$|HS$DAhp:zCs:@E$@,: A0:HC*$ A ch q$?o$D~ b:/:::Y%p![,J 2PvO#3}3} u_:@?^$ BeY%Y%Y(Y%Y%q+Y%e"j \-9:9:$G+\sȵ\s\s\s3} u uʁ)ʁ)ʁ)\s\s\s\s\s3}3}3}3}h u uʁ)3}bQ BvL$@AP$ R$DS$C}$D_$Dl$Be$PCGmL |6>'3$C:$@  \ $`Eit D$An`c$ Awh$Bdb:/Pk:/0unk$BC$@Y%h"Y~&9:9:$-9:9:$G6\)qYԄh||hh|hhʁ)||hhhhh|hh|h|h|hqYԄh,ehʁ)hKiKi3}KiKi3}KiKiKi3}h|||||h|h3}|3}||DP.tҽҽҽҽҽҽҽډډh3}Zshh,ehhhzVGBhzVGBhh3}hhhh,eh uh u3}4P $?Q $EU $?V $?W $~?X *Y $AZ $A V GxuVa$?U T]SwitchToRocketLauncherF$G?R$G?{m}{The Trident Tri-barrel Rocket Launcher is extremely popular among competitors who enjoy more bang for their buck.|The rotating rear loading barrel design allows for both single- and multi-warhead launches, letting you place up to three dumb fire rockets on target.|The warheads are designed to deliver maximum concussive force to the target and surrounding area upon detonation.E:HB? AP$pBO {*m:@A`An$p" ["\*Q ]! Crosshairs.Hud.Crosshair_Triad2^OW:A{:/M$?QY%Z$#"""!"M "Y%]Rocket Launcher ]Y%Y%CY%Y%EY%Y%$Y%Y%S Y%Y%xY%Z#ja6- ܈qYԅKiQQKi3}hhh uhBBBBh|KiKi|hhh|||ʁ)|h|hh,e,e,e,eKiBhhhh3}B4D:@@I:/UZ$f$? Q iVU T]SwitchToMiniGunF$5?R$5?{m][The Schultz-Metzger T23-A 23mm rotary cannon is capable of firing both high-velocity caseless ammunition and cased rounds. With an unloaded weight of only 8 kilograms, the T23 is portable and maneuverable, easily worn across the back when employing the optional carrying strap.|The T23-A is the rotary cannon of choice for the discerning soldier.E:BAP$pBO  {*m:A?n$o"p" [" Q ]"!Crosshairs.Hud.Crosshair_Circle1^MW:@{:/M$@Qa%Z$#"""P!"L "jY%] Minigun6> 'J3$C:$@K $>h$C]Y%Y%KY%Y%_Y%_#Z"O #>9:9:$9:9:$-- - GB\k Bh3}hxv3}h*`3}3}3}7 9]*7 9]*xvxvxvxvxvxvxvxv[ [ [ [ [ 3}hEW3}3}hh7 9]*7 9]*7 9]*7 9]*7 9]*7 9]*7 9]*[ [ [ [ [ [ [ [ hEWhEWhEWhhEWhEWhEWhEWhEW3}3}3}ʁ) uhh,e3}hhhhhqYԄhqYԄhhqYԄh,e̊3}@@hh[ [ [ xvhEW7 9]*E:A0A33?mn"o$BY$/GM$0AP*PrSr$W$u=V$AU$PGT$@@S6'dJd3$C:$@imS]hYY^Y%Y%Y%Y%AY%Y%oY%N"QP 6D qYԄh|||+$||||hh|+$+$+$|||hh+$h|||hh+$hh,eh+$h|h|||ʁ)|h||||hh|hh|h|hKi3}KiKi3}Ki)U)U4E* r oxuVU T]SwitchToShockRifleF$G!?R$G!?ke]#"WeaponStaticMesh.ShockRiflePickupg$f:pi:@j:/ x" {m={The ASMD Shock Rifle has changed little since its incorporation into the Tournaments. The ASMD sports two firing modes capable of acting in concert to neutralize opponents in a devastating shockwave.||This combination attack is achieved when the weapon operator utilizes the secondary fire mode to deliver a charge of seeded plasma to the target.|Once the slow-moving plasma charge is within range of the target, the weapon operator may fire the photon beam into the plasma core, releasing the explosive energy of the anti-photons contained within the plasma's EM field.E:B`A P$BO {*m:0A8An$?o"p"["\*m$?Q ]! Crosshairs.Hud.Crosshair_Cross2^pW:@A{:/M$ff?Qi%Z$#"""n!"J "Y%] Shock Rifle6> 'JF3$C:$@K $333?]Y%r!\P 2!G wcZDeY%Y%Y%7Y%IY% Y%5Y%a$@y-9:9:$G"%a]Fȵ%a]F%a]F%a]Fpʁ)bQ %a]F%a]F%a]F%a]Fʁ)ʁ)ʁ)ʁ)ʁ)ʁ)3}TqB3}3}3}L "H $HCB $@A $>l$ff?e"b"@$?v }$DP$Rl$AS$Be$@Gmw} l $E6>'RJ 3$>C:$?imSXcD$A $?YY nPwh$BX$@A$@`!Y%Y%yY%Y%j  Y%Y%\Y%Y%M*uY%F gP"UA##+$ȵhhhhhh 3}hhqYԊ3}3}ʁ)̃ʁ)ʁ)ʁ)+$ʁ)ǙǙǙ3}3}h3}3} u uʁ)3}ǙV ]$HC^$C_$|Hd"Pf}$D_$DRl$4BS$Ce$GmI} |l $E6>'JU3$C:$@ \ $zEimSXt D$ Au$333?YY^c$Aw2h$BX$ AA$ AlA nk$ BC$@Y%Y%PY%Y%p Y%Y%Y%Y%DY%Y%OY%Y%q% Y%Y%kY%KY%gY%Y%bY%Y%r*Y%Y%}Y%`#P @7 9]*Bmn"o$BY$/GM$@P*PrSr$ #3Ɋ3}$d hhzVGBhzVGBJ@qhzVGBJ@q@qE>3ɲ@qE>3$d @J Y%_"B$h 9:9:$ -G E>3;o23}hÛ Û Û Û Û Û Û @T$zCy$zCT "g : A^ :AAB] $A  c]c h$L@YY nvG]Y%Y%_Y%Y%Q Y%Y%eY%Y%HY%@Y%t Y% m"\ b"H&9:9:$-9:9:$GBY6}K~Wh3},e u uʁ),e,eVH# uhhhhhҽҽҽҽҽҽҽҽҽҽҽҽ3}ҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽҽhhhhh,ehp uhh uʁ)ʁ)H8~`nq|H;h,e u,e3}VH#,e,eh,e,e,e,e,eʁ)VH#zVGBhh4l$zCS$De$PCHm\g!d!_!\!Y!$pBW!$pAV!$AL"" Nm!" U!$B`:O!$ Ap:zCs:@E$@,: A0:HC*$ ASM N Q W o!Sa $zDk $Dt $u $ i6>'3$C:$@  iM S]f cb$@@t$?n`k ^ Sh$Bq$?o$@EX$AA$@AI Snk$BC$@Y%Y%Y%Y%|Y%Y%Y%Y%eY%Y%SY%Y%Y%@#R%D 6vRJn-qYԄh||ʁ)|ʁ)|h|h||h|h|hh,eh uh,eh uKih,eh uKih,eh uh uh uh uh uh uWW3}W3}WWҽҽҽҽҽҽҽҽҽҽډډҽҽҽډډҽҽҽҽډډҽҽҽډډҽҽҽҽҽҽҽډډҽҽҽҽҽډډҽҽҽҽҽҽҽҽҽҽډډhZehZeҽhh u4n$pBs$pBt$Cx$By$(B{$(B}**~ZGA*D:DCF: A4 W xVU T]SwitchToLinkGunF$?R$?`{mY The Ion Painter seems innocuous enough at first glance, emitting a harmless low-power laser beam when the primary firing mode is engaged. Several seconds later a multi-gigawatt orbital ion cannon fires on the target, neutralizing any combatants in the vicinity.||The Ion Painter is a remote targeting device used to orient and fire the VAPOR Ion Cannon. The Ion Painter offers increased targeting accuracy via its telescopic sight, easily activated by the secondary fire mode of the weapon.|Once the Ion Painter has been used to designate a target it is highly recommended that the user put considerable distance between themselves and the weapon's area of effect.^|E:BA@P$pBO m:BAn$o"[" \*m$@Q ]"!Crosshairs.Hud.Crosshair_Circle2^{W:A@M$?Q%Z$#"""!"v "Y%] Ion Painter ]Y%Y%Y%Y%]Y%Y%V&Y%Y%k Y%}"`-NRWKihhhAψqYԄhhhqYԃʁ)h3}3}RJn- X[ X[hRJn-h,eAϊ3}hh,eh,eh|hh|h3}3}RJn-AAA X[ X[qY X[Tq X[hhzVGB X[TqhzVGBJ X[Tq X[ X[qYԈqYԊ3}hh,eh,eh,ehRJn-h,ehh uh uhh uAW$@Fp $?i Q U] TAGFireAT] TAGFireBK] TAGAquireOyoY%$?t;"$?@$=Y%Y%Y%Y%NY%+R"_` -9:9:$G@Z8BhhhqYԄhqYԄh̊3}@@hhh3}3}3} uh' u3}JS Q mn"J $@?o$CM$AM@Br$=]s Shb$@@D$@?uYY^Y%Y%D! ZY%xY%Y%| Y%Y%SY%Y%nY%Y%bY%Y%m Y%Y%YY%Y%QY%yY%j$wZ$9:9:$G6neqYԄhzVGBKiKiKi[X! h,e[X! [X! |hzVGBh||ʁ)[X! [X! [X! h[X! ʁ)[X! ʁ)hzVGB@qhzVGB3}hhzVGB3}hhhh,e3}h3}hhh,ehhh3}hhzVGBhhhhhhhzVGBhzVGB[X! hhh u3}Zs- =13}Zs- =1hhh uh uhh uhzVGBhhhhhqYԄhKiKihݝҳu)hݝҳu)ݝҳu)hzVGBhh,e4HG Cu]LockOno] SeekLostn$@ G EVA$ @} $L>U TMballgun_changeF$=R$=HSO SGE:A A P$pBO m:A@n$o"p"[" \*Q ]#"Crosshairs.Hud.Crosshair_Bracket2{ $^W:0AM$ @QR]Ball Launcher $>Y%Y%SMY%eY%Y%_Y%Y%rY%Y%Y%Y%GY%Y%Y%Y%uY%Y%| Y%Y%Y%Y%{ Y%Y%G+Y%Y%g  Y%Y%O*Y%Y%`rY%ZY%Y%DY%Y%Y%Y%Y%Y%3Y%Y%WRY%tY%Y%R*Y%Y%Y%Y%g)Y%~"O#I9:9:$GB AϛB3}3}h3}hhhhhqYԄhhqYԄhhhhqYԄhRJn-̊3}@@hhh}=Hxv}=HE:pAi Q mn"o$BM$AP*dddPdddrSr$?mS]ht YY^w-h$BY%Y%LY%Y% Y%Y%UMY%Y%Y%Y%Y%Y%Y%rY%i#bM J6KiqYԃʁ)̃ʁ)ʁ)ʁ)ʁ)qYԽ},ʁ)qYԈqYԽ},qYԽ},hhhhZehZeW$@F{$?UY%Y%mY%Y%Y%Y%A Y%Y%K Y%Y%zY%Y%Y%JT#mg(QJ6  ܈qYԅKiqYԅKi     ܊3}    ܈qYԅKiqYԅKi   ܄hhhh ܈qYԈqYԊ3}- =13}3}- =13}3}- =1}$@@I "K  |M!z$q=>r] minifirebZ ] miniemptyAD p"t"{$gm$q=>o$AQ ;"p:HBHBHBs:@F@F@F$@,:???0:zDzDzD*$@$p}?[ h F$aDf$ ף=eY%Y%&Y%Y%RY%Y%PY%Y%Y%Y%f Y%Y%Y%Y%E Y%Y%q gY%H Y%Y%f Y%Y%Y%Y%UY%Y%bY%Y%N Y%Y%gY%Y%XY%Y%cY%Y%iY%Y%hY%Y%jY%Y%oY%Y%P Y%Y%aY%Y%dY%s$r(T 9:9:$G6nmDUqYԄh|||ʁ)|h|hhKi\"Ki\"#h3}- =1KiKiKiKi̾##cZD#@qKiYǓh||KiKiҽҽҽu)ҽҽҽҽҽҽҽxhʁ)hʁ)hhwhwwʁ)wwwwwwwwYǓw uhhh3}3}3}KiKiBKiBҽKiBҽhh,eh,eKiKiBKiBKiBhh,ehhhh,e4 a YVU T]SwitchToAssaultRifleF$>R$>`ke]%$WeaponStaticMesh.AssaultRiflePickupg$f:@i:@0A@j:/w" {moInexpensive and easily produced, the AR770 provides a lightweight 5.56mm combat solution that is most effective against unarmored foes. With low-to-moderate armor penetration capabilities, this rifle is best suited to a role as a light support weapon.|The optional M355 Grenade Launcher provides the punch that makes this weapon effective against heavily armored enemies. Pick up a second assault rifle to double your fire power.E:BA P$BO {*m:PA@A n$o" p"$["m$ڬ*?Q ]! Crosshairs.Hud.Crosshair_Cross5^^W:@@{:/M$?Qw%Z$#"""'!"I "OY%]Assault Rifle6> 'J3$C:$@K $L?]Y%Y%lY%Y%Y%Y%Y%Y%lY%Y%zY%Y%zY%Y%oY%Y%Y%Y%Y%Y%k)Y%Y%iY%Y%Y%Y%Y%Y%Y%Y%Y%`"}$i @դAʁ)T$zCy$zC  cR h$ff?YY nvY%Y%Y%Y%Y%Y%q Y%Y%QY%Y%xY%Y%J9Y%t Y%Y%PY%Y%c'Y%Y%JY%Y%[Y%Y%VY%Y%VY%Y%]Y%e Y%Y%GY%Y%BY%Y%kY%Y%*gY%fY%Y%}RY%h Y%Y%iY%Y%lY%Y%#Y%Y%!IY%Y% Y%EY%Y%SY%Y%Y%Y%Y%Y%ZY%Y%v)Y%Y%G 9Y%bY%Y%dY%Y%kY%Y%kY%Y%i)Y%Y%A9Y%Y%WY%| Y%Y%|Y%Y%Y%%Y%l9Y%Y%Y%k Y%Y%Y%Y%G Y%hY%W Y%Y%BY%Y%M Y%Y%h Y%Y%p)Y%Y%:Y%Y%@gY%Y%Y%Y%Y%]Y%Y%Y%Y%Y%Y%GrY%Y%Y%vrY%OY%Y%Y%Y%Y%Y%t Y%Y%Y%Y%Y%Y%pY%Y%sY%Y%e*Y%Y%[ ZY%eY%Y%QY%Y%gY%Y%nY%Y%]Y% t$Q)r.YǓ <3}- =13}- =1qYԈqYԊ3}qYԄhqYmDU3}hqYmDUqYԈqYԄhh@~o@~o@~o@~o@~o@~o@~o@~o@~ohqYԄhhmDUmDUmDUmDUqYԈqYԈqYԈqYԄh3}h3}w $?L $>o $?C $fff?F $zCK $;ER $TDS $Db $;Dc $?_:A AOKyKY%oY%F$?-Y  ?]AssaultRifleAltFire]!] BReload9$?~ ;"$@,:0:z*$@k@$>[ Y%Y%@ Y%W"U 2[#>2\"L"2K"g%Z$#"""!" "Y%= Shock CoreY%Y%ZY%Y%Y%Y%aY%Y%fY%Y%{&Y%Y%o+Y%Y%Y%Y%Y%Y%LY%Y%GY%Y%Y%Y%} Y%Y%t Y%Y%Y%Y%o Y%Y%AY%Y%k Y%Y%@Y%Y%ZY%b*Y%Y%q)Y%Y%H Y%Y%Y%c"m z$tPoOKiqYԈqYԈqYԈqYԈqYԈqYԈqY@դAqY@դAhҽqYԈqY@դAqYD䶚@դAqYԄhhhD䶚D䶚E>3ɈqYԈqYԄhhD䶚D䶚E>3ɈqY@դAB$L>A$@@_ c!gPdY%KY%oU- ?] TranslocatorModuleRegeneration$?} ;"$?Y%Y%fY%Y%Y%Y%yY%Y%Y%Y%JY%[#F.u A-9:9:$G"zɍȵʁ)̃ʁ)ʁ)hʁ)ʁ)3}3}h5?h5?3}3}3}3}h5?5?}$zD_$zEl$AS$mc| l $E6>'dJd3$C:$@@  \ $ZEit D$@@[ :H@ ? ?o: An^c$@wh$HBdb:/8nk$AC$@Y%Y%M Y%H"R]6i|i4qYԄh||hhh||||ʁ)|h||h|h|hh||BKi3}h,eh uhh uhKihh uKih,eh uhh uh uh uh uh uKi3}Ki3}KiҽҽҽҽҽҽҽҽҽҽҽҽҽҽډډҽҽҽҽҽډډҽҽҽҽҽҽҽҽҽҽډډhZehZeҽhh uB4m$Bl$Bn$pBs$pBt$Cx$By$(B{$(B}*j*i**~ZGA*D:DCF: A4 y _ xuVU$?L!$Q>U T]SwitchToLightningGunF$ף0?R$ף0?c{mAThe Lightning Gun is a high-power energy rifle capable of ablating even the heaviest carapace armor. Acquisition of a target at long range requires a steady hand, but the anti-jitter effect of the optical system reduces the weapon's learning curve significantly. Once the target has been acquired, the operator depresses the trigger, painting a proton 'patch' on the target. Milliseconds later the rifle emits a high voltage arc of electricity, which seeks out the charge differential and annihilates the target.E:BAP$pBO  {*m:A@H:BB n$p" \*{ $>^ ~W:33@M$33@Qv%Z$#"""!"K "Y%]Lightning Gun6> 'J3$C:$@K $>]Y%Y%HY%Y%K+Y%Y%Y%Y%Y%zY%J Y%Y%@Y%Y%I Y%Y%Y%%Y%]&Y%Y%OY%Y%HY%Y%MY%Y%{Y%Y%Y%Y%XY%Y%oY%Y%Y%Y%j*Y%Y%Y%Y%Y%Y%Y%Y%  Y%Y%`Y%Y%SY%Y%Q Y%Y%F Y%Y%Y%Y%OY%Y%WY%Y%Y%Y%Y%K$s 3\}1'i7i)]%o was PULVERIZED by %k!.]%o was PULVERIZED!1]%o was PULVERIZED!ySBCqI$DJ$DY%Y% Y%Y%})Y%Y%Y%Y%Y rY%y Y%Y%J Y% Y%]*Y%Y%Y%Y%+Y%F$wo 3f2V1'i7 )]0/%o was fatally enlightened by %k's shock beam..];:%o somehow managed to shoot herself with the shock rifle.1];:%o somehow managed to shoot himself with the shock rifle.]A@$L?$@?_ $Y?b$?Y%Y%Y%Y%e Y%Y%Y%Y%IY%Y%A Y%Y%CY%Y%x Y%Y%mY%Y%j  Y%Y%N Y%Y%nvib?xp| { z  qvzp6c|vv| 6c{ 6cu ax rvz(wu *vx m<vl&n9D $p99mt%tl6n9D?6n9D?6n9D?(v9PapntQ $t%tlCI@9?9?t9?l&@6pC6pC6p(v9Papmt (vm GY%Y%Y%S Y%Y%p Y%Y%"Y%Y%~Y%Y%XY%Y%NY%Y%Z Y%Y%x Y%Y%Y%Y%Y%Y%`yY%gMY%I Y%Y%Y%DY%Y%DY%Y%Y%aY%Y%KY%Y%D zr#Pq D-9:9:$G:I|ǏȵbQ Bʁ)ʁ)Af3}hʁ)ʁ)3}BBhʁ)ʁ)3}bQ BbQ Bps $@` ` ` ` ` ` }$@E_$(El$PAe$@Fm@  \ $;ED$,@$`An^mY%Y%Y%Y%T NY%HY%Y%L Y%Y%Y%Y%Y%Y%LY%Y%uY%Y%i Y%Y%MY%Y%Y%Y%WY%Y%XY%Y%Y%Y%Y%Y%Y%Y%o Y%Y%Y%Y%NzY%6Y%Y%Y%Zl#q#caI.vʁ)nou xy { | }~F J Y%Y%AY%Y%V*Y%Y%Y%Y%fY%Y%Y%Y%vY%Y%uWXY\Y%sY%Y%v Y%Y%VY%Y%v  Y%Y%Y%Y%sY%Y%t gY%Y%Y%_Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%D  Y%Y%Y%Y%oY%Y%BY%%Y%Y%Y%Y%Y%hY%Y%Y%Y%CY%d"qp k-9:9:$G+DP.t\sʁ)ʁ)mUD$ AY%Y%~Y%Y%-Y%Y%ZY%Y%Y%Y%Y%Y%_Y%Y%lY%\"i!e RNDXۅKiqYԊ3}- =13}- =13}- =13}- =13}3}- =13}3}- =1hhqYԄhhh3}BhhBBBBBBBhhhhhqYԊ3}ʁ)hqYԄhhhB?4ʁ)̄hʁ)hhh,eh,ehBqYԋҽqYԛBqYԈqYԛBqYԄhBqYԋҽqYԄhhhh3}qYԛBBAx |$By$>r$}Gl$PGi$ Bj$Cm$?q$>F%$A_ s$>t$ @r!v]shieldgun_chargeyq$?S OKY%oY%c$- ?]ShieldGunFire$?} $@,:0:z*$@$?@$=[ Y%Y%jY%Y%NY%DY%PY%Y%Y%Y%[Y%Y%Y%Y%kY%Y%VY%Y%Y%Y%fY%Y%W*Y%Y%]Y%["~j r9:9:$G6@R\@wqYԅKiNDXۅKiKiKih,ehhKiKi3}KiKiKiKiKiKitPoOtPoOphhhzVGBh|||||zVGBh||hh|||h|hhh||||hhh|||hKiKiKih||||Ki3}KiKiKiKiKiKiKihh|Kihh4H  J ]ShieldReflection N tVU T]ShieldGun_changeF$33>R$33>x`HS{mWThe Kemphler DD280 Riot Control Device has the ability to resist and reflect incoming projectiles and energy beams. The plasma wave inflicts massive damage, rupturing tissue, pulverizing organs, and flooding the bloodstream with dangerous gas bubbles.||This weapon may be intended for combat at close range, but when wielded properly should be considered as dangerous as any other armament in your arsenal.E:pA@@P$pBO {*ym: A33S@ffn$o"["\*yQ ]"!Crosshairs.Hud.Crosshair_Pointer\W:@333,{:/M$ @QD%Z$#"""'!" "MY%= Shield Gun $>]Y%Y%^Y%Y%dY%Y%Y%Y%Z*Y%Y%[Y%Y%@+ Y%Y%TY%Y%wY%Y%BY%Y%W Y%l"v 2gl\"L"K" `%Z$#""""!" "NY%] RocketsY%Y%P Y%Y%c~Y%iNY%{Y%Y%K Y%Y%`Y%Y%lY%Y%hY%Y%_Y%Y%Y%JQ"OKrD3TJ6qYZ8Z8  +$3}qYԄhhhhqYԖoqYԈqYԖookZAfp"-t"-W$ЄF{$`jGm - ?MShockRifleFire$333?[;"$@,:0:*$L@$333?[ F$/DY%Y%`Y%q$I 2t!\"L"K"] BallAmmoY%Y%dY%Y%uY%Y%d*Y%Y%{*Y%Y%OY%Y%pY%Y% Y%Y%Y%Y%w Y%Y%Y%Y%LY%Y%r Y%Y%C*Y%Y%Y%Y%v Y%g$E 2G%\"L"2K"y%Z$#"""R!" "Y%MBio-Rifle GoopY%Y%ZY%Y%Y%Y%EY%Y%Y%Y%Y%ZY%RY%Y%xY% q"H-y O/ <hqYԈqYԄh_:BOq$?- ?Mredeemer_shoot$?U;"$@,:0:z*$@kd$?Y%Y%TY%mY%V(Y%Y%Y% !WT 6 Sy hzVGBhzVGBJ)Uu))Uu)4 ] ] F$?HST]Super Shock Rifle]SY%Y%Y%Y%Y%Y%zY%Y%GY%Y%Y%Y%M Y%Y%,Y% u!LT[, <ۉխhhzVGBqYԄhzVGBJqYԈqYۉխqYۉխۉխuthh uۉխutۉխqYۉխh,eۉխqYz  a ]TranslocatorFirej ] TranslocatorModuleRegeneration_:AA aSPQSF$?$>;"k$>Y%Y%Y%Y%Y%Y%JY%Y%CY%Y%f*Y%Y%^Y%Y%Y%Y%Y%Y%Y% Y%B Y%Y%dY%Y%BY%Y%Y%x"t| 6 i %EGqYԄh|||h|hhhh,e4 O AxuVU$*?A$?} $ff>L!$,?U T]SwitchToFlakCannonF$?R$?`{m6tThe first time you witness this miniature nuclear device in action, you'll agree it is the most powerful weapon in the Tournament.|Launch a slow-moving but utterly devastating missile with the primary fire; but make sure you're out of the Redeemer's impressive blast radius before it impacts. The secondary fire allows you to guide the nuke yourself with a rocket's-eye view.||Keep in mind, however, that you are vulnerable to attack when steering the Redeemer's projectile. Due to the extreme bulkiness of its ammo, the Redeemer is exhausted after a single shot.^P$pBO m:A@[" \*m$@Q ]"!Crosshairs.Hud.Crosshair_Circle2^cjW:`A{:/pM$33?QL%Z$#"""^!"n "Y%] Redeemer $?Y%Y%AY%Y%^Y%Y%Y%DY%n Y%Y%Y%Y%tY%Y%QY%Y%Y%Y%wY%Y%X Y%Y%uY%Y%Y%Y%W @@vZD"x%| @wiRMZ8Z8J S Q mSYYY%Y%KY%Y%{@Y%Y%Y%Y%X(@Y%Y%Y%Y%|RY%[Y%Y%Y%R$W 3@ q1'i,eB,B,IP7^ )]&%%o was shredded by %k's flak cannon..]$#%o was perforated by her own flak.1]$#%o was perforated by his own flak.qk b$?Y%Y%Y%Y%C Y%Y%VY%L$t 3D n1'i7)]$#%o was mowed down by %k's minigun..]#"%o turned the minigun on herself.1]#"%o turned the minigun on himself.ok V:DN$D_ $ff&?Y%Y% Y%Y%P gY%{Y%Y%I  Y%Y%Y%Y%8Y%Y%Y%J$zZ 3L  1'i7)]$#%o rode %k's rocket into oblivion..]"!%o fired her rocket prematurely.1]"!%o fired his rocket prematurely.]qlX$>N$@Fb$ff?Y%Y%zY%Y%K Y%Y%{Y%Y%|)Y%X#I 2Q }I\"L",K"c%Z$#"R""(!" "OY%] BulletsY%Y%@Y%Y%z Y%Y%T Y%Y%U Y%Y%QY%Y%cY%Y%Pb#nQ >9:9:$-@+ -- 9:9:$G\ tM@3}SS逖*`SSSS逄hhVSS逊3}3}@Y^{ i :pAh :/Y%Y%uY%Y%Y%Y%OY%Y%_ Y%Y%t Y%d#R 2c #\"L"K"Fo%Z$#"""R!" "}Y%] Link AmmoY%Y%Y%Y%i Y%Y%~)Y%Y%Y%Y%JY%Y%Y%Y% Y%Y%Y%Y%uY%Y%eY%Y%l Y%Y%h Y%Y%wY%Y%gY%z#` 2r  3K\"L"#K"f%Z$#"""(!" "QY%] Flak ShellsY%Y%~Y%Y%UY%Y%Y%Y%n Y%Y%`Y%Y%W Y%Y%Y%Y%Z Y%Y%0Y%Y%Y%Y%~ Y%Y%A Y%Y%Y%Y%nY%Y%B Y%Y%P Y%Y%Y%Y%JY%Y%Y%Y%MY%Y%UY%Y%]Y%Y%(Y%Y%I Y%Y%PY%Y%a)NY%G Y%Y%UY%Y%NY%Y%O Y%Y%D Y%Y%s#Y%Y%M&NY%V Y%Y%TY%Y%Y%Y%bY%Y%K Y%Y%\ Y%Y%jY%Y%Y%Y%_jD( y{% '-O (n 99v l jen Mauzl j'fwM*wM {%-Ma/!G/.M luh 9D9?0>-O 'z#cM-A 0S0O ?A &O0A 9D9?A Ma/!I,Ma/!zMa/!V .VMuzM&+A ufn { z#ccw.*.VMuzul z#.VMuzSjv uz{-O  {,juv 9Ph    Gw#^S 6#^ AGqYԄhh _h||hh|h|hqYԄh|||ʁ)h|||ʁ)|h|hh|h|hqY4 W kxuVU T]SwitchToFlakCannonF$@?R$@?{mtTrident Defensive Technologies Series 7 Flechette Cannon has been taken to the next step in evolution with the production of the Mk3 "Negotiator". The ionized flechettes are capable of delivering second and third-degree burns to organic tissue, cauterizing the wound instantly.||Payload delivery is achieved via one of two methods: ionized flechettes launched in a spread pattern directly from the barrel; or via fragmentation grenades that explode on impact, radiating flechettes in all directions.E:HCBP$pBO  {*m:@`An$o" p" [" \*Q ]! Crosshairs.Hud.Crosshair_Triad3^^W:A{:/AM$33?Qe%Z$#"""!" "Y%] Flak Cannon6> 'J3$C:$@ ]Y%Y%_Y%Y%Y%Y%@Y%Y%tAY%lY%Y%Y%Y%}cY%zY%Y%EY%Y%MY%Y%rY%Y%dh .I ?r%+r,PrrF*!hrF i ]9?,_hh9?9Di 9D\e rF h -H rF-H e M !e M r0 GY%Y%Y%Y%Y%k Y%Y%l Y%Y%@Y%Y%n  Y%Y%m Y%Y%GY%Y%q Y%Y%Y%Y%BY%Y%MY%H$q 3x J1'i7\)]'&%o was pulverized by %k's shield gun..],+%o threw her weight around once too often.1],+%o threw his weight around once too often.]CI$CJ$Cb$>Y%Y%Y%Y%} Y%Y%pY%Y%[Y%Y%zY%Y% Y%Y%O Y%Y%tY%Y%X%F79:9:$B a C a I 99I --f'? GY%O]Y%]Y%Y%yY%Y%Y%F Y%Q Y%Y%K Y%Y%Y%Y%Y%Y%H \Y%aY%mY%Y%[gY%UY%Y%TY%Y%E Y%Y%}Y%Y%FY%Y%dY%Y%GY%Y%Y%Y%Y Y%Y%Y%Y%PY%Y%k\Y%Z Y%Y%Y%Y%Y%Y%Y%Y%sY%Y%c Y%Y%^ Y%Y%Y%Y%vY%Y%q[Y%pY%Y%qY%Y%i Y%Y%Y%Y%g Y%Y%m Y%Y%Y%Y%Y%Y%tgY%p Y%Y%z wCAp89:9:$r*r*a 9:9:$f #? r*a fuw*|a  xn m g a   M6hn ի6hm 6hg W.R @ rv."wv*$v9?&a v Xra  #?W A9:9:$fmWa+9PmWwu*ua Wm A19:v9:$g BaGIgwBzCB<I BV9:v9:$q!Smm9:v9:$q!E GY%~@gY%WY%u WZ$fN 6w (6dqYԅKih||hhh||hhh|||ʁ)|h|hh||h|hqY4 \ lVU T]SwitchToFlakCannonF$ ?R$ ?{mD The GES BioRifle continues to be one of the most controversial weapons in the Tournament. Loved by some, loathed by others, the BioRifle has long been the subject of debate over its usefulness.||Some Tournament purists argue that it is the equivalent of a cowardly minefield. Others argue that it enhances the tactical capabilities of defensive combatants.|Despite the debate, the weapon provides rapid-fire wide-area coverage in primary firing mode, and a single-fire variable payload secondary firing mode. In layman's terms, this equates to being able to pepper an area with small globs of Biosludge, or launch one large glob at the target.E:BBP$pBO {*m:AAn$["\*m$?Q ]! Crosshairs.Hud.Crosshair_Triad1^RW:@@@M$ @Qt%Z$#"""!" "Y%] Bio-Rifle Y%Y%lY%x Y%w"r]/?vr%9:v9:$q!S<<9:v9:$q!E GY%Y%Y%} Y%RY%Y%Y%@ Y%Y%fY%Y%nY%Y%E+Y%Y%yY%Y%FzY%gY%Y%Va]  GY%F G^)  GY%XY%Y%n*Y%Y%Y%Y%LrY%]Y%Y%Y%Y%^Y%Y%XY%Y%KZY%R Y%Y%\*Y%Y%Z Y%Y%U Y%Y%V Y%Y%W Y%Y%mY%Y%yY%Y%K Y%Y%\ Y%Y%wY%Y%X*Y%rC"MK ] Z]rD3ThzVGBhzVGBJqYԈqYZ8Z8hʁ)ʁ)hhhkwApp"t"{$PG- $̌?R;"Y%Y%PY%F"N _ ЊKiPQSdU$=$>Y%Y%Y*Y%Y%PY%Y%a Y%Y%b Y%Y%j(NgxP _P-xw.*NrY*Y--x(P(N GY%EY%Y%c Y%Y%'Y%Y%}Y%Y%YY%Y%kY%Y%l Y%Y%KY%Y%@yY%o Y%Y%KY%Y%IY%Y%CY%Y%WY%FY%Y%tY%Y%} Y%Y%Y%Y%rY%L"[ 2y rJ8\"L"(K"gu%Z$#"""R!" "Y%]Lightning ChargesY%Y%[  Y%Y%nY%Y%{ Y%Y%C Y%Y%Y%Y%@ Y%Y%B Y%Y%Y%Y%Y%Y%fY%Y%wY%Y%P@NY%E @NY%Y%Y%M Y%Y%Y%Y%Y%Y%VY%Y%hY%Y%SY%Y%fY%Y%Y%Y%gY%Y%pY%Y%Y%Y%T Y%Y%qY%Y%V ~Y%q~Y%Y Y%Y%Y%Y%ZY%Y%[ Y%Y%SY%Y%Y%Y%Y%Y%Y%Y%BY%Y%hY%Y%j Y%Y%_Y%Y%XY%Y%Y%Y%s Y%Y%n Y%Y%Y%Y%Y%Y%`Y%Y%v Y%Y%Y%Y%GY%Y%m Y%Y%AY%Y%vY%Y%Y%Y%Y%Y%w)Y%Y%LY%Y%z Y%b"n 2} \"L"dK"d]ShieldY%m#W 2~ g\"L"K"z] Grenades]Y%Y%Y%Y%Y%E^"g AQgE>3@YY Y%Y%C-zY%u Y%E]"f ERE>3@YY Y%Y%Y% f"o~GI <)ȵqYԈqYԄh)hqYԄhhqYԈqYԈqY\s\s\s3}\s)h)3})qY))hs$Cj$zD@""_:A@jOy^ $33@dTc$- ?]RocketLauncherFire$33s?g;"$@,:0:z*$@k$?@$fff?[ eY%Y%Y%Y%BzY%IzY%Y%Y%MY%Y%@Y%Y%Jzg"dC 2OPv3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}=$G?]You got the Rocket Launcher.]RocketLauncherPickup  $ff>Y%Y%nY%Y%]zY%] Y%Y%Y%Y%Rz i"Mt V$x <)ȵ)qY_:A@jOc$- ?]RocketLauncherFire$fff?g;"$@,:0:z*$@k$?@$fff?[ Y%Y%`Y%Y%WY%j"Ru Yp@3}BB@S J Y%Y%XY%Y%Y%Y"D 2\|EPv=$>\]You got the Shield Gun.]ShieldGunPickup  $?Y%Y%IpC*0#r*w 59:9:$ KF K -k-k(-V(_*Z   q[  }] _zb] S99[ Z cRzprz_nim-V nb-V'.  _znlw_*lila_*-V-V(.  -V(K i GY%U ~Y%^~!k"{ 2`";!G wL" =$>g]You picked up a rocket pack.]RocketAmmoPickup  $333?o: @A$XAY%Y%_~Y%a~Y%b~n"}Z;%d!ȵ3},e u uʁ),e,ep3},e,e,e _,eh,e,e,e,eh,e,e,ehhh,ehpʁ)3}phpp:zCs:@E$@,: A0:HC*$ An! }$zD_$zDl$zCS$De$PCHm\6>'3$C:$@  imStD$A$?n`vSwh$Bq$?o$@EX$AA$@Aldb:/Pk:/0unk$BC$@Y%Y%L Y%!V"| 2g!G wL" []You picked up a Shock Core.]ShockAmmoPickup  [ :L???o:BA$BY%Y%oY%U"Ed iS@3}BBhhzVGBhzVGBJhzVGBJ@S 6> 'JF3$C:$@K i :@ h :/YYY%o"y-w 2jBPv3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}Zsc c c c MS=$?iB$B]You got the Redeemer.]FlakCannonPickup  $fff?Y%Y%lY%Y%qY%S"c @m/-' P*PY%Y%cQ O"u\ o <hh qY_:AAq$>dTF$?- ?]ShockRifleAltFire$?[;"p:pBAs:zDzD$@k+$33>[ Y%M"^E 21plPv3} 3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3} 3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}_:>=$G!? ]You got the Shock Rifle.]ShockRiflePickup  $ ?YYY%Y%Y%Y%u Y%Y%tY%Y%s Y%!K"} 2u%!G wL" y ]You picked up lightning ammo.]SniperAmmoPickup  A$AY%J"CZv @3}h@6> 'J3$C:$@K Y%Y%xY%Y%EY%JI"C&z y J6qYԈqYԖ uqYԈqYԈqYԈqY|i4hqYԖ uhhhhqYԈqYԃʁ)̃ʁ)}Lhhʁ)ʁ)qYԛBʁ)b o&c  d "e $?h $Ci $@q Asp"Ft"FW$ЄFF$?-?]LightningGunFire$?y ;"$@,:p A0:zzE*$?$>@$?F$TDY%Y%Y%Y%|Y%Y%}Y%Y%KY%G"\F 2~W]Pv3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}=$ff&?|]You got the Lightning Gun.]SniperRiflePickup  $ff>Y%Y%LY%Y%Y%Op"Dx AcO/qYԈqYԄhK~WK~Wh uh u uhh u uK~WK~WK~WK~WK~WK~W uzVGBqYԈqYԄhY%Y%f Y%Y%OY%Y%O(Y%Y%a&|\;y.*ry*ry*wy*<y y 9?@fff?-x?yIAyd1y^ 3y  9??>y  9?@=6y 6y 9?,> GY%@Y%Y%SIY%FY%Y%Y%+Y% {z[g @.@r@*r@*X@\ @>@   + GY%HY%r"Vz L:3 @3}SS@J\ $@E i : h :/$?Y%Y%CY%Y%yY%Y%buKS4ebw*LaP KHI%L*LHF@ GY%xY%Y%wvNV @-x(z.Erz*rz*$Zzd $z^ wY*Y-zf-x'$Y*zfzI-N'$$kz  Mz9?,V@ +hV@@ +kV k9?,Y*$wY*Y-zf-x'$Y*k9?  ?$+zfzI-N'$:333?$$ G[E"w%M 2RV{[#>2L"K"Y%Y%t"I}!H 2TnPv=$ff&?S] You got the Super Shock Rifle.]ShockRiflePickup  $?Y%s"{ 2UY=\"L"K"]Redeemer AmmoY%z!D-F V@hhzVGBhzVGBJ@J YY  Y%Y%aY%Y%WY%Y%eY%s!A"\}ZAȅKih||h|ʁ)ۉխqYۉխۉխۉխhututۉխut3}WSFhututhhqYutututhzVGBhzVGB?4hh3},e,e,e,eh,ehh,ehh,eh3},eh3}u,eh,eh,ehqYԑ,eۉխ̄hhhhhzVGBhzVGBJhhhbQ hhhhhhhzVGBhzVGB'yhh uutۉխۉխhututhuthuthuthhhhhhhhhqYԄhhۉխqYۉխhh uۉխqYw] ] QSdQ $>$>Y%Y%G ZtaH ( GY%?Y%Y%E Y%Y%Y%Y%`Y%aY%bY%cY%dY%eY%fY%gY%NY%| Y%hY%kY%y Y%iY%lY%mY%nY%oY%pY%Y%hy"} ;s;YutC Y%Y%g+gY%;Y%Y%qY%mY%{"~ xVoKiPQS$=$>Y%Y%zY%Y%o Y%|"Gv 2{QlPv3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}ZsMS=$?RB$B]You got the Ion Painter.]LinkGunPickup  $?Y%Y%Y%Y%pY%Y%cY%"XC 0@3}SS@ Y%Y%Y%Y%~Y%Y%CY%Y%e Y%Y%AY%Y%Y%Y%GY%Y%QY%Y%NY%Y%TY%Y%Y%Y%ZY%Y%N aS#PB 2 M Pv3}3}3}3}3}3}3}=$H:?]You got the Minigun.]MinigunPickup  $?Y%Y%Y%Y%LaY%QY%RY%SY%TY%UY%VY%WY%XY%vY%]!Y%Y%iY%Y%\Y%H Y%[!Y%Y%CY%Y%o,R G.|qNw*urw*ra  \a  al% N@.w@*$@9?&a @ XFa  #? Aak%H19?,(1#O9P119?,n-9:9:$9?,(&M b w*uR aq% nwR *R   GY%gbV#]u5a+@3}3}3}h uʁ)aI.3}h3}3}܊3}3}B3}3}3}܄hW=W=W=W=W=W=W=W=W=܊3}hhhqYԺ܊3}3}ܺܛB@^ H  P!$=s!$Q8>p!$HBq!$@Fw JY^D%6> 'J3$C:$@K\ $@E Y%Y%] pSc  G!W#z 2cZ\^!G wL"2Q ]You picked up 50 bullets.]MinigunAmmoPickup  A$LAY%Y%Y%Y%Y%Y%CY%Y%mbY%Y%QY#K iW,.Q}$?| M!z$>r] minialtfirebAap"t"m$>o$@@h f$n(s>nu @rs*s> u rs*a (]CC \PG s G\#V,A 26lyPvh||\fF E| E Eh Eh3}V3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}V3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}_:>=$333?]You got the Link Gun.]LinkGunPickup  $ff&?Y%Y%pbY%u Y%!c#d,y 2oMo!G w3}ZsL"2=$u>c ]You picked up link charges.MLinkAmmoPickup  A$(AY%Y%qbY%vb e#~S r{ <VVVBBVqYzɍVzɍqYԛBqYU  G ] BLinkedFire_:AA@KY%oY%F$@?- ?]TranslocatorFire$L>c ;"p: Bs:D$@,:?0:*$@kz$p}?@$=[ Y%Y%tY%Y%s Y%Y%r Y%Y%p bY%xY%Y%PY%Y%f Y%Y%yY%Y%^Y%Y%~Y%AcY%RY%Y%N~Y%P!Y%Y%FcY%TY%Y%[ Y%Y%GcY%HcY%IcY%LcY%EY%Y%Y%Y%RcY%UY%Y%J Y%Y%YY%Y%Y%Y%Y%Y%ScY%Vco#hr *TWȵ3} u uʁ)3}ʁ)Bʁ)bQ 3}3} u uʁ)}$DP$aCl$Be$|Gmj|  \ $zEct D$@$AYYv&ndwh$Blnk$pBC$@Y%Y%QY%Y%c p#rY Wg <qYg" _:A@oY%F$33s?- ?MFlakCannonFire$ e?r ;"$@,:0:z*$@kI$333?[ f$DeY%Y%N Y%Y%ZY%Y%U Y%Y%Y%Y%cY%Y%Y%v#T@ 2^4Pv3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}3}_:>=$@?^ ]You got the Flak Cannon.]FlakCannonPickup  $ ?Y%Y%E!Y%Y%Y%Y%HY%Y%}Y%Y%rY%Y%hY%x#p_ e @3}BB@^ J6> 'J3$C:$@ Y%!y#x 2fn[!G wL" =$ ף>r ]You picked up 10 Flak Shells.MFlakAmmoPickup  $L?o:@A$AY%Y%vY%Y%xY%Y%\Y%Y%Y% }#qe k@ <qYԅKi_:AA@OKdToY%F$fff?- ?]FlakCannonAltFire${?r ;"$@,:0:z*$@kT$?@$fff?Y%Y%nY%@$k 3mQ1'i7)]%$%o had their atoms scattered by %k..]0/%o tried to go where no woman has gone before.1].-%o tried to go where no man has gone before.s |SS$?Y%Y%Y%Y%Y%fA$l 2p_ $Y?Y%Y%u)AY%Y%Y%b AY%vAY%yY%Y%Y%Y%@TY%|Y%Y%}Y%Y%Y%D$on 386"1'i u,e,eB,B,IPM7|)];:%o's cranium was made extra crispy by %k's lightning gun..]87%o violated the laws of space-time and sniped herself.1]87%o violated the laws of space-time and sniped himself.Sr AA @$fff?Y%Y%FTY%aY%E$qY 3CeQ'1'i,eB,B,IP7 )]43%o couldn't avoid the blast from %k's shock combo..]0/%o made a tactical error with her shock combo.1]0/%o made a tactical error with his shock combo.S]lY%Y%Y%Y%x Y%Y%H@TY%@TG$yp 3I1'i7 )]#"%o was wasted by %k's shock core..])(%o snuffed herself with the shock core.1])(%o snuffed himself with the shock core.]qA@$L?Y%Y%q9Y%LY%Y%] Y%Y%[ PY%Y%Y%x-Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%~ Y%L I$r 2UNL  Y%Y%y X|>b;X9?&&& C& GY%E Y%Y%Y%Y%Vb,  GY%Y%Y%E Y%Y%M \Y%\\Y%Yd mMJ9:9:$-'a d9?,d"@q!B GY%]\Y%Y%D M$u 2aK)D nY%N$|v 3bB1'i7)]'&%o was carved up by %k's green shaft..]%o shafted herself.1]%o shafted himself.]q @SKA@$?Y%O$~w 3cv1'i7)]0/%o was served an extra helping of %k's plasma..]-,%o fried herself with her own plasma blast.1]-,%o fried himself with his own plasma blast.]qV:/DA@$?_ $+?Y%Y%Y%Y%OY%Y%LY%Y%i9P$x 3hH~1'i7R)]%o was OBLITERATED by %k!.]%o was OBLITERATED1]%o was OBLITERATEDyS]q Bm $A@$?Y%Y%k9@ Q$X 2ju D@ q)]+*%o was ripped to shreds by %k's shrapnel..]'&%o blew herself up with a flak shell.1]'&%o blew himself up with a flak shell.]l$>Y%Y%s9Y%Y%Y%vY%Y%LZY%pO +[+O %orm*rm* r*r*)my rm*x- rx  a a(((]9?O >a GY%n@ZY%kY%Y%Y%Y%{9Y%rY%Y%eY%Y%p@ZS$y 3wМz1'i7w )]"!%o was slimed by %k's bio-rifle..] %o was slimed by her own goop.1] %o was slimed by his own goop.]qA"Y%Y%k+ZY%xZY%yZY%@9Y%zZY%vZY%|ZT$z 31'i7m)]"!%o tried to juggle %k's grenade..]%o jumped on her own grenade.1]%o jumped on his own grenade.]qY%Y%9U${ 3AO@1'i7m)]*)%o was ventilated by %k's assault rifle..]%o assaulted herself.1]%o assaulted himself.ok V:DN$D_ $333?Y%Y%~ZY%}ZY%CZY%T Y%Y%eY%Y%U Y%Y%IY% Y%Y% Y% ~dwT*T-(DwP*P-(Pa[w}*}a  GY%yMY%Y%Y%Y%Y%O@Y%Y%gMZV$A.} @Pc!^Z8Z8Jm'mSYYY%W$@ ;QE7utC f 'Y%Y$WG 2 R#Pv3}3}3}3}3}3}3}3}3}3}3}=$@?w ]You got the Bio-Rifle]FlakCannonPickup  $?Y%Y%EMY%Y%Y%jMY%X$[$e+( GY%`'Y%Y%lY%Y%lY%Y%jY%Y%AY% b$oB \$0 <BqY_:AAOKoY%- ?] BioRifleFire$>G;"p:Bs:zD$ff?,:0:zD*$ff?k%$L?[ Y%Y%d$Y%Y%Y%Y%s+eac-~'>ee9?,d/a3 E+ee10wE+*9?,dB9?,ZS ,rT *T 9?,B -6e333?$9:9:$a$-(o$MwT*T-(9:9:$ rP*PaI #@"@Pa* GY%Y%Y%~+Y%Y%Y%Y%Y%Y%FD|( GY%bY%Y%U Y%Y%rY%Y%Y%Y%}Y%Y%Y%Y%MY% c$T)R&l6$P <3}- =13}3}- =13}3}- =1qY%a]F%a]F%a]FqYԈqYԄhhhhhhqYԈqYԈqYԄhhhqYԈqYԈqYԈqYԈqYԈqYԛBqYԈqYԅKiS $>R " v  _:AAOKyoY%- ?] BioRifleFire$>Gp:Bs:zD$@,:0:zDzD*$@k%$?@$L?Y%Y%vY%Y%O Y%Y%SY%Y%nGY%rY%Y%Y%Y%pGe$rD t8@-@3}BBB@J Y%Y%oY%Y%xY%Y%PY%Y%{Y%!f$u-t 2y!G wʁ)L"=$ ף>G]#"You picked up some Bio-Rifle ammoMFlakAmmoPickup  o:(AA$AY%Y%SY%Y%{Y%Y%~yY%m yY%}Y%Y%ByY%myY%@yY%~Y%Y%Y%h$UPE! KihhhzVGBh,ehnnzVGBhzVGBnheG $A[ $zEy$>tY%Y%KY% i$NG G<n <qYԄh,ezVGB[X! e[X! [X! eqYԄhzVGBhzVGBehzVGB[X! hۉխhhhhh uPQS- ?Mballgun_launch$>tY%Y%_$dLw3*3a GY%r WY%IWY%NY%Y%yY%Y%Y%Y%Y%Y%IY%@NY%mlgU Go$vH Rٛ7@@J Y%Y%Y%Y%D Y%Y%~Y%Y%Y%Y%VY%Y%TY%Y%G Y%Y%Y%Y%oY% Y%aY%r$ 2^^E5Pv_:>=$>m]You got the Assault Rifle.]AssaultRiflePickup  $?Y%Y%jNY%HY%Jx$C)N a3wJ63}- =13}- =1mDUh3}h3}3}3}qYԈqYAAp"t"{$gKY%oY%- ?]AssaultRifleFire$ #>K(;"p:HBHBHBs:@F@F@F$@,:???0:zDzDzD*$@$p}?[ F$HDf$ ף 'J3$C:$@K i :h :/$>Y%Y%Y%!{$~ 2zK!G wL"~ ]('You got a box of grenades and bullets.]AssaultAmmoPickup  q$>A$HAY%Y%Y%Y%Y%Y%A~d:7  GY%Y%Y%Y%Y%C{j?{ ~`{b9?`b9?,d,`,?L>9?` @>9?{ GY% B|r5a GY%B/S-(a!m ? GY%D}h;: GY%GueE%Eu~a իb@Yw~*~ ծ~CYL?9:9:$BYY~ BB=~E G"Y%l%wl*l-( GY%EI?P9:9:$P-la l99-ff&?II@?G$I>G$G$a+a@ GY%^s I9:9:$9?}9?`bbm9:9:$?tsaL$a GY%FMd8r.IM*9:9:$ wM9?,9:9:$r*r*M j MT+,9Dt9?&la GY%QNogyo`y@l9D9?l&9?,Jlm9:9:$ey@Jy@Jjyab Ab Aa$a!\-k(am ( GY%RY%Y%HLbLFo$? GY%Y%Y%Ke aRX- X-'r.X*.X- 9:9:$r*r*X j X*+9Da o$^9:G%- >a,l+ff&?@e e G9=9:G& -(wl*l-(lo$ GY% UJr-kRY#iR333?a!o (?-m'aB(f-@ Ra!n ?-@ -k' GY%jY%Y%Mhpu =:h-.wl*l-(ff&? GY%OY%Y%QY%Y%RY%Y%YZ-9:9:$W*M wW***W* 9?pYa o*a 99Z6Za+Z6f GY%YS+&#j--m(a=( GY%T$<wY*Y-(3wo**o*a GY%Vb d.OLwb G_9?D__b   GY%Y%Y%[cd96ca/!z wc-m(a@( GY%W|G9a @@H(b*M wb***b* 9? a |o9?,a |o9?,a |o9?,9Pow*9:9:$a |9Po GY%\{m-m-m(a  L>o$- '-k(-(a!G?q!Gx  GY%BBa!\am ( GY%ZO bH#GO DO  GY%kIeGY%]]aNb] GY%pY%Y%Y%Y%imd 4p.%mwp*rp*,wpwp-Ap g`-'a `1wm<ma/!zma/!Hm- `11wmm-a`m GY%_XDXd D 9?, T9:9:$]\CXy%y,w6w9D9?}9?>6w9D9?}9?>6w9D9?}9?>Oa I !Y%D wyNa GY%jYa} ^bY[G - G --@'a*G [r*  GY%vb^ #9:9:$a$Yvdl@,`du9:9:$e`djda 9Pv- (ab Ab A-'u9Pv6ua+uo$-k(a q!e GY%QdGG Y%Y%Y%nGc,- H(a a Cw*aZwh *h a GY%A)`?62/9:9:$9:9:$b99 GY%h a*a!G?L9:9:$996f9:9:$l,9:9:$+9:9:$--($ GY%^Y%Y%rpC:/r*r*<.t.Cw.*www!w%@!w&@"w,@"w,@B ^ ` 6^6^a  6aY*^dY*b` fffv a  6a,^a9?%Yw.*.-.Vw.*r. $$w.* ` 9?%5Y*C  9?,H+ao+F+#B($wH+*6F+333?v B  GY%sX i&y.X .ry* ry dX r.y*G4NyB .yI-9?,9?,.yv GY%s+tvF=w.*P $iB GY%_uqac8aqrw.*6q333?A C  v `9:9:$Zw.*.-.Zw.*r. B GY%vrHtr.qwr* -R r*r*r-(rZ GY%p+wB q!Y% GY%Jumu.dwu*u*u*u-(uZ8 GY%z '%wP*P-( GY%xc*9:9:$c*M wc***c* 9?|Pa  9:9:$99PF-[ (--w'? GY%y`7[$!9:9:$az (-X' GY%z@D#? GY%{jbEMaj* GY%Y%Y%|YdJURY-wY-[ DM M Y  GY%di|&ri GY%p+qqpN$G"Y%~_aU~4w.C*w.C*D_ P-Xaz (-X'`__`s`pPG6%6 %79?,-(6 o$6%6%a+4wP*P-({m9:9:$ 9?,a$- (- '6%6 P{-9:9:$O ? H(f*M gwf***f* 9?pan 9P_O  GY%Y%Y%`Y%Y%BY%Y%[&aDk aa  @eH(a a9P#?a a9P^a GY%_cpGcq!q GY%Y%Y%GY%Y%HY%Y%/ w/*/a GY%JhPG99h6ha+h GY%NZ+ - wj*wj*>r*1rj S ZT j GY%KZ*XUD%%w/*/i!9?^D% $( GY%Qyw 9:9:$ 1Ja>( |r}*}a  #@9P#?}a*wP*Pa GY%Mm*`:V;EW9:9:$9:9:$/a w/* w*[9:9:$/ E!=m* m*9?,d/E!=m*9?9:9:$Z*9:9:$ j-9:9:$-($p*M rp** r*wp*-($ GY%Or D` WIH(3D%a r 9Pp Ia r 9Pp a a GY%RYdfn'rY9:9:$awY-~w.Y*r.Y*`'6`'`'9?, aY GY%UTb_aT* GY%PBdo rB "rB Ba/!G-.BlLt9D>9:9:$ouo@totaB Lu9?,9PuaBa/!iB-9:9:$Gr*r*B j B:+9D?9?DLDL#? GY%Y%Y%c&Tp[ GY% XE8" 9:9:$E}6E6Et6E]&6E]&6E6E6E]&,99E6E66E%6E%a+E-~(TaH a>( GY%Y%Y% YWJ0#S E GY%JLn *w.L*a GY%R Y%Y%ZY%Y%]C!                             GY%.v G/.  .  .  .  .  .  .  .  .  .  .  .  .  .  . &  G Y%_CCV  &  GY%bC&?: -                                         GY%R wR*Ra GY%f,(/- a!B 999:9:$Ra  9?,(Ra* GY%v: -                                         &  &  G Y%aud9u-'( GY%gC a &  GY%Y%Y%ctdA*'wtDr#? GY%hCn             GY%Wv&W  W  W  W  W  W  W & W &  G Y%fqDG q GY%sQ*C0Q*%7Q*,Q*~*Q*                   GY%Y%Y%impL GY%Y%Y%lobP9  GY%Y%Y%nqaU  GY%rY%Y%Y%Y%u~vR*%7R*,~R*~*R*~  ~  ~  ~  ~  ~  ~  ~  ~  ~ & ~ &  G Y%Y%Y% |t@m   GY%wY%Y%xY%Y%Y%Y%ozqk   G Y%Y% Y%yl p Jak+ l9?,d"@b?o$-'q!B GY% F- - ( GY%i+EBn-a ]>a?]>aL>]33>aL>]ff&?aL>]33S?aL>]?a @Y%GY%o+  GY%@Y%Y%AY%Y%BY%Y%CY%Y%Y%Y%i,B)[-'o$a(((a | !BOwR*Raa( GY%DQ|QwQ*G.QwG*wG*HG H@HM?M@HQ2|BM~|zMyxQQ GY%~*U )&a/!sa GY%HC$                   GY%KLvFL  L  L  L  L  L  L  L  L  L &  G Y%Y%Y%fY%Y% NI@   GY%MY%Y%B Y%Y% O - ( GY%UL)&a/!sa GY%QCVE       GY%WvSW  W  W  W &  G Y%SC$o& -                                   GY%_v A& -_  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _ & _ &  G Y%UC+E1 &  &  GY%VC  A9:9:$              v&   GY%Qv J Q  A9:Q9:$Q  Q  Q  Q  Q  Q  Q  v&Q  Q & Q & Q &  G Y%YCm           GY%J<wB *B -(3wC *C a GY%_vd{_  _  _  _  _  _ &  G Y%C j`;9:V%a='r&F*/a9 j9:jV9:VP Fjr%jF*%jFw%jF&jFP P ,109:9:$ ,-9:9:$-($|)M hw*r|) r|)*r|)**|) 9? -($ GY% \,A a  GY% AB a  GY%ZSbhDS GY%Y%Y%]X dm7 YVwX (X a/!iX -DQ999? GY%a^\p.a)9?9Da) GY%e- w*a GY%_P s *]Pb? GY%Y%Y%bY D{ a  @H(a Y c9?,9Pc]*M w]***]* 9?a Y c9?,9Pc Y a GY%fc-j GY%gvP\&w.*$r.K9? DL9?C69=,69=,69=,69=,9=,<a 9?9?DD]   ] L uCu] L uCu9?9Du,,69Cu69Cu69Cu69=,<a 9?9?DDr*O*?O*O*L*L*O*%L*!K!ML*9?%6O+9D9?M+M+!K!O+%-P+w*w*-P+'&&  G Y% h[E$d[r*Ca/!2$r.ja^ GY%i^7)#w*a/!2. . x.a+ @, GY%jj) !w.*$r.. x. w*a+.  GY% kL%  GY%md CL9:9:$Fa)K=N9Da)N9Da)v!C a)d T a)a)Ka)?-N'(bb-N'r]'*a/!O]'.. Z!!}bw]'*w]' *-N'(a)?bw.*.9?&N9Da)N9Da)a)9?Na)9?9Da)d T K GY%Y%Y%b(c g`-M& c &9:%r.*c w*BZ%G( GY%j os$($j #j #j %wo* woso sj 9?%k 9:o9:$ ssL?k ss?k k s9?,sa+9P GY% r{a1 {|-}a)a)N9Da) GY%C n.?C a=' GY%sxF~ xKya) GY%vP-u!C-N'(a)9?&N&w.*. @@.  GY%j,Y%Y%tY%Y%zuJ' GY%Y%Y%wY%Y%xY%Y%Byw}( GY%wU$)&w.*. G Y%{f;9:9:$u)a u)a*99a>(o GY%m,DLaAA GY%}I;2wu)*#-u)a2u)I" GY%~NVWwu)*u)a GY%nd^xrn "rn na/!G-.nluw9D>9:9:$p ~p @wp w~wan u~9?,9P~Nauuna/!in-Duun uw.+n*.+n"Dun u GY%<Y%Y%g(A\Z<.*r<*X<-w<* A<-Xr<<5w<*r<<< t<w*|tw.<*w<nraL>(@r(r*r%@*r&@+r,@+r,@@raL>(@r GY% DiXnU 969:i%<w*-R 'a*\.kr\* %8%o%h~%. %!( "x\ w.\*6x.\ w*C ra   կ#? =\ #x>\ 6x?6x6\ 9:9:$)6 6\ &6  9?6x9?, .( B x("p. GY%GN`' zqw*N.qwN*wN* N- gNX$ GY%s Y%Y%@aDwJ /9:9:$]aa$H(a -9:9:$a aa GY%Kg4s-K+--(n-K+r tw*|(s   s 9?,~a r~*C99 ~  ?s 9?,**(~~'l99   ?a=(('( GY%Y%Y%FJ+} c`r][(dL`wd*dJ%9?q'd GY%dY%Y%Pw Y(Kw `Hw.w *.w - ' GY%MY%Y%]Y%Y%Y%Y%IY L]vb Cta 9:9:$ H(Y aK P#B(wY *a  K 9P#aw$? HDNa GY%NB"x' GY%OY%Y% XQULt{O.<rO*rO*'O  9?9?& GY%OKK wKww*q!H GY%{Y%Y%SVHIGY%WCPrw*w- r*r. *q!Y% w ?b w"w 9?%. ]q!Y%  GY%Y%Y%ZT\%#{.*r{*I{d >r{*w{*<{ { 9?@33s?{dU=U=w.{*UL>M 6 6{ oM 9?8U=G {  G 9?{^ UU>@UG 9?Q9{^ =U GY%Y%Y%\YN$ GY%Y%Y%a[_R L> GY%{ ^y eQ6 -e6 Ee\eee GY%Y%Y%]z i}b?z   q\ <z Z 9P99\ Dz Z  GY%Y%Y%d`I ̾ GY%Y%Y%bCl*rO*Oa O!5O-% L%% GY%fce GY%Y%Y%heQ:a/!2.~Lq!Y%'( GY%Y%Y%igYwbTw.*y.T[q!eg GY%ji Z-i[i &i -(Xw.*.pfi  GY%kg [m_g &g -'\a/!2.qjg  GY%lvo^ .r.*-D ( fy.a $ (y.a $ (y...-D ( A%p)?p)?%%i9? D_9?CfRiiS_o@Ti|@UisPitQis 6H iq 6H _m 6F ik 6F _}9=,<a 9?9?CCCC[69=,$B9??o9??|Ja o@|@9? 9? oVi|W_XB9??o9??|Ja o@|@9? 9? \69=,p)9?&69C9?,p)F6$6$np)9?&69=,6$$s q Ja m k p)9? 9? p)-D ' G Y%p,f}E$@6L9=,6L9=,6L9=,6L9=,)6 -6 C$C9=9:C9:6C9=9:C9:6C9=9:C9:6)9:C,C9=,6LC6LC6LCfL GY%nQ2WLCw*w.*.~ GY%o* wO*Oa GY%P%  GY%qY%Y%rY%Y%sY%Y%tY%Y%Y%Y%[Y%uY%J `z-*w*!5 GY%wL o:6L !WL %? GY%Y%Y%xuc-J ?F ף<=J  GY%z|f!r'omw.*K a K >( GY%Y%Y%{Q0/09D9?0q=?O9D9?Oq=? GY%}R6`00OO GY%AyJQ:a/!2.~Lq!Y%'( GY%Y%Y%B@YD;w.*l. GY%CA Z<m_A &A -(\a/!2.pjA  GY%D|[m_|&|-'\a/!2.qj| GY%H(Evi8l.a $ (mml.a $ (l...H(-v (%v)?Rv)?%%^9? DS9?Cea^cbSgc^dd^B_^C`^e 6y ^^ 6y SZ 6x ^Y 6x S}9=,<a 9?9?DDj69=,$B9??g9??dJa g@d@9? 9? ge^dfSgB9??g9??dJa g@d@9? 9? k69=,v)9?&69C9?,v) 6$6$2v)9?&69=,H6$$e ^ Ja Z Y v)9? 9? v)-v ' G Y%Fu}?@6}9=,6}9=,6}9=,6}9=,)6 -t6 ;$;9=9:;9:6t;9=9:;9:6t;9=9:;9:6t)9:;,;9=,6};6};6};u} GY%GQ3ePGw*a/!2.~ GY%w-+ wu *u a GY%'_!1 ' GY%jY%TQh9w*? 09D9?0q=?O9D9?Oq=? GY%JR|R9w*? 00OO GY%D)-F?9?P F TGF . GY%L{ o6k:6{ !W{ %? GY%IY%M`=-*w*!D GY%O~ EDFr.* r*#r~ *F qr~ *g+~ F GY%Y%Y%PnRI'r*F *J  GY%RjY GY%ScZ GY%T8[ GY%Uh\ GY%QYQN2$ GY%Y%Y%JlX[*C  GY%Y%Y%[`U| GY%[]th ' GY%Y%Y%\Bm E*n GY%^Hs/ Eq  GY%F _ax .*[*Toq!V GY%[fV,GY%B. ~ GY%bH F%Cr*P $-f~~~r*P $-f~ GY%cbV [b*[oT9-q!J *T*T[ojb*q!D jb* GY%Y%Y%G dG  q!J GY%akDGY%Bnl=Ett al9?P F  GY%G hG q!J GY%iHZEq ft $a l GY%jJ V@J jJ *=-q!J  GY%d sYg$-x(d Y GY%grJjGY%B~ GY%nH6F%Cr*P $-f~~~r*P $-f~ GY%o\V[\*[oTq**[j\*q!U j\* GY%Y%Y%F paM q!V GY%Es,q\  GY%z%` nM 9:9:$*Jw*!5 GY%t^ <*neQw. *w. Y*9P. Y ^ ^ P GY%kY%Y%d ]A <9-x-x(9w*rg% GY%Y%Y%Y%Y%@Y%Y%EInZG-Nr.*r* -N(D YIY"K. GY%yY%Y%Y%Y%A}\ N2?%.N%a GY%Y%Y%] B&k D =K99l _k k KeKl  GY%C_ L GY%Y%Y%EBI L? GY%_&J_#1(AC afbEJ'wA* wAC A-A&+Offv { b#w.A* fJ|_fEv } .A fEb#SJ} fb% GY%Gzr C%-a!i @@&-z GY%p Y%Y% ~,sl '&- L%%(I99 p  s#AtIIp ps %J%9?s '( GY%Iqp#)M.t& Uq GY% JA F{3aL$.t& UA pA  GY% LN msqB(ro qA``o-ro x  rf plL l%hL&,N hh9Dqka,L 99 N hh?Ow*w*w*hL&hJ&9?hFhpJ&9?h,Fh, GY%MY%Y%OK\ +M.*rM*VM- My AM-wM *AwM*,233>>rM*|M  AMd |9?,d=|9?M9?,Ma/!@  w.\M*C|9?&?@?|9?=w |9?,x>?B|9?& GY%ODW S;-kw*$&`a P W Y `aP W Y W%`*`HZX GY%eY%Y%PNNwq B.=rB*rB*$fB- By $eB  e9?,$wBB0Bb e9?,$$ GY% Q[XfUJG9:[%%8%o%h~% GY%@-qUt9:9:$q.twq*q-wq *qZ q*wq*wq*w( GY%Y%Y%RY%Y% USR>' GY%VcY6QKcTHw.c*.c- ' GY%W%_ v&+vh ?B%hB,^wB*B q_ B'_  G Y% LL GY%\Y%Y%[XN(\.=r\*r\*$}>\c 9:9:$$$ GY%DY%Y%^Z\m#uD.@rD*rD*w*' #D \ ==o D  Qo LyQ9?hereQ9?,C,2,D,LL=Qo:[6 6D [9?,xL> [9?`L33>  [9?LL=lwD*"D-Q9? L>L GY%] UrD) -h)  =h) x]| z |.|-D d 6h)z F9?% -d 6h)]Cd 6h)]ի?6h)z d  M6h)]ի6h)| 6h)z _]]U^eK%'-S(]99H Lr^]-aHeLr'yw-*w- K%--a/!G/.- lHG9D9?0>-S'vvw-p ]--G9D9?0O0Bw.-*d*.-l!H]?wd**d*1+9D9?GIHf]BZw.-* _]$.-M"H]?-1+9D9?GIHf]BZ+_]GN-&+GHf]{ vHH@eHLerLr* [.a] d9Pew[*[ Hw.k#-* T_]wHe@Tw-*--p --S K,rHH 9P]@G]G_%_rwH 9P]R^Jdw GY%PY%Y%`]IWw!P  lP9?cP9?i333P9?@?̽ GY%] C?-pN  GY%a_TCa>Oa)\= $ (RocketLauncherLoada)\>Q $ (RocketLauncherPlungeraz>q!Y% @Y%GY%b@Y1`}e ('o[ &?!Q  ,?!V !a"%?@ GY%A-M, -{' GY%dx [W1 w.Gx *e (#5x %w)&<w)%#w)-%w)w)9?%e '!-pppNo RL reg fire because other firing 9Tw)- next fire 9Uw) x  G Y%eQ*a!IL?&a!IL?, GY%fDNmIDG<@9?,BIOIO-p(6u 9DI!au %? GY%gO~DOG9?,9OGOGIG-p' GY%hFrIFF%9:9:$MF9:9:$ BL GY%iHL)-Hq!T!@ GY%jK8-Kq!T!@ GY% lMMa> GY%QY%Y%mW(-k'N.SwN*N9?,9?, ?wN*rNNIN N 9?9?&N>&N ?-V'_N-V w_*Pa D WVPo_wN*-V(_*PQa  WVQ GY%omvx -Vm^6m9=,m$mB9?m?U 9?m?V mJa U @V @9? 9? m G Y%bY%Y%]PRo b.PDrb* rbb-(c-'w*'y b(rb*1wb GY%zY%Y%r 2.95Y% 3Y%sY%Y%vs\5s.*rs*>Bsd ?rs*s-3s  9?` > GY%Y%Y%xuN.$ GY%Y%Y%zw_&]  GY%Y%Y%|yI!  GY%Y%Y% }{sk<!r*B Z G Y%E-|Z69:9:$t|3|%g9=| G Y%UQ  GY%Y%Y% BU/' GY%Y%Y% DA[* @ GY%Y%Y%HC_%x @ GY%gY%Y%Y%Y%>{zO\  q{6c|6c}6c GY%JFI ;  GY%Y%Y%NIN$ GY%Y%Y% 8Y%sY%Y%PM\+s.*rs*sd OwaG+m+s #Ds (*fG+wef(*rs*26 6s s^ fs s#@uwef(*@r.s*= GY%Y% Y%RMeWwd*d/a9 d)0d10da #Dd GY%Y%Y%ZQBdw%* L%& GY%Y%Y%UY%Y%VY%Y%WrY%XrY%YrY%ErY%\SD:a/!2.~ GY%Y%Y%][YM?a/!2R.[ GY%^RZm_R&R-(\a/!2.pjR GY%_T[Km_T&T-'\a/!2.qjT GY%ev\P>R.a $ (ssR.a $ (R...- (m.W%m-m-j&mI>i)?mImji)?i)i)`9? DU9?Cgv`hqUjp`ko`T 6| `U 6| UV 6} `W 6} U}9=,<a 9?9?DD$<a gh9? 9? "9?g>a gh9? 9? 49?g9?h@a gh9? 9? "9?h>a gh9? 9? i69=,$B9??j9??kJa j@k@9? 9? jn`kmUlB9??j9??kJa j@k@9? 9? h69=,i)9?&69C9?,i)6$6$Bi)9?&69=,X6$$T U Ja V W i)9? 9? i)- ' G Y%x5{f G9?,a Gb P.m`GEvK ?b 9?, GY%E)bf+r'omw.*Y a Y >( GY%Y%Y%a`::-*w*!~ GY%>G)](f: N=a @ ]E Ew=*xC yzo C  w.*=G=Ev==EG=o == =99E == GY%f\}3[@6w9=,6w9=,6w9=,6w9=,)6 -Z6 ?$?9=9:?9:6Z?9=9:?9:6Z?9=9:?9:6Z)9:?,?9=,6w?6w?6w?\w GY%p%Q' LCw*w.*.~ GY%=Y%Y%lbVGb%Db,:wb*bq!Ub GY%Y%Y%okKV GY%dV{p jq!U GY%m}jqpxc Q}a FQpQp-i 'xQxxG6k 9DxP!l k %B-i  GY%r|WV| GY%k Y%Y%nY%Y%sj gt:.Q%t.Q&t(-nj j-nj a-n GY%vDj9:9:$ ~FJ AADJ AAG6c9DA!bc%N 6c9DL9?6cO!L c%N  GY%Y%Y%nrN )a r r,r%a  GY%tr' GY%a Y%Y%Y%Y%uj GY%yc GY%z8 GY%{h GY%|~UeGY%` GAw 6` !z` %?c xf Pa9:9:$r*a$ D (q!c GY%FxE7R[w.* .- GY%}Bc#GY%BR K ( GY%A q!w GY%@EwGY%BeC59:9:$a$ D ( GY%DEV-C+wq!U@@jEq!U GY%O_ l r8* E Aw.*8a %8_ &8_ 8 { GY%CQ.vv?`GEv GY%GR'vv`GEv GY%JfW' GY%Y%Y%IF(u F(.mF(-g'. h mwg'*g'zw.*[,rr*.x GY%rK[ i"E9:9:$ :r* [ .ir[ * .e-R'r GY%\ Y%Y%>LF(6 O.O.e[zO99GO_ Fz.e[** GY%RMNJ P.=rP*rP*$W%-$nn&-$\ P  \ 9?$$ GY%G*Y%Y%OY%Y%UP\ho G*.*rG**rG**wG**<G* G* 9?@?G*^ >.? GY%XY%Y%SY%Y%VIwGdiX9:NRX%i$i$ti$i$-I'- XthX9:9:$(XgX' GY%Z4I'w8*8a8* GY%RY%V` 41r*P $ GY%XJqS3%w*a+ J GY% v%^*Id.r*[B *L GY%Yw*' L%q!O GY%[]y! D GY%Y%Y%\_f&( L% |% GY%Y%Y%^c+,."a!T?V9?}= GY%`80^ GY%aeOVGY%B8 W|%R V' $BioRiflePowerUp GY%cA1! L%|J?|} L%R ( HB$2 GY%dHO5w*r *fBioRiflePowerUp GY%>bK(\}q!Y%|%*Da % KZzwD*DD j|Dy|% L%^D GY%Ab!9:9:$ 8a _w8*8 {8!q GY%FaY%DY%Y%haY%fQo N9w*? VV@? GY%kRv G9w*? VV GY%dqY3%w*a+ d GY%Y%Y%mpy D GY%Y%Y%`L41r*P $ GY%`I-*w*!5 GY% xnsg&..&w* w* %-B-B'N-BLinkGunBeam1 %-B-B(fBLinkGunBeam1 G Y%@Y%Y%B eq 30w*a+ e GY%Y%Y%>F-@ (@ 99  A9?. @a z @  w@*@D. @Z@ GY%{vY]e% %v GY%Y%Y%@Y%Y%yV$(.&E* % GY%wo%\Sw*=. %% S%  GY%|| 1Y;'. %B 2 GY%}8:;'. %B 2 GY%S-h~O$7h4w.\ *.\ b  GY%i*Y%Y%_-BJ4x J-\w.& *r..& *']B%-i*'mw*w*w*o)mwo)*Vwo)* w.o)*(.o)z .o) B@-i*o)o)B@-i* GY%sY%Y%Y%Y%ju(2a K ur br2*2!a K  r w2*2&2ak.k$>wk*X kkO akkk `22 2992 2 2 2l ka (]CC \PG -(G* GY%HC_C ̾ GY%Y%Y%2Y%Y%NFI L? GY%o Y%Y%hI GY%J` m-*w*!5 GY%K8.8' GY%>Lw(Md .(wxDwd *d d  GY%QIN@.'r@*$fw.@*1@s@S br@*w.@*(@s@S O@ @ &y(r@*@^ $Yr@@$g)@ f @rg)*g).@rg)@$wg)*8 g) .&E!9?g)g)g)9?%@bg)$r@*$o @   o .&E$$ GY%pY%Y%d Y%Y%SO\J#p.*rp*w.p*$wp*2w.p*?y)p f pdwy)*? y) ?.&E!9?y)y)y)9?%?w.p*rp*H p ?.&E-.pspS ?q).pwq)*rp*q)spS q) q) ? q) ̌?.&Epbq)?.? GY%KY%Y% W~YPK.&rK*(qw.K*XK~)K f Kw~)*X~)-~9?XX~)9?%&rK*~)- QrX*XKQrX*(-~1rX*X`(w.X*gw.X*L99K  X fff?f   qX f .&Ef azyX f 'rf XKf '( GY%t Y%Y%A&h GY%\Bgr 9:9:$w.* w.*t . L wt *V&99 Ut wU*r.U *wU* w.U*#UY'8V&U  fff?UU r UU B GY%Uc.L( GY%X8 2b?!T(!|.89?j*^ GY%Yu+V.-{%w.* ff&?|$i$.-{( GY%rZgiDc(9:9:$ 9?,r b?x~ A B }   qg} ~ 6cB 6c|ggA 6cI aO Ng} (,wI *gO P <gZ&9D(%(ZJ g9?,կ9?(,I@9?j*9?,9?,A կ9?(,I@9?j*9?,9?,B ~ 9?,(n.(J P (Y'Z, NC9:N%N$(%`(ZVw(n*(n-H -| (nVN@ %\%\Z (\w\n*@ (nF\n@ \-| -| V9:9:$(n a='(J GY%p&d B99:9:$9w.&*.&E* GY%Y%Y%`]_Zb ̾ GY%Y%Y%b_IROFw.*#.9?,>L? GY%TY%Y%daN;6`.=r`*r`*$T`  STS9?6TS$$0w`*"`-$0!S9?6T9?,$00ff&?$$ GY%cY%Y%c\Tc.*rc*wc*r.c*3c  9?fff? rc*wc*<c c 9? L>E c  ZE Z9?Z9?}Z9? L>>6E Z>&wc*"c-33>&&Z9?L>L>Z9?Q:L> GY%Y%Y%geBg$L%&&- GY%iXr]LH%N UQ:N !Ta!O?=EX GY%[Y%Y%kh_N[.@r[*r[*{[  9?@ GY%]Y%Y%pjI>].@r]*r]*> ]   9?? 9?>̾ GY%[[Vi F9? L --([? [.L(Z?@@? GY%Y%Y%l`c-*w*!5 GY%>n\(6Mu .(\cDwu *u u  GY%smN4WL?$$ GY%kY%Y%u Y%Y%[%q\gk.*rk*rk*wk*<k k 9? L>y k  ay a9?=kb >^wk*"k-33>9?6y a=a9?33> GY%`N-*w*!5 GY%>td(,li>dhcw. * wi*. n.+ii GY%FY%Y% |q DF.%8%o%h~%-R'FE_  q ( BFF g'w.q *.q -(S*' GY%iY%Y%nY%Y%yY%Y%zY%Y%}{wn.d.|d- rn* rS*d-((lS n*w.S*llի?ln n.S n.Sr.S*)6S 6n llS#?Ddl GY% @DQUSD GY%Y%Y%~Y%Y% NR' GY%z8 B?.-Q+aF GY%CE<  GY%FY%Y%GY%Y%Y%Y%DIf".a)? GY%Y%Y%>Ha ("r.*r*r*r*Ca  a _ %Ca s a _ Ca Q a _ .Caz$ (.j.Jw*w.*.  .a.*a@$ (C GY%b Y%Y% Qv XRu/w.*v Kpw*b  Xt pwb *v t b * GY%CY%Y%Y%Y%B%PB2)$w.*'( GY%MTf' GY%Y%Y%SwiP9:9:$r*r* W *} MI@9?,z 99 U /a7 w[ rwrw*1ww1T w  K T z N T oK } 1N [ 1p?N [ pK pU U pW w10.e fW  GY%WNC>9:9:$ r*r* r*tL?r(r*rxtrD* t?wwbw[*f* ` ew[*@r[**[  9?pf*t`N GY%XR`{& *rw*9?LnRL9?&9D9D9?LL9?9DL'ww*.g  GY%Zy fg yYw[* w[y w.[*.[ }[y r[**[.w.* wy *. C.. }vw[*w.[*.[ C GY%Y%Y%\Y[P`7-Rr*-R([r*( GY%Y%Y% ^TtS1r~ . T~  GY%Y%Y% _WrK1rE . WE  GY%p(G Y?TmD[G a/!ZG %-'%-' GY% Y%ZZ+`Z GY% R^ GY%Y%Y%eb\2?&.Y&` GY%I*Y%Y%}(dNI*.}wI**wI**}=I*^ L&&$L%%$$ GY%(MW& J-H'(.Y&VMGwy&*y&ay&* GY% ~(}ZH#`}z4?} GY%I)`|}9:9:$ w*w*wwx GY%Y%Y%iY%Y%jkT( GY%Y%Y%XF%X  G Y%Y%Y%pA F%A &A  G Y%e^L r.^* .^V e%^**E.^wE*E E ,w.^*.^ i !@ $ G Y%u^LGyJ.^vwJ*J vJ ,w.^*.^ i !A $ G Y%Y%Y%f%969:9:$6w*a GY%U-ZVL^--g' 6.6 %稨warning:9Vlinkgun had9S6 links6 %w 6 ,yEB!6(E 9:9:$E Z6xEx{,zEx{EE9?6 ,9:9:$r*/ a9 ``-w`*r``10w* r w *E?F9:9:$J-j6J9?.Fw* w.*$w* @qw*@P $-: ,E<aSi  ,'rxw E#a+9P ,E ,r-x'FFr-x'w *P   #?9:9:$e P,e EU % -P,?EE*r *w.*g-g<,-g(R666 }`EZ&6F669D}#6F666FF<,69D}6F666FF<,666 RF<,666 :r*_9P ,i_9P ,6_6666 _C!,E99_P,EEaSi P,'8 w* wYSC YPb w* JY 9:9:$ w6* 6-\\w*w*0&sh r*$%.\ 6N $ .\ 6N $  6 %.\ 6N $ .\ 6N $ m w* wC @* w E.@ w *xKm s w *g xE*s xZm -j w*-k(b?s9DD!69?gm -e -w.*w.*6r.s%{&. r{&*{&." w{&*{&sS E*-{*' {&u sO6J9?Q &+sSSEOm w*-k'A'. 6wA'*-js9D9?g?9?6 9?& {!s9?,6A'u sO6J9?.-\w *-{*y-xGBr*- aY(9:U*9:n*U*9=9:n*&U*n*Bw*,6-\\w*w*0&s'9=&)w6* r*$%.\ 6N $).\ 6N $'$w6*6 %.\ 6N $.\ 6N $t9=6 9:t,q+U*r -Aw* JYKG-I (-j( GY%hgF%g  G Y%Y%Y%mF%m  G Y%Y%Y%vF%v  G Y%QFD%Q (V(%&Q AAL?&Q  G Y%Y%Y%|F%|  G Y%Y%Y%F%  G Y%DHL yZ.HvwZ*Z vZ ,w.H*.H i !g$ G Y%Jxi-Jw.x*-Iw.x*iwr *ar x x .x-'xa GY%BX  G Y%MXZM GY%DXQH9:9:$Brn*na n!5s G Y%n wn*na GY%F~ X9:9:$ 9:%>9:%sgr~*~aU~!5w~*~6~ !W~ %? G Y%L)g w~*~a GY%HWI:(%w:*:IW-V GY%OX'vm9:9:$ 9:%m9:%^r}*}a }!5}| G Y%[-JRw.666Y66'66'( GY%Y%Y%X)is0-j'E = GY%K80WN. % LBLinkGunBeam1 GY%LGw1*Kw*a*E*-I '-A(. %fBLinkGunBeam1 GY%MZE2Ow * w*H&. .-\( Zw *K&. -A'.-\' a[$ GY%QMXMr*r*$&:a EM%:a EM:a AM:a*M GY%NH K5w * -A,r M (m h wm*..mP $KH M .m H (' GY%} 7w:*:a.w}*}a GY%TJ XA9:9:$ 9:%\rH*Ha`\wH*H!5wH*H6J !WJ %? G Y%mY%Y%` wH*Ha GY%PS HT7w * -Aw T q h wq*..qP $HS T .q S  GY%WR X9:9:$ 9:%9:%@r*w*{*6R !rR %? G Y% w*a GY%Z\ X9:9:$ 9:%9:%@rJ*wJ*J{*6\ !s\ %? G Y%Ua@R9aa/!za-d.ard*da/!Iw.d*dsS (X.d].XP $w]*w] *w] d f , 6r] (X.] frX*].XP $f -!dS S ( GY%J wJ*Ja GY%dY%Y%bC*jb GY%^\PIGY%_@*X>(9:9:$ r* 9:%@*M $9:s 9:s _@*M $r@**@* 9?9:%a aT 9Pa 9PE%_L>w@* s9:%M*e+hG@@M*c+hG-9:9:$M*@O'Nrh*ha` h!52wh*hH!&rK*9:9:$-KavwK*K!qwK*Kq!Y% G Y% akVaD 9?&ikg GY%Ymz!=:  qm GY%iJ*NaC9:9:$ 4r)*)aew)*i M*J*G)a J*UJ*`+u'a*99 }a*J*U_+r)a*U+66%)6r)66%)6r)66%)6r)66%)6r)66%)6r)66%)6r)6%)UU+6%)6%))H!&i q!Pu' GY%cY%Y%dY%Y%Y%Y%`Q&=h9w*? g9D9?gq=?g9D9?gq=? GY%eR/D>R9w*? gggg GY%vY%Y%OY%Y%jgGMv.^wv*vuwv*v \{wh*h  GY%knO=Uk t 8-nt Rk L>h GY%lqj-fhO(h AqhAAG6l 9DA!bl %? GY%` BNw)*)a.wh*haEwK*Ka GY%u'uY%o^ XC[0'9:9:$ 9:%'9:%dr4*4a 4!5^ 'w4*%4%4b, y9?&&4%4b%N $N $4{*6^ !s^ %? G Y%e,9 w4*4a GY%qX XO9:9:$ 9:%sWro*oa\o!5wo*6X !WX %?o G Y%\ wo*oa GY%uI X9:9:$ 9:%brG*Ga G-(G!5wG*6I !WI %?G G Y%tNY%F NY%Gv wG*Ga GY%wX  G Y%SXYS GY%M)cXjf 9:9:$&?Cw}&*}&&?G9:%s9:n 9:n _V*M w*rV**V* 9?a aT 9PE%hD-c' w}&*}&h9:& 9:%srJ*Jao J!~J6c!zc%? G Y%]-N VGY%q <(kw.**[-H r .R f9P q hw.*-v*.-.-(t*8<q Cbw.*.--v*t* GY% N)FVN#+KFN GY%N,T-c'Tw* %!| %kwK*KawJ*Ja GY%v*Y%Y%{BAyk9:9:$;rB*Ba A-r'-j(IR >'F  GY%R -O' GY%@ B V`* -GxRuoT  qRL <TR99L MT_RMaSkMT(wM* wM-O-j(M-cSrHBb@@`I>-]Ijr#*#.ReS-]w#* #eS-]j#`*.RR?xKwB*B]$fE PG-j'-Z-Z'E `I-j(-Z(`w.*r. .#@-H'IrS-j(-Z(I-j(-Z(-O(iSiM.R @ iHwB*B Wi7-jB]$HB]$~w#*[-jXr#3*#3a  r#3a>#AB@w*w*w*#3 9=#3k~~w#3*#d GY%TY%Y%D M|l4MwM*V.MwV*wV*WV WP@WPX?XP@WPM2|`XgmpXqvMM GY% J B2O-'-p 'o$a(((a Fwy*ya| GY%Y%Y%E Y%Y%F Y%Y%G Y%Y%H Y%Y% K I +2 GY% L I2 GY%YX b32 GY%A G\.-Z($wB*B]$q!Y% GY%M H"-H(R (fF  GY%zi GY%O w q!V GY%P Q GY%Q R GY%Y)fz:  qf GY%Y%Y%V Y%Y%W Y%Y%Y%Y%^Z T 2 GY%Y%Y%V[ Y |1 GY%`1 GY%d C B"79a ]IP>RSa?]IP>RSaL>]IP33>RSaL>k]IPff&?RSaL>]IP33S?RSaL>]IP?RSa @Y%G i(Y%c-Di D.Da~+|wD*wD:*D:-(R H' GY%Y%Y%^ 8$j3ShieldNoiseR H'a!@  GY%` CG-,C.D*wC*wC:*C:-'fShieldNoiseR H' GY%_ Cv/L-n w.*-n '.FlakCannonAltFire{r&*&% r*r&*& C&  GY%a `U<)wI*I D`I' GY%O,b GT1GY%c QF_ GY%e RJ GY%Z)YIU9?L&:FD FD [wI*I I9Dl.Dwl*lI9D-Y GY%Y%Y%h Y%Y%i Y%Y%g l qbl 2rI*I a @-L&%Ia  \Ia+ }l aI(( GY%p j \ U.  GY%k qP N-F?p &k&&KR ( J&?9:9:$MGFHI( GY%Y%Y%n Y%Y% q o R Q- G Y%r ] vs- 6 ?6 ?6 ?6 ? 9=,   9=,9=,9=,-p  <a 9? 9? DD__  `)   _an)?9? ?9? D9?&`)`)9?D "?9?  Qan)?9? ?9? D`)D "?9?  _an)?9? ?9? D9?&`)D`)9? 4?9? ?9?  Qan)?9? ?9? DD`)  _ak)?9? ?9? D9?&`)`)9?D "?9?  Qak)?9? ?9? D`)D "?9?  _ak)?9? ?9? D9?&`)D`)9? 4?9? ?9?  Qak)?9? ?9? DD`) 2?9?   Cah*9? 9? D`)D `D`)9?&9?9? 9?`)9? CD Ma)9? 9?,`)9? ,CC zD`)9?&9?9?,9?,9? 9?`)9? CD Ma)9? 9?,`)9? ,CC_`)   ]an)?9? ?9? D9?&`)DD`) "?9?  ]an)?9? ?9? DD9?&`)īD`) "?9?  Qan)?9? ?9? DD`) 4?9? ?9?  Qan)?9? ?9? DDī`)  ]ak)?9? ?9? D9?&`)DD`) "?9?  ]ak)?9? ?9? DD9?&`)īD`) "?9?  Qak)?9? ?9? DD`) 4?9? ?9?  Qak)?9? ?9? DDī`) 2?9?   Cah*9? 9? DD`) `9? CDD`)9?&9?9? 9?`) Ma)9? ,9? 9?,`)CC v9? ,,D`)9?&9?9? 9?`) Ma)9? ,9? 9?,`)CC s- GY%u {  G"Y%Y%Y%s Y%Y%^t ] Q( GY%Y%Y%v Y%Y%w Y%Y%k,g +*heg %orE*rE* r*r*)Ey rE*v - rv  ew.*.w !F!$'&w.E*.Ew !F!$'a ka(((]9?g P>RSa GY%{ ui  u-  G"Y%A!_   GY%Y%Y%| Y%Y%d fq w*a GY%~ `"RA9:9:$a -'-e( GY% ` q-cew*  -a  \` a((w*a  \|a+ }a+ ` a((`r^ -* GY%D!} a  GY%@!_ <I} w.*x  w*W 9P _ 6x 6W x _ _ GY%Y%Y%G!C!b5  GY%x Y%Y%Y%Y%I!F!p GY%B!F i^t b?xD JE-m (wR&*S&>jR&F j R&*U [ <UQ Uc 99[ jaF MQ U'o sasash U o FU JX o GX *w*-'wj* wjGw.j*'w.j*.j-j7+9Dh F JD #?d j.-J@?+9Dx-Oh F իeJD d w.j*j7+9Dh F JD #?d R ( GY%L!Xf @ M ?9?,XM XOz?9?,XzXYa+9PZU V T;EQ6-9?Q9?@T9?Q9?T9?Q9?Tz9?9Dz%--9?Q9?@Tz9?9Dz%9?,M U zV |#_*9DXj+Oa+9?A*9?\+_*A*9DX9?_*A*A*S+S+e*6e*A*a+e*g*.h*awg**6g* 6q*..)wq**q*6Z+V+V+ GY%Y%Y%J!Y%Y%M!K!U   GY%N!`y a^w.*a+.q $? GY%O!C l uC 99C r9:9:$ya  9?,(C ya* GY%n,kS r* *a!X kw&*&% `&w&*&z   &* GY%Y%Y%S!@dF@-'( GY%Y%Y%T!R!b A( GY%Z!9&kwy*ya GY%H!wR A' GY%U!W!`--m  GY%Y%Y%V!Ib -C Q <CI Cc 99Q Ia{^I C')w.I* wI-m '-(*R&.IS&&w*-'_^ +faAw*-(Uf9?, 9?,%U&U%fp&fpUfAL>%U&U_-e-e'a r^ *R ( GY%Y%Y%x,Y!d 2#w*l  GY%Y%Y%TdJ]]$w.T*Qr.T R.T |r.T i.T 'XVw.T*z9VTxWeapons.PainterPickupOTxWeapons.SniperRiflePickupSQz9VTxWeapons.RedeemerPickupOTxWeapons.RocketLauncherPickupS'X'( GY%Y%Y%_!9d,<>-W HY$Ew.9*.9d9w.9*w9d.9-Y$'(9w.9*{9V9yO9y9w.9*{9V9{O9{979a/!}9q!g '( GY%J-YH -W 'vdv dy9VdY% Y,wYd*!wYd**wYd*{9VYd YV GY%j!Oi&tr.O* rq* Oa q qw.OT*.OT-( GY%X!b!z  GY%c!Y%Y%d!Y%Y%e!Y%Y%Y%Y%a!Q`9w*? @?aa@? GY%f!RR9w*? aa GY%[)j%a!O?a= GY%h!8-e(fa  GY%h 2/h !Y%/a0 qh ..10 GY%Wb//============================================================================= // ZoomSuperShockRifle //============================================================================= class ZoomSuperShockRifle extends SuperShockRifle HideDropDown CacheExempt; var(Gfx) float testX; var(Gfx) float testY; var(Gfx) float borderX; var(Gfx) float borderY; var(Gfx) float focusX; var(Gfx) float focusY; var(Gfx) float innerArrowsX; var(Gfx) float innerArrowsY; var(Gfx) Color ArrowColor; var(Gfx) Color TargetColor; var(Gfx) Color NoTargetColor; var(Gfx) Color FocusColor; var(Gfx) Color ChargeColor; var(Gfx) vector RechargeOrigin; var(Gfx) vector RechargeSize; var transient float LastFOV; var() bool zoomed; var() xEmitter chargeEmitter; simulated function PostBeginPlay() { Super.PostBeginPlay(); } simulated function bool WeaponCentered() { return ( zoomed || bSpectated || (Hand > 1) ); } simulated function Destroyed() { if (chargeEmitter != None) chargeEmitter.Destroy(); Super.Destroyed(); } simulated function ClientWeaponThrown() { if( Instigator != None && Instigator.Controller.IsA( 'PlayerController' ) ) PlayerController(Instigator.Controller).EndZoom(); Super.ClientWeaponThrown(); } // compensate for bright fog simulated function SetZoomBlendColor(Canvas c) { local Byte val; local Color clr; local Color fog; clr.R = 255; clr.G = 255; clr.B = 255; clr.A = 255; if( Instigator.Region.Zone.bDistanceFog ) { fog = Instigator.Region.Zone.DistanceFogColor; val = 0; val = Max( val, fog.R); val = Max( val, fog.G); val = Max( val, fog.B); if( val > 128 ) { val -= 128; clr.R -= val; clr.G -= val; clr.B -= val; } } c.DrawColor = clr; } simulated event RenderOverlays( Canvas Canvas ) { local float tileScaleX; local float tileScaleY; local float bX; local float bY; local float fX; local float fY; local float ChargeBar; local float tX; local float tY; local float barOrgX; local float barOrgY; local float barSizeX; local float barSizeY; if ( LastFOV > PlayerController(Instigator.Controller).DesiredFOV ) { PlaySound(Sound'WeaponSounds.LightningGun.LightningZoomIn', SLOT_Misc,,,,,false); } else if ( LastFOV < PlayerController(Instigator.Controller).DesiredFOV ) { PlaySound(Sound'WeaponSounds.LightningGun.LightningZoomOut', SLOT_Misc,,,,,false); } LastFOV = PlayerController(Instigator.Controller).DesiredFOV; if ( PlayerController(Instigator.Controller).DesiredFOV == PlayerController(Instigator.Controller).DefaultFOV ) { Super.RenderOverlays(Canvas); zoomed=false; } else { if ( FireMode[0].NextFireTime <= Level.TimeSeconds ) { ChargeBar = 1.0; } else { ChargeBar = 1.0 - ((FireMode[0].NextFireTime-Level.TimeSeconds) / FireMode[0].FireRate); } tileScaleX = Canvas.SizeX / 640.0f; tileScaleY = Canvas.SizeY / 480.0f; bX = borderX * tileScaleX; bY = borderY * tileScaleY; fX = focusX * tileScaleX; fY = focusY * tileScaleX; tX = testX * tileScaleX; tY = testY * tileScaleX; barOrgX = RechargeOrigin.X * tileScaleX; barOrgY = RechargeOrigin.Y * tileScaleY; barSizeX = RechargeSize.X * tileScaleX; barSizeY = RechargeSize.Y * tileScaleY; SetZoomBlendColor(Canvas); Canvas.Style = 255; Canvas.SetPos(0,0); Canvas.DrawTile( Material'ZoomFB', Canvas.SizeX, Canvas.SizeY, 0.0, 0.0, 512, 512 ); // !! hardcoded size Canvas.DrawColor = FocusColor; Canvas.DrawColor.A = 255; // 255 was the original -asp. WTF??!?!?! Canvas.Style = ERenderStyle.STY_Alpha; Canvas.SetPos((Canvas.SizeX*0.5)-fX,(Canvas.SizeY*0.5)-fY); Canvas.DrawTile( Texture'SniperFocus', fX*2.0, fY*2.0, 0.0, 0.0, Texture'SniperFocus'.USize, Texture'SniperFocus'.VSize ); fX = innerArrowsX * tileScaleX; fY = innerArrowsY * tileScaleY; Canvas.DrawColor = ArrowColor; Canvas.SetPos((Canvas.SizeX*0.5)-fX,(Canvas.SizeY*0.5)-fY); Canvas.DrawTile( Texture'SniperArrows', fX*2.0, fY*2.0, 0.0, 0.0, Texture'SniperArrows'.USize, Texture'SniperArrows'.VSize ); // Draw the Charging meter -AsP Canvas.DrawColor = ChargeColor; Canvas.DrawColor.A = 255; if(ChargeBar <1) Canvas.DrawColor.R = 255*ChargeBar; else { Canvas.DrawColor.R = 0; Canvas.DrawColor.B = 0; } if(ChargeBar == 1) Canvas.DrawColor.G = 255; else Canvas.DrawColor.G = 0; Canvas.Style = ERenderStyle.STY_Alpha; Canvas.SetPos( barOrgX, barOrgY ); Canvas.DrawTile(Texture'Engine.WhiteTexture',barSizeX,barSizeY*ChargeBar, 0.0, 0.0,Texture'Engine.WhiteTexture'.USize,Texture'Engine.WhiteTexture'.VSize*ChargeBar); zoomed = true; } } simulated function ClientStartFire(int mode) { if (mode == 1) { FireMode[mode].bIsFiring = true; if( Instigator.Controller.IsA( 'PlayerController' ) ) PlayerController(Instigator.Controller).ToggleZoom(); } else { Super.ClientStartFire(mode); } } simulated function ClientStopFire(int mode) { if (mode == 1) { FireMode[mode].bIsFiring = false; if( Instigator.Controller.IsA( 'PlayerController' ) ) PlayerController(Instigator.Controller).StopZoom(); } else { Super.ClientStopFire(mode); } } simulated function BringUp(optional Weapon PrevWeapon) { if ( PlayerController(Instigator.Controller) != None ) LastFOV = PlayerController(Instigator.Controller).DesiredFOV; Super.BringUp(); } simulated function bool PutDown() { if( Instigator.Controller.IsA( 'PlayerController' ) ) PlayerController(Instigator.Controller).EndZoom(); if ( Super.PutDown() ) { GotoState(''); return true; } return false; } simulated function IncrementFlashCount(int Mode) { if ( Mode == 1 ) return; Super.IncrementFlashCount(Mode); } Sk!q,W6Ol!kSy h,eh uhh uKih,eh uKih,eh uh uh uh uh uh uKi3}Ki3}KiҽҽҽҽҽҽҽҽҽҽҽҽҽҽډډҽҽҽҽҽډډҽҽҽҽҽҽҽҽҽҽډډhZehZeҽh,eh uB4m$Bl$Bn$pBs$pBt$Cx$By$(B{$(B}*j*i**~ZGA*D:DCF: A4 E& _ cY%Y%] 8 52.-Q+a GY%m!o!fn-c.a)?-c9:9:$w.*w.*. ] -c GY%cY%Y%L class UTWeaponPickup extends WeaponPickup; var(WeaponPickup) vector StandUp; // rotation change used by WeaponLocker var(WeaponPickup) float LockerOffset; simulated event ClientTrigger() { bHidden = true; if ( EffectIsRelevant(Location, false) && !Level.GetLocalPlayerController().BeyondViewDistance(Location, CullDistance) ) spawn(class'WeaponFadeEffect',self); } function RespawnEffect() { spawn(class'PlayerSpawnEffect'); } State FadeOut { function Tick(float DeltaTime) { disable('Tick'); } function BeginState() { bHidden = true; LifeSpan = 1.0; bClientTrigger = !bClientTrigger; if ( Level.NetMode != NM_DedicatedServer ) ClientTrigger(); } } Y%\&\\Y r*r.* \.\J.%D translocate_gib-k' a\ 9:\9:$a#?a#?H !aWXa\ 'WwH *a\ \a(((w*w? N  GwG*wG*wG^aG \*6^6^\*G9?,7^G9?,JGy FG.-Q '\*?G})a6})333?G})aի?G^ b$})aa})GGp-Q }a\.PW.|wW*W j N b 6bbbb6b6  b;w*R kR ^?(p((- w.*6 6 6  #o$mw.*. h!w.*. ] \a.*.j GY%jclass UTAmmoPickup extends Ammo; function RespawnEffect() { spawn(class'PlayerSpawnEffect'); } Y%`lclass TransRecall extends WeaponFire; var() Sound TransFailedSound; var bool bGibMe; var Material TransMaterials[2]; simulated function PlayFiring() { if ( TransLauncher(Weapon).bBeaconDeployed ) { Weapon.PlayAnim(FireAnim, FireAnimRate, TweenTime); } } simulated function bool AllowFire() { local bool success; success = ( TransLauncher(Weapon).AmmoChargeF >= 1.0 ); if (!success && (Weapon.Role == ROLE_Authority) && (TransLauncher(Weapon).TransBeacon != None) ) { if( PlayerController(Instigator.Controller) != None ) PlayerController(Instigator.Controller).ClientPlaySound(TransFailedSound); } return success; } function bool AttemptTranslocation(vector dest, TransBeacon TransBeacon) { local vector OldLocation, HitLocation, HitNormal; local actor HitActor; OldLocation = Instigator.Location; if ( !TranslocSucceeded(dest,TransBeacon) ) return false; HitActor = Weapon.Trace(HitLocation,HitNormal,Instigator.Location, dest, false); if ( HitActor == None ) return true; Instigator.SetLocation(OldLocation); return false; } function bool TranslocSucceeded(vector dest, TransBeacon TransBeacon) { local vector newdest; if ( Instigator.SetLocation(dest) || BotTranslocation() ) return true; if ( TransBeacon.Physics != PHYS_None ) { newdest = TransBeacon.Location - Instigator.CollisionRadius * Normal(TransBeacon.Velocity); if ( Instigator.SetLocation(newdest) ) return true; } if ( (dest != Transbeacon.Location) && Instigator.SetLocation(TransBeacon.Location) ) return true; newdest = dest + Instigator.CollisionRadius * vect(1,1,0); if ( Instigator.SetLocation(newdest) ) return true; newdest = dest + Instigator.CollisionRadius * vect(1,-1,0); if ( Instigator.SetLocation(newdest) ) return true; newdest = dest + Instigator.CollisionRadius * vect(-1,1,0); if ( Instigator.SetLocation(newdest) ) return true; newdest = dest + Instigator.CollisionRadius * vect(-1,-1,0); if ( Instigator.SetLocation(newdest) ) return true; return false; } function Translocate() { local TransBeacon TransBeacon; local Actor HitActor; local Vector HitNormal,HitLocation,dest,Vel2D; local Vector PrevLocation,Diff, NewDest; local xPawn XP; local controller C; local bool bFailedTransloc; local int EffectNum; local float DiffZ; if ( (Instigator == None) || (Translauncher(Weapon) == None) ) return; TransBeacon = TransLauncher(Weapon).TransBeacon; // gib if the translocator is disrupted if ( TransBeacon.Disrupted() ) { UnrealMPGameInfo(Level.Game).SpecialEvent(Instigator.PlayerReplicationInfo,"translocate_gib"); bGibMe = true; // delay gib to avoid destroying player and weapons right away in the middle of all this return; } dest = TransBeacon.Location; if ( TransBeacon.Physics == PHYS_None ) dest += vect(0,0,1) * Instigator.CollisionHeight; else dest += vect(0,0,0.5) * Instigator.CollisionHeight; HitActor = Weapon.Trace(HitLocation,HitNormal,dest,TransBeacon.Location,true); if ( HitActor != None ) dest = TransBeacon.Location; TransBeacon.SetCollision(false, false, false); if (Instigator.PlayerReplicationInfo.HasFlag != None) Instigator.PlayerReplicationInfo.HasFlag.Drop(0.5 * Instigator.Velocity); PrevLocation = Instigator.Location; // verify won't telefrag teammate or recently spawned player for ( C=Level.ControllerList; C!=None; C=C.NextController ) if ( (C.Pawn != None) && (C.Pawn != Instigator) ) { Diff = Dest - C.Pawn.Location; DiffZ = Diff.Z; Diff.Z = 0; if ( (Abs(DiffZ) < C.Pawn.CollisionHeight + 2 * Instigator.CollisionHeight) && (VSize(Diff) < C.Pawn.CollisionRadius + Instigator.CollisionRadius + 8) ) { if ( (C.SameTeamAs(Instigator.Controller) || (Level.TimeSeconds - C.Pawn.SpawnTime < DeathMatch(Level.Game).SpawnProtectionTime)) ) { bFailedTransloc = true; break; } else { if ( DiffZ > 1.5 * C.Pawn.CollisionHeight ) { NewDest = Dest; NewDest.Z += 0.7 * C.Pawn.CollisionHeight; } else NewDest = Dest + 0.5 * C.Pawn.CollisionRadius * Normal(Diff); if ( Weapon.FastTrace(NewDest ,dest) ) Dest = NewDest; } } } if ( !bFailedTransloc && AttemptTranslocation(dest,TransBeacon) ) { TransLauncher(Weapon).ReduceAmmo(); // spawn out XP = xPawn(Instigator); if( XP != None ) XP.DoTranslocateOut(PrevLocation); // bound XY velocity to prevent cheats Vel2D = Instigator.Velocity; Vel2D.Z = 0; Vel2D = Normal(Vel2D) * FMin(Instigator.GroundSpeed,VSize(Vel2D)); Vel2D.Z = Instigator.Velocity.Z; Instigator.Velocity = Vel2D; if ( Instigator.PlayerReplicationInfo.Team != None ) EffectNum = Instigator.PlayerReplicationInfo.Team.TeamIndex; Instigator.SetOverlayMaterial( TransMaterials[EffectNum], 1.0, false ); Instigator.PlayTeleportEffect( false, false); if ( !Instigator.PhysicsVolume.bWaterVolume ) { if ( Bot(Instigator.Controller) != None ) { Instigator.Velocity.X = 0; Instigator.Velocity.Y = 0; Instigator.Velocity.Z = -150; Instigator.Acceleration = vect(0,0,0); } Instigator.SetPhysics(PHYS_Falling); } if ( UnrealTeamInfo(Instigator.PlayerReplicationInfo.Team)!= None ) UnrealTeamInfo(Instigator.PlayerReplicationInfo.Team).AI.CallForBall(Instigator); // for bombing run } else if( PlayerController(Instigator.Controller) != None ) PlayerController(Instigator.Controller).ClientPlaySound(TransFailedSound); TransBeacon.Destroy(); TransLauncher(Weapon).TransBeacon = None; TransLauncher(Weapon).ViewPlayer(); } function ModeDoFire() { local TransBeacon TransBeacon; Super.ModeDoFire(); if ( Weapon.Role == ROLE_Authority && bGibMe) { TransBeacon = TransLauncher(Weapon).TransBeacon; TransLauncher(Weapon).TransBeacon = None; TransLauncher(Weapon).ViewPlayer(); Instigator.GibbedBy(TransBeacon.Disruptor); TransBeacon.Destroy(); bGibMe = false; } } function DoFireEffect() { if (TransLauncher(Weapon).TransBeacon != None) { Translocate(); } } // AI Interface function bool BotTranslocation() { local Bot B; B = Bot(Instigator.Controller); if ( (B == None) || !B.bPreparingMove || (B.RealTranslocationTarget == None) ) return false; // if bot failed to translocate, event though beacon was in target cylinder, // try at center of cylinder return ( Instigator.SetLocation(B.RealTranslocationTarget.Location) ); } // END AI interface Y%^//============================================================================= // Translocator Launcher //============================================================================= class TransLauncher extends Weapon config(user) HideDropDown; #EXEC OBJ LOAD FILE=InterfaceContent.utx var TransBeacon TransBeacon; var() float MaxCamDist; var() float AmmoChargeF; var int RepAmmo; var() float AmmoChargeMax; var() float AmmoChargeRate; var globalconfig bool bPrevWeaponSwitch; var xBombFlag Bomb; var bool bDrained; var bool bBeaconDeployed; // meaningful for client var bool bTeamSet; var byte ViewBeaconVolume; var float PreDrainAmmo; var rotator TranslocRot; var float TranslocScale, OldTime; replication { reliable if ( bNetOwner && (ROLE==ROLE_Authority) ) TransBeacon,RepAmmo; } simulated function bool HasAmmo() { return true; } // AI Interface... function GiveTo(Pawn Other, optional Pickup Pickup) { Super.GiveTo(Other, Pickup); if ( Bot(Other.Controller) != None ) Bot(Other.Controller).bHasTranslocator = true; } function bool ShouldTranslocatorHop(Bot B) { local float dist; local Actor N; local bool bHop; bHop = B.bTranslocatorHop; B.bTranslocatorHop = false; if ( bHop && (B.Focus == B.TranslocationTarget) && (B.NextTranslocTime < Level.TimeSeconds) && B.InLatentExecution(B.LATENT_MOVETOWARD) && B.Squad.AllowTranslocationBy(B) ) { if ( (TransBeacon != None) && TransBeacon.IsMonitoring(B.Focus) ) return false; dist = VSize(B.TranslocationTarget.Location - B.Pawn.Location); if ( dist < 300 ) { // see if next path is possible N = B.AlternateTranslocDest(); if ( (N == None) || ((vector(B.Rotation) Dot Normal(N.Location - B.Pawn.Location)) < 0.5) ) { if ( dist < 200 ) { B.TranslocationTarget = None; B.RealTranslocationTarget = None; return false; } } else { B.TranslocationTarget = N; B.RealTranslocationTarget = B.TranslocationTarget; B.Focus = N; return true; } } if ( (vector(B.Rotation) Dot Normal(B.TranslocationTarget.Location - B.Pawn.Location)) < 0.5 ) { SetTimer(0.1,false); return false; } return true; } return false; } simulated function Timer() { local Bot B; if ( Instigator != None ) { B = Bot(Instigator.Controller); if ( (B != None) && (B.TranslocationTarget != None) && (B.bPreparingMove || ShouldTranslocatorHop(B)) ) FireHack(0); } Super.Timer(); } function FireHack(byte Mode) { local Actor TTarget; local vector TTargetLoc; if ( Mode == 0 ) { if ( TransBeacon != None ) { // this shouldn't happen TransBeacon.bNoAI = true; TransBeacon.Destroy(); TransBeacon = None; } TTarget = Bot(Instigator.Controller).TranslocationTarget; if ( TTarget == None ) return; // hack in translocator firing here FireMode[0].PlayFiring(); FireMode[0].FlashMuzzleFlash(); FireMode[0].StartMuzzleSmoke(); IncrementFlashCount(0); ProjectileFire(FireMode[0]).SpawnProjectile(Instigator.Location,Rot(0,0,0)); // find correct initial velocity TTargetLoc = TTarget.Location; if ( JumpSpot(TTarget) != None ) { TTargetLoc.Z += JumpSpot(TTarget).TranslocZOffset; if ( (Instigator.Anchor != None) && Instigator.ReachedDestination(Instigator.Anchor) ) { // start from same point as in test Transbeacon.SetLocation(TransBeacon.Location + Instigator.Anchor.Location + (Instigator.CollisionHeight - Instigator.Anchor.CollisionHeight) * vect(0,0,1)- Instigator.Location); } } else if ( TTarget.Velocity != vect(0,0,0) ) { TTargetLoc += 0.3 * TTarget.Velocity; TTargetLoc.Z = 0.5 * (TTargetLoc.Z + TTarget.Location.Z); } else if ( (Instigator.Physics == PHYS_Falling) && (Instigator.Location.Z < TTarget.Location.Z) && (Instigator.PhysicsVolume.Gravity.Z > -800) ) TTargetLoc.Z += 128; TransBeacon.Velocity = Bot(Instigator.Controller).AdjustToss(TransBeacon.Speed, TransBeacon.Location, TTargetLoc,false); TransBeacon.SetTranslocationTarget(Bot(Instigator.Controller).RealTranslocationTarget); } } function class GetDamageType() { return class'DamTypeTelefrag'; } // super desireable for bot waiting to translocate function float GetAIRating() { local Bot B; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( B.bPreparingMove && (B.TranslocationTarget != None) ) return 10; if ( B.bTranslocatorHop && ((B.Focus == B.MoveTarget) || ((B.TranslocationTarget != None) && (B.Focus == B.TranslocationTarget))) && B.Squad.AllowTranslocationBy(B) ) { if ( (TransBeacon != None) && TransBeacon.IsMonitoring(Transbeacon.TranslocationTarget) ) { if ( (GameObject(B.Focus) != None) && (B.Focus != Transbeacon.TranslocationTarget) ) { if ( Instigator.Weapon == self ) SetTimer(0.2,false); return 4; } if ( (Transbeacon.TranslocationTarget == Instigator.Controller.MoveTarget) || (Transbeacon.TranslocationTarget == Instigator.Controller.RouteGoal) || (Transbeacon.TranslocationTarget == Instigator.Controller.RouteCache[0]) || (Transbeacon.TranslocationTarget == Instigator.Controller.RouteCache[1]) || (Transbeacon.TranslocationTarget == Instigator.Controller.RouteCache[2]) || (Transbeacon.TranslocationTarget == Instigator.Controller.RouteCache[3]) ) return 4; } if ( Instigator.Weapon == self ) SetTimer(0.2,false); return 4; } if ( Instigator.Weapon == self ) return AIRating; } function bool BotFire(bool bFinished, optional name FiringMode) { return false; } // End AI interface function bool ConsumeAmmo(int mode, float load, optional bool bAmountNeededIsMax) { return true; } function ReduceAmmo() { enable('Tick'); bDrained = false; AmmoChargeF -= 1; RepAmmo -= 1; if ( Bot(Instigator.Controller) != None ) Bot(Instigator.Controller).TranslocFreq = 3 + FMax(Bot(Instigator.Controller).TranslocFreq,Level.TimeSeconds); } simulated function GetAmmoCount(out float MaxAmmoPrimary, out float CurAmmoPrimary) { MaxAmmoPrimary = AmmoChargeMax; CurAmmoPrimary = FMax(0,AmmoChargeF); } function GiveAmmo(int m, WeaponPickup WP, bool bJustSpawned) { Super.GiveAmmo(m, WP,bJustSpawned); AmmoChargeF = Default.AmmoChargeF; RepAmmo = int(AmmoChargeF); } function DrainCharges() { enable('Tick'); PreDrainAmmo = AmmoChargeF; AmmoChargeF = -1; RepAmmo = -1; bDrained = true; if ( Bot(Instigator.Controller) != None ) Bot(Instigator.Controller).NextTranslocTime = Level.TimeSeconds + 3.5; } simulated function bool StartFire(int Mode) { if ( !bPrevWeaponSwitch || (Mode == 1) || (Instigator.Controller.bAltFire == 0) || (PlayerController(Instigator.Controller) == None) ) return Super.StartFire(Mode); if ( (OldWeapon != None) && OldWeapon.HasAmmo() ) Instigator.PendingWeapon = OldWeapon; ClientStopFire(0); Instigator.Controller.StopFiring(); PutDown(); return false; } simulated function Tick(float dt) { if (Role == ROLE_Authority) { if ( AmmoChargeF >= AmmoChargeMax ) { if ( RepAmmo != int(AmmoChargeF) ) // condition to avoid unnecessary bNetDirty of ammo RepAmmo = int(AmmoChargeF); disable('Tick'); return; } AmmoChargeF += dt*AmmoChargeRate; AmmoChargeF = FMin(AmmoChargeF, AmmoChargeMax); if ( AmmoChargeF >= 1.5 ) bDrained = false; else if ( bDrained ) { if ( (Bomb == None) && ( Level.Game.IsA('xBombingRun') ) ) Bomb = xBombFlag(UnrealMPGameInfo(Level.Game).GetGameObject('xBombFlag')); if ( (Bomb != None) && (Bomb.Holder != None) ) { bDrained = false; AmmoChargeF = 1.5; if ( Bot(Instigator.Controller) != None ) Bot(Instigator.Controller).NextTranslocTime = Level.TimeSeconds - 1; } } if ( RepAmmo != int(AmmoChargeF) ) // condition to avoid unnecessary bNetDirty of ammo RepAmmo = int(AmmoChargeF); } else { // client simulation of the charge bar AmmoChargeF = FMin(RepAmmo + AmmoChargeF - int(AmmoChargeF)+dt*AmmoChargeRate, AmmoChargeMax); } } simulated function DoAutoSwitch() { } simulated function ViewPlayer() { if ( (PlayerController(Instigator.Controller) != None) && (PlayerController(Instigator.Controller).ViewTarget == TransBeacon) ) { PlayerController(Instigator.Controller).ClientSetViewTarget( Instigator ); PlayerController(Instigator.Controller).SetViewTarget( Instigator ); if ( TransBeacon != None ) { Transbeacon.SetRotation(PlayerController(Instigator.Controller).Rotation); Transbeacon.SoundVolume = Transbeacon.default.SoundVolume; } } } simulated function ViewCamera() { if ( TransBeacon!=None ) { if ( Instigator.Controller.IsA('PlayerController') ) { PlayerController(Instigator.Controller).SetViewTarget(TransBeacon); PlayerController(Instigator.Controller).ClientSetViewTarget(TransBeacon); PlayerController(Instigator.Controller).SetRotation( TransBeacon.Rotation ); Transbeacon.SoundVolume = ViewBeaconVolume; } } } simulated function Reselect() { if ( (TransBeacon == None) || (Instigator.Controller.IsA('PlayerController') && (PlayerController(Instigator.Controller).ViewTarget == TransBeacon)) ) ViewPlayer(); else ViewCamera(); } simulated event RenderOverlays( Canvas Canvas ) { local float tileScaleX, tileScaleY, dist, clr; local float NewTranslocScale; if ( (PlayerController(Instigator.Controller) != None) && (PlayerController(Instigator.Controller).ViewTarget == TransBeacon) ) { tileScaleX = Canvas.SizeX / 640.0f; tileScaleY = Canvas.SizeY / 480.0f; Canvas.DrawColor.R = 255; Canvas.DrawColor.G = 255; Canvas.DrawColor.B = 255; Canvas.DrawColor.A = 255; Canvas.Style = 255; Canvas.SetPos(0,0); Canvas.DrawTile( Material'TransCamFB', Canvas.SizeX, Canvas.SizeY, 0.0, 0.0, 512, 512 ); // !! hardcoded size Canvas.SetPos(0,0); if ( !Level.IsSoftwareRendering() ) { dist = VSize(TransBeacon.Location - Instigator.Location); if ( dist > MaxCamDist ) { clr = 255.0; } else { clr = (dist / MaxCamDist); clr *= 255.0; } clr = Clamp( clr, 20.0, 255.0 ); Canvas.DrawColor.R = clr; Canvas.DrawColor.G = clr; Canvas.DrawColor.B = clr; Canvas.DrawColor.A = 255; Canvas.DrawTile( Material'ScreenNoiseFB', Canvas.SizeX, Canvas.SizeY, 0.0, 0.0, 512, 512 ); // !! hardcoded size } } else { if ( TransBeacon == None ) NewTranslocScale = 1; else NewTranslocScale = 0; if ( NewTranslocScale != TranslocScale ) { TranslocScale = NewTranslocScale; SetBoneScale(0,TranslocScale,'Beacon'); } if ( TranslocScale != 0 ) { TranslocRot.Yaw += 120000 * (Level.TimeSeconds - OldTime); OldTime = Level.TimeSeconds; SetBoneRotation('Beacon',TranslocRot,0); } if ( !bTeamSet && (Instigator.PlayerReplicationInfo != None) && (Instigator.PlayerReplicationInfo.Team != None) ) { bTeamSet = true; if ( Instigator.PlayerReplicationInfo.Team.TeamIndex == 1 ) Skins[1] = Material'WeaponSkins.NEWTranslocatorBlue'; } Super.RenderOverlays(Canvas); } } simulated function bool PutDown() { ViewPlayer(); return Super.PutDown(); } simulated function Destroyed() { if (TransBeacon != None) TransBeacon.Destroy(); Super.Destroyed(); } simulated function float ChargeBar() { return AmmoChargeF - int(AmmoChargeF); } Y%Cclass TransFire extends ProjectileFire; var() Sound TransFireSound; var() Sound RecallFireSound; var() String TransFireForce; var() String RecallFireForce; simulated function PlayFiring() { if (!TransLauncher(Weapon).bBeaconDeployed) { Weapon.PlayAnim(FireAnim, FireAnimRate, TweenTime); ClientPlayForceFeedback( TransFireForce ); // jdf } } function Rotator AdjustAim(Vector Start, float InAimError) { return Instigator.Controller.Rotation; } simulated function bool AllowFire() { return ( TransLauncher(Weapon).AmmoChargeF >= 1.0 ); } function projectile SpawnProjectile(Vector Start, Rotator Dir) { local TransBeacon TransBeacon; if (TransLauncher(Weapon).TransBeacon == None) { if ( (Instigator == None) || (Instigator.PlayerReplicationInfo == None) || (Instigator.PlayerReplicationInfo.Team == None) ) TransBeacon = Weapon.Spawn(class'XWeapons.TransBeacon',,, Start, Dir); else if ( Instigator.PlayerReplicationInfo.Team.TeamIndex == 0 ) TransBeacon = Weapon.Spawn(class'XWeapons.RedBeacon',,, Start, Dir); else TransBeacon = Weapon.Spawn(class'XWeapons.BlueBeacon',,, Start, Dir); TransLauncher(Weapon).TransBeacon = TransBeacon; Weapon.PlaySound(TransFireSound,SLOT_Interact,,,,,false); } else { TransLauncher(Weapon).ViewPlayer(); if ( TransLauncher(Weapon).TransBeacon.Disrupted() ) { if( (Instigator != None) && (PlayerController(Instigator.Controller) != None) ) PlayerController(Instigator.Controller).ClientPlaySound(Sound'WeaponSounds.BSeekLost1'); } else { TransLauncher(Weapon).TransBeacon.Destroy(); TransLauncher(Weapon).TransBeacon = None; Weapon.PlaySound(RecallFireSound,SLOT_Interact,,,,,false); } } return TransBeacon; } Y%}class TransbeaconTeleporter extends Keypoint; var() name JumpSpotTag; var JumpSpot myJumpSpot; function PostBeginPlay() { super.PostBeginPlay(); if ( JumpSpotTag != '' ) ForEach AllActors(class'JumpSpot',myJumpSpot,JumpSpotTag) break; } event Touch(Actor Other) { if ( (TransBeacon(Other) == None) || (myJumpSpot == None) ) return; Other.SetLocation(myJumpSpot.Location); if ( TransBeacon(Other).Trail != None ) TransBeacon(Other).Trail.mRegen = false; } w!`![ x!(vKʁ)ututBX$AA$AO Y%Y%i //============================================================================= // Translocator Beacon //============================================================================= class TransBeacon extends TranslocatorBeacon; var bool bCanHitOwner, bHitWater; var bool bDamaged; var bool bNoAI; var xEmitter Trail; var xEmitter Flare; var Actor TranslocationTarget; // for AI var int Disruption; var int DisruptionThreshold; var Pawn Disruptor; var TransBeaconSparks Sparks; var class TransTrailClass; var class TransFlareClass; replication { reliable if ( Role == ROLE_Authority ) Disruption; } simulated function Destroyed() { if ( Trail != None ) Trail.mRegen = false; if ( Flare != None ) { Flare.mRegen = false; Flare.Destroy(); } if ( Sparks != None ) Sparks.Destroy(); Super.Destroyed(); } event EncroachedBy( actor Other ) { if ( Mover(Other) != None ) Destroy(); } simulated function bool Disrupted() { return ( Disruption > DisruptionThreshold ); } simulated function PostBeginPlay() { local Rotator r; local int diff; Super.PostBeginPlay(); if ( Role == ROLE_Authority ) { R = Rotation; if ( AimUp() ) { R.Pitch = R.Pitch & 65535; if ( R.Pitch > 32768 ) diff = 65536 - R.Pitch; else diff = R.Pitch; R.Pitch = R.Pitch + (32768 - diff)/8; } Velocity = Speed * Vector(R); R.Yaw = Rotation.Yaw; R.Pitch = 0; R.Roll = 0; SetRotation(R); bCanHitOwner = false; } Trail = Spawn(TransTrailClass, self,, Location, Rotation); SetTimer(0.3,false); } function bool AimUp() { if ( xPlayer(Instigator.Controller) == None ) return false; return xPlayer(Instigator.Controller).bHighBeaconTrajectory; } simulated function PhysicsVolumeChange( PhysicsVolume Volume ) { } simulated function Landed( vector HitNormal ) { HitWall( HitNormal, None ); } simulated function ProcessTouch( actor Other, vector HitLocation ) { local vector Vel2D; if ( Other == Instigator && Physics == PHYS_None ) Destroy(); else if ( (Other != Instigator) || bCanHitOwner ) { if ( (Pawn(Other) != None) && (Vehicle(Other) == None) ) { Vel2D = Velocity; Vel2D.Z = 0; if ( VSize(Vel2D) < 200 ) return; } HitWall( -Normal(Velocity), Other ); //HitWall( Normal(HitLocation-Other.Location), Other ); // causes problems with actors using large staticmeshes } } // poll for disruption simulated function Timer() { if ( Level.NetMode == NM_DedicatedServer ) return; if ( !Disrupted() ) { SetTimer(0.3, false); return; } // create the disrupted effect if (Sparks == None) { Sparks = Spawn(class'TransBeaconSparks',,,Location+vect(0,0,5),Rotator(vect(0,0,1))); Sparks.SetBase(self); } if (Flare != None) Flare.Destroy(); } function TakeDamage(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, class DamageType) { if ( Level.Game.bTeamGame && (EventInstigator != None) && (EventInstigator.PlayerReplicationInfo != None) && ((Instigator == None) || (EventInstigator.PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team)) ) { return; } else { Disruption += Damage; Disruptor = EventInstigator; } } function BotTranslocate(); simulated function HitWall( vector HitNormal, actor Wall ) { local CTFBase B; bCanHitOwner = true; Velocity = 0.3*(( Velocity dot HitNormal ) * HitNormal * (-2.0) + Velocity); // Reflect off Wall w/damping Speed = VSize(Velocity); if ( Speed < 100 ) { ForEach TouchingActors(class'CTFBase', B) break; if ( B != None ) { Speed = VSize(Velocity); if ( Speed < 100 ) { Speed = 90; Velocity = 90 * Normal(Velocity); } Disruption += 5; if ( Disruptor == None ) Disruptor = Instigator; } } if ( Speed < 20 && Wall.bWorldGeometry && (HitNormal.Z >= 0.7) ) { if ( Level.NetMode != NM_DedicatedServer ) PlaySound(ImpactSound, SLOT_Misc ); bBounce = false; SetPhysics(PHYS_None); if (Trail != None) Trail.mRegen = false; if ( (Level.NetMode != NM_DedicatedServer) && (Flare == None) ) { Flare = Spawn(TransFlareClass, self,, Location - vect(0,0,5), rot(16384,0,0)); Flare.SetBase(self); } } } // AI Interface function SetTranslocationTarget(actor T) { TranslocationTarget = T; GotoState('MonitoringThrow'); } function bool IsMonitoring(actor A) { return false; } function EndMonitoring(); State MonitoringThrow { function bool IsMonitoring(actor A) { return ( A == TranslocationTarget ); } function Destroyed() { local Bot B; B = Bot(Instigator.Controller); if ( B != None ) { B.TranslocationTarget = None; B.RealTranslocationTarget = None; B.bPreparingMove = false; B.SwitchToBestWeapon(); } Global.Destroyed(); } function EndMonitoring() { GotoState(''); } function EndState() { local Bot B; B = Bot(Instigator.Controller); if ( (B != None) && !bNoAI ) { B.TranslocationTarget = None; B.RealTranslocationTarget = None; B.bPreparingMove = false; B.SwitchToBestWeapon(); } } simulated function HitWall( vector HitNormal, actor Wall ) { Global.HitWall(HitNormal,Wall); if ( (GameObject(TranslocationTarget) != None) && (HitNormal.Z > 0.7) && (VSize(Location - TranslocationTarget.Location) < FMin(400, VSize(Instigator.Location - TranslocationTarget.Location))) ) { Instigator.Controller.MoveTarget = TranslocationTarget; BotTranslocate(); return; } if ( Physics == PHYS_None ) { if ( (Bot(Instigator.Controller) != None) && Bot(Instigator.Controller).bPreparingMove ) { Bot(Instigator.Controller).MoveTimer = -1; if ( (JumpSpot(TranslocationTarget) != None) && (Instigator.Controller.MoveTarget == TranslocationTarget) ) JumpSpot(TranslocationTarget).FearCost += 900; } EndMonitoring(); } } function BotTranslocate() { if ( TransLauncher(Instigator.Weapon) != None ) Instigator.Weapon.GetFireMode(1).DoFireEffect(); EndMonitoring(); } function Touch(Actor Other) { local Pawn P; P = Pawn(Other); if ( (P == None) || (P == Instigator) ) return; ProcessTouch( Other, Location ); if ( (Bot(P.Controller) == None) || Level.Game.IsOnTeam(P.Controller,Instigator.PlayerReplicationInfo.Team.TeamIndex) ) { EndMonitoring(); return; } if ( Bot(P.Controller).ProficientWithWeapon() && (2 + FRand() * 8 < Bot(P.Controller).Skill) ) BotTranslocate(); } // FIXME - consider making this a timer or projectile latent function instead of using tick? function Tick(float DeltaTime) { local vector Dist, Dir, HitLocation, HitNormal; local float ZDiff, Dist2D; local actor HitActor; if ( (TranslocationTarget == None) || (Instigator.Controller == None) || !Bot(Instigator.Controller).Squad.AllowTranslocationBy(Bot(Instigator.Controller)) || ((GameObject(Instigator.Controller.MoveTarget) != None) && (Instigator.Controller.MoveTarget != TranslocationTarget)) || ((TranslocationTarget != Instigator.Controller.MoveTarget) && (TranslocationTarget != Instigator.Controller.RouteGoal) && (TranslocationTarget != Instigator.Controller.RouteCache[0]) && (TranslocationTarget != Instigator.Controller.RouteCache[1]) && (TranslocationTarget != Instigator.Controller.RouteCache[2]) && (TranslocationTarget != Instigator.Controller.RouteCache[3])) ) { EndMonitoring(); return; } Dist = Location - TranslocationTarget.Location; ZDiff = Dist.Z; Dist.Z = 0; Dir = TranslocationTarget.Location - Instigator.Location; Dir.Z = 0; Dist2D = VSize(Dist); if ( Dist2D < TranslocationTarget.CollisionRadius ) { if ( ZDiff > -0.9 * TranslocationTarget.CollisionHeight ) { Instigator.Controller.MoveTarget = TranslocationTarget; BotTranslocate(); } return; } Dir = TranslocationTarget.Location - Instigator.Location; Dir.Z = 0; if ( (Dist Dot Dir) > 0 ) { if ( (Bot(Instigator.Controller) != None) && Bot(Instigator.Controller).bPreparingMove ) { Bot(Instigator.Controller).MoveTimer = -1; if ( (JumpSpot(TranslocationTarget) != None) && (Instigator.Controller.MoveTarget == TranslocationTarget) ) JumpSpot(TranslocationTarget).FearCost += 400; } else if ( (GameObject(TranslocationTarget) != None) && (ZDiff > 0) && (Dist2D < FMin(400, VSize(Instigator.Location - TranslocationTarget.Location) - 250)) ) { // if safe underneath, then translocate HitActor = Trace(HitLocation, HitNormal, Location - vect(0,0,100), Location, false); if ( (HitActor != None) && (HitNormal.Z > 0.7) ) { Instigator.Controller.MoveTarget = TranslocationTarget; BotTranslocate(); return; } } EndMonitoring(); return; } } } // END AI interface Y%lclass TransAttachment extends xWeaponAttachment; function InitFor(Inventory I) { Super.InitFor(I); } simulated event ThirdPersonEffects() { Super.ThirdPersonEffects(); } simulated event BaseChange() { if ( (Pawn(Base) != None) && (Pawn(Base).PlayerReplicationInfo != None) && (Pawn(Base).PlayerReplicationInfo.Team != None) ) { if ( Pawn(Base).PlayerReplicationInfo.Team.TeamIndex == 1 ) Skins[1] = Material'WeaponSkins.NEWTranslocatorBlue'; else Skins[1] = Material'WeaponSkins.NEWTranslocatorTEX'; } } Y%iclass TransAmmo extends Ammunition; function bool AddAmmo(int AmmoToAdd) { return false; } {!kG 2|!i\"L"K"]TransLauncherY%Y%t//============================================================================= // SuperShockRiflePickup //============================================================================= class SuperShockRiflePickup extends UTWeaponPickup; Y%q!Uu9:9:$-kU..*.jp UT Ua-k( GY%y//============================================================================= // SuperShockRifle //============================================================================= class SuperShockRifle extends ShockRifle HideDropDown CacheExempt; #exec OBJ LOAD FILE=..\Sounds\WeaponSounds.uax #exec OBJ LOAD FILE=XEffectMat.utx simulated event RenderOverlays( Canvas Canvas ) { if ( (Instigator.PlayerReplicationInfo.Team != None) && (Instigator.PlayerReplicationInfo.Team.TeamIndex == 1) ) ConstantColor'UT2004Weapons.ShockControl'.Color = class'HUD'.Default.BlueColor; else ConstantColor'UT2004Weapons.ShockControl'.Color = class'HUD'.Default.RedColor; Super.RenderOverlays(Canvas); } simulated function bool ConsumeAmmo(int Mode, float load, optional bool bAmountNeededIsMax) { return true; } simulated function CheckOutOfAmmo() { } function float GetAIRating() { return AIRating; } simulated function bool StartFire(int mode) { bWaitForCombo = false; return Super.StartFire(mode); } function float RangedAttackTime() { return 0; } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { return 0; } Y%~!i%"w.*\ GY%@"B"[yK.RrK*K-rK*(a K  GY%KY%Y%sclass SuperShockBeamFire extends ShockBeamFire; function DoFireEffect() { local Vector StartTrace; local Rotator R, Aim; Instigator.MakeNoise(1.0); // the to-hit trace always starts right in front of the eye StartTrace = Instigator.Location + Instigator.EyePosition(); Aim = AdjustAim(StartTrace, AimError); R = rotator(vector(Aim) + VRand()*FRand()*Spread); DoTrace(StartTrace, R); } function DoTrace(Vector Start, Rotator Dir) { local Vector X; X = vector(Dir); TracePart(Start,Start+X*TraceRange,X,Dir,Instigator); } function bool AllowMultiHit() { return false; } function TracePart(Vector Start, Vector End, Vector X, Rotator Dir, Pawn Ignored) { local Vector HitLocation, HitNormal; local Actor Other; Other = Ignored.Trace(HitLocation, HitNormal, End, Start, true); if ( (Other != None) && (Other != Ignored) ) { if ( !Other.bWorldGeometry ) { Other.TakeDamage(DamageMax, Instigator, HitLocation, Momentum*X, DamageType); HitNormal = Vect(0,0,0); if ( (Pawn(Other) != None) && (HitLocation != Start) && AllowMultiHit() ) TracePart(HitLocation,End,X,Dir,Pawn(Other)); } } else { HitLocation = End; HitNormal = Vect(0,0,0); } SpawnBeamEffect(Start, Dir, HitLocation, HitNormal, 0); } function SpawnBeamEffect(Vector Start, Rotator Dir, Vector HitLocation, Vector HitNormal, int ReflectNum) { local ShockBeamEffect Beam; if ( (Instigator.PlayerReplicationInfo.Team != None) && (Instigator.PlayerReplicationInfo.Team.TeamIndex == 1) ) Beam = Weapon.Spawn(class'BlueSuperShockBeam',,, Start, Dir); else Beam = Weapon.Spawn(BeamEffectClass,,, Start, Dir); if (ReflectNum != 0) Beam.Instigator = None; // prevents client side repositioning of beam start Beam.AimAt(HitLocation, HitNormal); } Y%] class SuperShockBeamEffect extends ShockBeamEffect; #exec obj load file=InstagibEffects.utx simulated function SpawnEffects() { local ShockBeamEffect E; Super.SpawnEffects(); E = Spawn(class'ExtraRedBeam'); if ( E != None ) E.AimAt(mSpawnVecA, HitNormal); } simulated function SpawnImpactEffects(rotator HitRot, vector EffectLoc) { Spawn(class'ShockImpactFlareB',,, EffectLoc, HitRot); Spawn(class'ShockImpactRingB',,, EffectLoc, HitRot); Spawn(class'ShockImpactScorch',,, EffectLoc, Rotator(-HitNormal)); Spawn(class'ShockExplosionCoreB',,, EffectLoc, HitRot); } Y%Hclass SuperShockAmmo extends ShockAmmo; simulated function CheckOutOfAmmo() { } simulated function bool UseAmmo(int AmountNeeded, optional bool bAmountNeededIsMax) { return true; } Y%)class SniperZoom extends WeaponFire; Y%E#//============================================================================= // SniperRiflePickup. //============================================================================= class SniperRiflePickup extends UTWeaponPickup; #exec OBJ LOAD FILE=WeaponSkins.utx static function StaticPrecache(LevelInfo L) { L.AddPrecacheMaterial(Material'XGameShaders.WeaponEnvShader'); L.AddPrecacheMaterial(Texture'SniperBorder'); L.AddPrecacheMaterial(Texture'SniperFocus'); L.AddPrecacheMaterial(Texture'SniperArrows'); L.AddPrecacheMaterial(Texture'Engine.WhiteTexture'); L.AddPrecacheMaterial(Texture'WeaponSkins.SniperScreen1'); L.AddPrecacheMaterial(Texture'WeaponSkins.SniperScreen1Pan'); L.AddPrecacheMaterial(Texture'WeaponSkins.SniperScreen2'); L.AddPrecacheMaterial(Texture'XEffects.LightningChargeT'); L.AddPrecacheMaterial(Texture'XEffects.pcl_BlueSpark'); L.AddPrecacheMaterial(Texture'XEffects.LightningBoltT'); L.AddPrecacheMaterial(Material'XGameShaders.fulloverlay'); L.AddPrecacheMaterial(Material'XGameShaders.scanline'); L.AddPrecacheMaterial(Material'EmitterTextures.LargeFlames'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.SniperRiflePickup'); } simulated function UpdatePrecacheMaterials() { Level.AddPrecacheMaterial(Material'EmitterTextures.LargeFlames'); Level.AddPrecacheMaterial(Material'XGameShaders.WeaponEnvShader'); Level.AddPrecacheMaterial(Texture'SniperBorder'); Level.AddPrecacheMaterial(Texture'SniperFocus'); Level.AddPrecacheMaterial(Texture'SniperArrows'); Level.AddPrecacheMaterial(Texture'Engine.WhiteTexture'); Level.AddPrecacheMaterial(Texture'WeaponSkins.SniperScreen1'); Level.AddPrecacheMaterial(Texture'WeaponSkins.SniperScreen1Pan'); Level.AddPrecacheMaterial(Texture'WeaponSkins.SniperScreen2'); Level.AddPrecacheMaterial(Texture'XEffects.LightningChargeT'); Level.AddPrecacheMaterial(Texture'XEffects.pcl_BlueSpark'); Level.AddPrecacheMaterial(Texture'XEffects.LightningBoltT'); Level.AddPrecacheMaterial(Material'XGameShaders.fulloverlay'); Level.AddPrecacheMaterial(Material'XGameShaders.scanline'); super.UpdatePrecacheMaterials(); } Y%//============================================================================= // Sniper Rifle //============================================================================= class SniperRifle extends Weapon config(user); #EXEC OBJ LOAD FILE=InterfaceContent.utx #EXEC OBJ LOAD FILE=HudContent.utx #exec OBJ LOAD FILE=XGameShaders.utx var(Gfx) float testX; var(Gfx) float testY; var(Gfx) float borderX; var(Gfx) float borderY; var(Gfx) float focusX; var(Gfx) float focusY; var(Gfx) float innerArrowsX; var(Gfx) float innerArrowsY; var(Gfx) Color ArrowColor; var(Gfx) Color TargetColor; var(Gfx) Color NoTargetColor; var(Gfx) Color FocusColor; var(Gfx) Color ChargeColor; var(Gfx) vector RechargeOrigin; var(Gfx) vector RechargeSize; var transient float LastFOV; var() bool zoomed; var() xEmitter chargeEmitter; simulated function PostBeginPlay() { Super.PostBeginPlay(); } simulated function Destroyed() { if (chargeEmitter != None) chargeEmitter.Destroy(); Super.Destroyed(); } simulated function ClientWeaponThrown() { if( (Instigator != None) && (PlayerController(Instigator.Controller) != None) ) PlayerController(Instigator.Controller).EndZoom(); Super.ClientWeaponThrown(); } simulated function IncrementFlashCount(int Mode) { if ( Mode == 1 ) return; Super.IncrementFlashCount(Mode); } // compensate for bright fog simulated function SetZoomBlendColor(Canvas c) { local Byte val; local Color clr; local Color fog; clr.R = 255; clr.G = 255; clr.B = 255; clr.A = 255; if( Instigator.Region.Zone.bDistanceFog ) { fog = Instigator.Region.Zone.DistanceFogColor; val = 0; val = Max( val, fog.R); val = Max( val, fog.G); val = Max( val, fog.B); if( val > 128 ) { val -= 128; clr.R -= val; clr.G -= val; clr.B -= val; } } c.DrawColor = clr; } simulated event RenderOverlays( Canvas Canvas ) { local float tileScaleX; local float tileScaleY; local float bX; local float bY; local float fX; local float fY; local float ChargeBar; local float tX; local float tY; local float barOrgX; local float barOrgY; local float barSizeX; local float barSizeY; if ( PlayerController(Instigator.Controller) == None ) { Super.RenderOverlays(Canvas); zoomed=false; return; } if ( LastFOV > PlayerController(Instigator.Controller).DesiredFOV ) { PlaySound(Sound'WeaponSounds.LightningGun.LightningZoomIn', SLOT_Misc,,,,,false); } else if ( LastFOV < PlayerController(Instigator.Controller).DesiredFOV ) { PlaySound(Sound'WeaponSounds.LightningGun.LightningZoomOut', SLOT_Misc,,,,,false); } LastFOV = PlayerController(Instigator.Controller).DesiredFOV; if ( PlayerController(Instigator.Controller).DesiredFOV == PlayerController(Instigator.Controller).DefaultFOV ) { Super.RenderOverlays(Canvas); zoomed=false; } else { if ( FireMode[0].NextFireTime <= Level.TimeSeconds ) { ChargeBar = 1.0; } else { ChargeBar = 1.0 - ((FireMode[0].NextFireTime-Level.TimeSeconds) / FireMode[0].FireRate); } tileScaleX = Canvas.SizeX / 640.0f; tileScaleY = Canvas.SizeY / 480.0f; bX = borderX * tileScaleX; bY = borderY * tileScaleY; fX = 2*focusX * tileScaleX; fY = 2*focusY * tileScaleX; tX = testX * tileScaleX; tY = testY * tileScaleX; barOrgX = RechargeOrigin.X * tileScaleX; barOrgY = RechargeOrigin.Y * tileScaleY; barSizeX = RechargeSize.X * tileScaleX; barSizeY = RechargeSize.Y * tileScaleY; SetZoomBlendColor(Canvas); Canvas.Style = 255; Canvas.SetPos(0,0); Canvas.DrawTile( Material'ZoomFB', Canvas.SizeX, Canvas.SizeY, 128, 128, 256, 256 ); // !! hardcoded size Canvas.DrawColor = FocusColor; Canvas.DrawColor.A = 255; // 255 was the original -asp. WTF??!?!?! Canvas.Style = ERenderStyle.STY_Alpha; Canvas.SetPos((Canvas.SizeX*0.5)-fX,(Canvas.SizeY*0.5)-fY); Canvas.DrawTile( Texture'SniperFocus', fX*2.0, fY*2.0, 0.0, 0.0, Texture'SniperFocus'.USize, Texture'SniperFocus'.VSize ); fX = innerArrowsX * tileScaleX; fY = innerArrowsY * tileScaleY; Canvas.DrawColor = ArrowColor; Canvas.SetPos((Canvas.SizeX*0.5)-fX,(Canvas.SizeY*0.5)-fY); Canvas.DrawTile( Texture'SniperArrows', fX*2.0, fY*2.0, 0.0, 0.0, Texture'SniperArrows'.USize, Texture'SniperArrows'.VSize ); // Draw the Charging meter -AsP Canvas.DrawColor = ChargeColor; Canvas.DrawColor.A = 255; if(ChargeBar <1) Canvas.DrawColor.R = 255*ChargeBar; else { Canvas.DrawColor.R = 0; Canvas.DrawColor.B = 0; } if(ChargeBar == 1) Canvas.DrawColor.G = 255; else Canvas.DrawColor.G = 0; Canvas.Style = ERenderStyle.STY_Alpha; Canvas.SetPos( barOrgX, barOrgY ); Canvas.DrawTile(Texture'Engine.WhiteTexture',barSizeX,barSizeY*ChargeBar, 0.0, 0.0,Texture'Engine.WhiteTexture'.USize,Texture'Engine.WhiteTexture'.VSize*ChargeBar); zoomed = true; } } simulated function ClientStartFire(int mode) { if (mode == 1) { FireMode[mode].bIsFiring = true; if( Instigator.Controller.IsA( 'PlayerController' ) ) PlayerController(Instigator.Controller).ToggleZoom(); } else { Super.ClientStartFire(mode); } } simulated function ClientStopFire(int mode) { if (mode == 1) { FireMode[mode].bIsFiring = false; if( PlayerController(Instigator.Controller) != None ) PlayerController(Instigator.Controller).StopZoom(); } else { Super.ClientStopFire(mode); } } simulated function BringUp(optional Weapon PrevWeapon) { if ( PlayerController(Instigator.Controller) != None ) { LastFOV = PlayerController(Instigator.Controller).DesiredFOV; if ( Instigator.IsLocallyControlled() ) GotoState('TickEffects'); } Super.BringUp(PrevWeapon); } simulated function bool PutDown() { if( Instigator.Controller.IsA( 'PlayerController' ) ) PlayerController(Instigator.Controller).EndZoom(); if ( Super.PutDown() ) { GotoState(''); return true; } return false; } state TickEffects { simulated function Tick( float t ) { if (chargeEmitter == None) { chargeEmitter = Spawn(class'LightningCharge',self); AttachToBone(chargeEmitter, 'tip' ); } chargeEmitter.mRegenPause = ( FireMode[0].NextFireTime > Level.TimeSeconds || AmmoAmount(0) == 0 ); } } // AI Interface function float SuggestAttackStyle() { return -0.4; } function float SuggestDefenseStyle() { return 0.2; } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { return 0; } function float GetAIRating() { local Bot B; local float ZDiff, dist, Result; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( B.IsShootingObjective() ) return AIRating - 0.15; if ( B.Enemy == None ) { if ( (B.Target != None) && VSize(B.Target.Location - B.Pawn.Location) > 8000 ) return 0.95; return AIRating; } if ( B.Stopped() ) result = AIRating + 0.1; else result = AIRating - 0.1; if ( Vehicle(B.Enemy) != None ) result -= 0.2; ZDiff = Instigator.Location.Z - B.Enemy.Location.Z; if ( ZDiff < -200 ) result += 0.1; dist = VSize(B.Enemy.Location - Instigator.Location); if ( dist > 2000 ) { if ( !B.EnemyVisible() ) result = result - 0.15; return ( FMin(2.0,result + (dist - 2000) * 0.0002) ); } if ( !B.EnemyVisible() ) return AIRating - 0.1; return result; } function bool RecommendRangedAttack() { local Bot B; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return true; return ( VSize(B.Enemy.Location - Instigator.Location) > 2000 * (1 + FRand()) ); } // end AI Interface Y%DJclass SniperFire extends InstantFire; var() class HitEmitterClass; var() class SecHitEmitterClass; var() int NumArcs; var() float SecDamageMult; var() float SecTraceDist; var() float HeadShotDamageMult; var() class DamageTypeHeadShot; var(tweak) float offsetadj; function DoTrace(Vector Start, Rotator Dir) { local Vector X,Y,Z, End, HitLocation, HitNormal, RefNormal; local Actor Other, mainArcHitTarget; local int Damage, ReflectNum, arcsRemaining; local bool bDoReflect; local xEmitter hitEmitter; local class tmpHitEmitClass; local float tmpTraceRange; local vector arcEnd, mainArcHit; local Pawn HeadShotPawn; local vector EffectOffset; if ( class'PlayerController'.Default.bSmallWeapons ) EffectOffset = Weapon.SmallEffectOffset; else EffectOffset = Weapon.EffectOffset; Weapon.GetViewAxes(X, Y, Z); if ( Weapon.WeaponCentered() || SniperRifle(Weapon).zoomed ) arcEnd = (Instigator.Location + EffectOffset.Z * Z); else if ( Weapon.Hand == 0 ) { if ( class'PlayerController'.Default.bSmallWeapons ) arcEnd = (Instigator.Location + EffectOffset.X * X); else arcEnd = (Instigator.Location + EffectOffset.X * X - 0.5 * EffectOffset.Z * Z); } else arcEnd = (Instigator.Location + Instigator.CalcDrawOffset(Weapon) + EffectOffset.X * X + Weapon.Hand * EffectOffset.Y * Y + EffectOffset.Z * Z); arcsRemaining = NumArcs; tmpHitEmitClass = HitEmitterClass; tmpTraceRange = TraceRange; ReflectNum = 0; while (true) { bDoReflect = false; X = Vector(Dir); End = Start + tmpTraceRange * X; Other = Weapon.Trace(HitLocation, HitNormal, End, Start, true); if ( Other != None && (Other != Instigator || ReflectNum > 0) ) { if (bReflective && Other.IsA('xPawn') && xPawn(Other).CheckReflect(HitLocation, RefNormal, DamageMin*0.25)) { bDoReflect = true; } else if ( Other != mainArcHitTarget ) { if ( !Other.bWorldGeometry ) { Damage = (DamageMin + Rand(DamageMax - DamageMin)) * DamageAtten; if (Vehicle(Other) != None) HeadShotPawn = Vehicle(Other).CheckForHeadShot(HitLocation, X, 1.0); if (HeadShotPawn != None) HeadShotPawn.TakeDamage(Damage * HeadShotDamageMult, Instigator, HitLocation, Momentum*X, DamageTypeHeadShot); else if ( (Pawn(Other) != None) && (arcsRemaining == NumArcs) && Pawn(Other).IsHeadShot(HitLocation, X, 1.0) ) Other.TakeDamage(Damage * HeadShotDamageMult, Instigator, HitLocation, Momentum*X, DamageTypeHeadShot); else { if ( arcsRemaining < NumArcs ) Damage *= SecDamageMult; Other.TakeDamage(Damage, Instigator, HitLocation, Momentum*X, DamageType); } } else HitLocation = HitLocation + 2.0 * HitNormal; } } else { HitLocation = End; HitNormal = Normal(Start - End); } if ( Weapon == None ) return; hitEmitter = xEmitter(Weapon.Spawn(tmpHitEmitClass,,, arcEnd, Rotator(HitNormal))); if ( hitEmitter != None ) hitEmitter.mSpawnVecA = HitLocation; if ( HitScanBlockingVolume(Other) != None ) return; if( arcsRemaining == NumArcs ) { mainArcHit = HitLocation + (HitNormal * 2.0); if ( Other != None && !Other.bWorldGeometry ) mainArcHitTarget = Other; } if (bDoReflect && ++ReflectNum < 4) { //Log("reflecting off"@Other@Start@HitLocation); Start = HitLocation; Dir = Rotator( X - 2.0*RefNormal*(X dot RefNormal) ); } else if ( arcsRemaining > 0 ) { arcsRemaining--; // done parent arc, now move trace point to arc trace hit location and try child arcs from there Start = mainArcHit; Dir = Rotator(VRand()); tmpHitEmitClass = SecHitEmitterClass; tmpTraceRange = SecTraceDist; arcEnd = mainArcHit; } else { break; } } } function PlayFiring() { Super.PlayFiring(); if ( Weapon.AmmoAmount(0) > 0 ) Weapon.PlayOwnedSound(Sound'WeaponSounds.LightningGunChargeUp', SLOT_Misc,,,,1.1,false); } Y%Lclass SniperAttachment extends xWeaponAttachment; var() LightningCharge3rd charge; simulated function Destroyed() { if (charge != None) charge.Destroy(); Super.Destroyed(); } simulated event ThirdPersonEffects() { if ( Level.NetMode != NM_DedicatedServer ) { if (charge == None) { charge = Spawn(class'LightningCharge3rd'); AttachToBone(charge, 'tip'); } WeaponLight(); } Super.ThirdPersonEffects(); } Y%1class SniperAmmoPickup extends UTAmmoPickup; Y%Uclass SniperAmmo extends Ammunition; #EXEC OBJ LOAD FILE=InterfaceContent.utx Y%B7//============================================================================= // ShockRiflePickup //============================================================================= class ShockRiflePickup extends UTWeaponPickup; static function StaticPrecache(LevelInfo L) { if ( class'ShockRifle'.Default.bUseOldWeaponMesh ) { L.AddPrecacheMaterial(Texture'WeaponSkins.Skins.ShockTex0'); L.AddPrecacheMaterial(Texture'WeaponSkins.ShockLaser.lasermist'); } L.AddPrecacheMaterial(Material'XEffects.ShockHeatDecal'); L.AddPrecacheMaterial(Material'XEffectMat.shock_flash'); L.AddPrecacheMaterial(Material'XEffectMat.shock_flare_a'); L.AddPrecacheMaterial(Material'XEffectMat.shock_core'); L.AddPrecacheMaterial(Material'XEffectMat.purple_line'); L.AddPrecacheMaterial(Material'XEffectMat.shock_sparkle'); L.AddPrecacheMaterial(Material'XEffectMat.shock_core_low'); L.AddPrecacheMaterial(Material'XEffectMat.shock_Energy_green_faded'); L.AddPrecacheMaterial(Material'XEffectMat.Shock_Elec_a'); L.AddPrecacheMaterial(Material'XEffectMat.shock_gradient_b'); L.AddPrecacheMaterial(Material'XEffectMat.Shock_ring_a'); L.AddPrecacheMaterial(Material'XEffectMat.ShockComboFlash'); L.AddPrecacheMaterial(Material'XGameShaders.shock_muzflash_1st'); L.AddPrecacheMaterial(Material'XGameShaders.WeaponShaders.shock_muzflash_3rd'); L.AddPrecacheMaterial(Material'XWeapons_rc.ShockBeamTex'); L.AddPrecacheMaterial(Material'XEffects.SaDScorcht'); L.AddPrecacheMaterial(Material'DeployableTex.C_T_Electricity_SG'); L.AddPrecacheMaterial(Material'UT2004Weapons.ShockRipple'); L.AddPrecacheStaticMesh(StaticMesh'Editor.TexPropSphere'); L.AddPrecacheStaticMesh(StaticMesh'NewWeaponPickups.ShockPickupSM'); } simulated function UpdatePrecacheMaterials() { if ( class'ShockRifle'.Default.bUseOldWeaponMesh ) { Level.AddPrecacheMaterial(Texture'WeaponSkins.Skins.ShockTex0'); Level.AddPrecacheMaterial(Texture'WeaponSkins.ShockLaser.lasermist'); } Level.AddPrecacheMaterial(Material'XEffects.ShockHeatDecal'); Level.AddPrecacheMaterial(Material'XEffectMat.shock_flash'); Level.AddPrecacheMaterial(Material'XEffectMat.shock_flare_a'); Level.AddPrecacheMaterial(Material'XEffectMat.shock_core'); Level.AddPrecacheMaterial(Material'XEffectMat.purple_line'); Level.AddPrecacheMaterial(Material'XEffectMat.shock_sparkle'); Level.AddPrecacheMaterial(Material'XEffectMat.shock_core_low'); Level.AddPrecacheMaterial(Material'XEffectMat.shock_Energy_green_faded'); Level.AddPrecacheMaterial(Material'XEffectMat.Shock_Elec_a'); Level.AddPrecacheMaterial(Material'XEffectMat.shock_gradient_b'); Level.AddPrecacheMaterial(Material'XEffectMat.Shock_ring_a'); Level.AddPrecacheMaterial(Material'XEffectMat.ShockComboFlash'); Level.AddPrecacheMaterial(Material'XGameShaders.shock_muzflash_1st'); Level.AddPrecacheMaterial(Material'XGameShaders.WeaponShaders.shock_muzflash_3rd'); Level.AddPrecacheMaterial(Material'XWeapons_rc.ShockBeamTex'); Level.AddPrecacheMaterial(Material'DeployableTex.C_T_Electricity_SG'); Level.AddPrecacheMaterial(Material'XEffects.SaDScorcht'); Level.AddPrecacheMaterial(Material'UT2004Weapons.ShockRipple'); super.UpdatePrecacheMaterials(); } simulated function UpdatePrecacheStaticMeshes() { Level.AddPrecacheStaticMesh(StaticMesh'Editor.TexPropSphere'); Super.UpdatePrecacheStaticMeshes(); } Y%JG//============================================================================= // Shock Rifle //============================================================================= class ShockRifle extends Weapon config(user); #EXEC OBJ LOAD FILE=InterfaceContent.utx #exec OBJ LOAD FILE=..\Sounds\WeaponSounds.uax #exec OBJ LOAD FILE=XEffectMat.utx #exec OBJ LOAD FILE=UT2004Weapons.utx var ShockProjectile ComboTarget; // used by AI var bool bRegisterTarget; var bool bWaitForCombo; var vector ComboStart; var color EffectColor; simulated function PostBeginPlay() { ConstantColor'UT2004Weapons.ShockControl'.Color = EffectColor; Super.PostBeginPlay(); } simulated event RenderOverlays( Canvas Canvas ) { local float A; A = 128 * (1.0 - FMax(0,FMax((FireMode[0].NextFireTime - Level.TimeSeconds)/FireMode[0].FireRate, (FireMode[1].NextFireTime - Level.TimeSeconds)/FireMode[1].FireRate))); ConstantColor'UT2004Weapons.ShockControl'.Color.A = A; Super.RenderOverlays(Canvas); } simulated function vector GetEffectStart() { local Coords C; if ( Instigator.IsFirstPerson() ) { if ( WeaponCentered() ) return CenteredEffectStart(); C = GetBoneCoords('tip'); return C.Origin - 15 * C.XAxis; } return Super.GetEffectStart(); } simulated function bool WeaponCentered() { return ( bSpectated || (Hand > 1) ); } // AI Interface function float GetAIRating() { local Bot B; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( B.Enemy == None ) { if ( (B.Target != None) && VSize(B.Target.Location - B.Pawn.Location) > 8000 ) return 0.9; return AIRating; } if ( bWaitForCombo ) return 1.5; if ( !B.ProficientWithWeapon() ) return AIRating; if ( B.Stopped() ) { if ( !B.EnemyVisible() && (VSize(B.Enemy.Location - Instigator.Location) < 5000) ) return (AIRating + 0.5); return (AIRating + 0.3); } else if ( VSize(B.Enemy.Location - Instigator.Location) > 1600 ) return (AIRating + 0.1); else if ( B.Enemy.Location.Z > B.Location.Z + 200 ) return (AIRating + 0.15); return AIRating; } function SetComboTarget(ShockProjectile S) { if ( !bRegisterTarget || (bot(Instigator.Controller) == None) || (Instigator.Controller.Enemy == None) ) return; bRegisterTarget = false; ComboStart = Instigator.Location; ComboTarget = S; ComboTarget.Monitor(Bot(Instigator.Controller).Enemy); } function float RangedAttackTime() { local bot B; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 0; if ( B.CanComboMoving() ) return 0; return FMin(2,0.3 + VSize(B.Enemy.Location - Instigator.Location)/class'ShockProjectile'.default.Speed); } function float SuggestAttackStyle() { return -0.4; } simulated function bool StartFire(int mode) { if ( bWaitForCombo && (Bot(Instigator.Controller) != None) ) { if ( (ComboTarget == None) || ComboTarget.bDeleteMe ) bWaitForCombo = false; else return false; } return Super.StartFire(mode); } function DoCombo() { if ( bWaitForCombo ) { bWaitForCombo = false; if ( (Instigator != None) && (Instigator.Weapon == self) ) StartFire(0); } } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { local float EnemyDist, MaxDist; local bot B; bWaitForCombo = false; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 0; if (B.IsShootingObjective()) return 0; if ( !B.EnemyVisible() ) { if ( (ComboTarget != None) && !ComboTarget.bDeleteMe && B.CanCombo() ) { bWaitForCombo = true; return 0; } ComboTarget = None; if ( B.CanCombo() && B.ProficientWithWeapon() ) { bRegisterTarget = true; return 1; } return 0; } EnemyDist = VSize(B.Enemy.Location - Instigator.Location); if ( B.Skill > 5 ) MaxDist = 4 * class'ShockProjectile'.default.Speed; else MaxDist = 3 * class'ShockProjectile'.default.Speed; if ( (EnemyDist > MaxDist) || (EnemyDist < 150) ) { ComboTarget = None; return 0; } if ( (ComboTarget != None) && !ComboTarget.bDeleteMe && B.CanCombo() ) { bWaitForCombo = true; return 0; } ComboTarget = None; if ( (EnemyDist > 2500) && (FRand() < 0.5) ) return 0; if ( B.CanCombo() && B.ProficientWithWeapon() ) { bRegisterTarget = true; return 1; } if ( FRand() < 0.7 ) return 0; return 1; } // end AI Interface Y%jclass ShockProjFire extends ProjectileFire; function InitEffects() { Super.InitEffects(); if ( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'tip'); } // for bot combos function projectile SpawnProjectile(Vector Start, Rotator Dir) { local Projectile p; p = Super.SpawnProjectile(Start,Dir); if ( (ShockRifle(Instigator.Weapon) != None) && (p != None) ) ShockRifle(Instigator.Weapon).SetComboTarget(ShockProjectile(P)); return p; } Y%OM//============================================================================= // ShockProjectile. //============================================================================= class ShockProjectile extends Projectile; var() Sound ComboSound; var() float ComboDamage; var() float ComboRadius; var() float ComboMomentumTransfer; var ShockBall ShockBallEffect; var() int ComboAmmoCost; var class ComboDamageType; var Pawn ComboTarget; // for AI use var Vector tempStartLoc; simulated event PreBeginPlay() { Super.PreBeginPlay(); if( Pawn(Owner) != None ) Instigator = Pawn( Owner ); } simulated function PostBeginPlay() { Super.PostBeginPlay(); if ( Level.NetMode != NM_DedicatedServer ) { ShockBallEffect = Spawn(class'ShockBall', self); ShockBallEffect.SetBase(self); } Velocity = Speed * Vector(Rotation); // starts off slower so combo can be done closer SetTimer(0.4, false); tempStartLoc = Location; } simulated function PostNetBeginPlay() { local PlayerController PC; Super.PostNetBeginPlay(); if ( Level.NetMode == NM_DedicatedServer ) return; PC = Level.GetLocalPlayerController(); if ( (Instigator != None) && (PC == Instigator.Controller) ) return; if ( Level.bDropDetail || (Level.DetailMode == DM_Low) ) { bDynamicLight = false; LightType = LT_None; } else if ( (PC == None) || (PC.ViewTarget == None) || (VSize(PC.ViewTarget.Location - Location) > 3000) ) { bDynamicLight = false; LightType = LT_None; } } function Timer() { SetCollisionSize(20, 20); } simulated function Destroyed() { if (ShockBallEffect != None) { if ( bNoFX ) ShockBallEffect.Destroy(); else ShockBallEffect.Kill(); } Super.Destroyed(); } simulated function DestroyTrails() { if (ShockBallEffect != None) ShockBallEffect.Destroy(); } simulated function ProcessTouch (Actor Other, vector HitLocation) { local Vector X, RefNormal, RefDir; if (Other == Instigator) return; if (Other == Owner) return; if (Other.IsA('xPawn') && xPawn(Other).CheckReflect(HitLocation, RefNormal, Damage*0.25)) { if (Role == ROLE_Authority) { X = Normal(Velocity); RefDir = X - 2.0*RefNormal*(X dot RefNormal); RefDir = RefNormal; Spawn(Class, Other,, HitLocation+RefDir*20, Rotator(RefDir)); } DestroyTrails(); Destroy(); } else if ( !Other.IsA('Projectile') || Other.bProjTarget ) { Explode(HitLocation, Normal(HitLocation-Other.Location)); if ( ShockProjectile(Other) != None ) ShockProjectile(Other).Explode(HitLocation,Normal(Other.Location - HitLocation)); } } simulated function Explode(vector HitLocation,vector HitNormal) { if ( Role == ROLE_Authority ) { HurtRadius(Damage, DamageRadius, MyDamageType, MomentumTransfer, HitLocation ); } PlaySound(ImpactSound, SLOT_Misc); if ( EffectIsRelevant(Location,false) ) { Spawn(class'ShockExplosionCore',,, Location); if ( !Level.bDropDetail && (Level.DetailMode != DM_Low) ) Spawn(class'ShockExplosion',,, Location); } SetCollisionSize(0.0, 0.0); Destroy(); } event TakeDamage( int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, class DamageType) { if (DamageType == ComboDamageType) { Instigator = EventInstigator; SuperExplosion(); if( EventInstigator.Weapon != None ) { EventInstigator.Weapon.ConsumeAmmo(0, ComboAmmoCost, true); Instigator = EventInstigator; } } } function SuperExplosion() { local actor HitActor; local vector HitLocation, HitNormal; HurtRadius(ComboDamage, ComboRadius, class'DamTypeShockCombo', ComboMomentumTransfer, Location ); Spawn(class'ShockCombo'); if ( (Level.NetMode != NM_DedicatedServer) && EffectIsRelevant(Location,false) ) { HitActor = Trace(HitLocation, HitNormal,Location - Vect(0,0,120), Location,false); if ( HitActor != None ) Spawn(class'ComboDecal',self,,HitLocation, rotator(vect(0,0,-1))); } PlaySound(ComboSound, SLOT_None,1.0,,800); DestroyTrails(); Destroy(); } function Monitor(Pawn P) { ComboTarget = P; if ( ComboTarget != None ) GotoState('WaitForCombo'); } State WaitForCombo { function Tick(float DeltaTime) { if ( (ComboTarget == None) || ComboTarget.bDeleteMe || (Instigator == None) || (ShockRifle(Instigator.Weapon) == None) ) { GotoState(''); return; } if ( (VSize(ComboTarget.Location - Location) <= 0.5 * ComboRadius + ComboTarget.CollisionRadius) || ((Velocity Dot (ComboTarget.Location - Location)) <= 0) ) { ShockRifle(Instigator.Weapon).DoCombo(); GotoState(''); return; } } } Y%Mclass ShockBeamFire extends InstantFire; var() class BeamEffectClass; #exec OBJ LOAD FILE=..\Sounds\WeaponSounds.uax function DoFireEffect() { local Vector StartTrace,X,Y,Z; local Rotator R, Aim; Instigator.MakeNoise(1.0); StartTrace = Instigator.Location + Instigator.EyePosition(); if ( PlayerController(Instigator.Controller) != None ) { // for combos Weapon.GetViewAxes(X,Y,Z); StartTrace = StartTrace + X*class'ShockProjFire'.Default.ProjSpawnOffset.X; if ( !Weapon.WeaponCentered() ) StartTrace = StartTrace + Weapon.Hand * Y*class'ShockProjFire'.Default.ProjSpawnOffset.Y + Z*class'ShockProjFire'.Default.ProjSpawnOffset.Z; } Aim = AdjustAim(StartTrace, AimError); R = rotator(vector(Aim) + VRand()*FRand()*Spread); DoTrace(StartTrace, R); } function InitEffects() { if ( Level.DetailMode == DM_Low ) FlashEmitterClass = None; Super.InitEffects(); if ( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'tip'); } // for bot combos function Rotator AdjustAim(Vector Start, float InAimError) { if ( (ShockRifle(Weapon) != None) && (ShockRifle(Weapon).ComboTarget != None) ) return Rotator(ShockRifle(Weapon).ComboTarget.Location - Start); return Super.AdjustAim(Start, InAimError); } function SpawnBeamEffect(Vector Start, Rotator Dir, Vector HitLocation, Vector HitNormal, int ReflectNum) { local ShockBeamEffect Beam; if (Weapon != None) { Beam = Weapon.Spawn(BeamEffectClass,,, Start, Dir); if (ReflectNum != 0) Beam.Instigator = None; // prevents client side repositioning of beam start Beam.AimAt(HitLocation, HitNormal); } } Y%Y&class ShockBeamEffect extends xEmitter; var Vector HitNormal; var class CoilClass; var class MuzFlashClass; var class MuzFlash3Class; replication { reliable if (bNetInitial && Role == ROLE_Authority) HitNormal; } function AimAt(Vector hl, Vector hn) { HitNormal = hn; mSpawnVecA = hl; if (Level.NetMode != NM_DedicatedServer) SpawnEffects(); } simulated function PostNetBeginPlay() { if (Role < ROLE_Authority) SpawnEffects(); } simulated function SpawnImpactEffects(rotator HitRot, vector EffectLoc) { Spawn(class'ShockImpactFlare',,, EffectLoc, HitRot); Spawn(class'ShockImpactRing',,, EffectLoc, HitRot); Spawn(class'ShockImpactScorch',,, EffectLoc, Rotator(-HitNormal)); Spawn(class'ShockExplosionCore',,, EffectLoc+HitNormal*8, HitRot); } simulated function bool CheckMaxEffectDistance(PlayerController P, vector SpawnLocation) { return !P.BeyondViewDistance(SpawnLocation,3000); } simulated function SpawnEffects() { local ShockBeamCoil Coil; local xWeaponAttachment Attachment; if (Instigator != None) { if ( Instigator.IsFirstPerson() ) { if ( (Instigator.Weapon != None) && (Instigator.Weapon.Instigator == Instigator) ) SetLocation(Instigator.Weapon.GetEffectStart()); else SetLocation(Instigator.Location); Spawn(MuzFlashClass,,, Location); } else { Attachment = xPawn(Instigator).WeaponAttachment; if (Attachment != None && (Level.TimeSeconds - Attachment.LastRenderTime) < 1) SetLocation(Attachment.GetTipLocation()); else SetLocation(Instigator.Location + Instigator.EyeHeight*Vect(0,0,1) + Normal(mSpawnVecA - Instigator.Location) * 25.0); Spawn(MuzFlash3Class); } } if ( EffectIsRelevant(mSpawnVecA + HitNormal*2,false) && (HitNormal != Vect(0,0,0)) ) SpawnImpactEffects(Rotator(HitNormal),mSpawnVecA + HitNormal*2); if ( (!Level.bDropDetail && (Level.DetailMode != DM_Low) && (VSize(Location - mSpawnVecA) > 40) && !Level.GetLocalPlayerController().BeyondViewDistance(Location,0)) || ((Instigator != None) && Instigator.IsFirstPerson()) ) { Coil = Spawn(CoilClass,,, Location, Rotation); if (Coil != None) Coil.mSpawnVecA = mSpawnVecA; } } Y%3class ShockBeamCoilBlue extends ShockBeamCoil; Y%b 4Y%uclass ShockAttachment extends xWeaponAttachment; var class MuzFlashClass; var xEmitter MuzFlash; simulated function PostNetBeginPlay() { Super.PostNetBeginPlay(); if ( (Instigator != None) && (Instigator.PlayerReplicationInfo != None)&& (Instigator.PlayerReplicationInfo.Team != None) ) { if ( Instigator.PlayerReplicationInfo.Team.TeamIndex == 0 ) Skins[1] = Material'UT2004Weapons.RedShockFinal'; else if ( Instigator.PlayerReplicationInfo.Team.TeamIndex == 1 ) Skins[1] = Material'UT2004Weapons.BlueShockFinal'; } } simulated function Destroyed() { if (MuzFlash != None) MuzFlash.Destroy(); Super.Destroyed(); } simulated event ThirdPersonEffects() { local rotator r; if ( Level.NetMode != NM_DedicatedServer && FlashCount > 0 ) { if ( FiringMode == 0 ) WeaponLight(); else { if (MuzFlash == None) { MuzFlash = Spawn(MuzFlashClass); AttachToBone(MuzFlash, 'tip'); } if (MuzFlash != None) { MuzFlash.mStartParticles++; r.Roll = Rand(65536); SetBoneRotation('Bone_Flash', r, 0, 1.f); } } } Super.ThirdPersonEffects(); } Y%1class ShockAmmoPickup extends UTAmmoPickup; Y%Tclass ShockAmmo extends Ammunition; #EXEC OBJ LOAD FILE=InterfaceContent.utx Y%T"]&\?w* a(-($[w5*5-(rw$*$a]%],w]"*]"a]y GY%i//============================================================================= // ShieldGunPickup. //============================================================================= class ShieldGunPickup extends UTWeaponPickup; Y%t,a Cx 89:9:$r*r*a rCp%9:9:$w*ur5*5a w5*5a%r* HJ(Z*M %rZ*n Z*a 9:t, y~9:t9:g 9:'9:j  w5r*%%?9?&?9?&v9:t&,9:9:$%,v-9:9:$dr"*"a 7%"@@9?vw"*"aS9:'%9:t%% w5*%5 $(P% Hw5*%5 $d9:'&% w5*%5 $% w5*%5 $/w5*%5%5?9?&&5%54C9?,(@9?,w*L 9:t9:'%-9:'%9?,]9:'% wr*]r$*9:9:$$a ]9:',%$ g tj 'r*5-9:9:$-($-$wr*Jr r#?CAJ--k 9:'%-k 9:'%9?,@a &j a( #??@n 9999@ v j  ף<n @??a Av  @ %jv`w"*C&"a "a+" "?"9?C@A9?C@A"-9:'%%"%C w*a JC A-Aa+ a+9PC% & -' 9:'% wr* w$*$a J$a+$-( ru%$A %$ B&$%$  w$*$-' -A9:9:$B )\=B `aq m J9?,dCJ9?,dC' w`*`-a q 9Pm  GY%cj//============================================================================= // Shield Gun //============================================================================= class ShieldGun extends Weapon config(user) HideDropDown; #EXEC OBJ LOAD FILE=InterfaceContent.utx var Sound ShieldHitSound; var String ShieldHitForce; replication { reliable if (Role == ROLE_Authority) ClientTakeHit; } simulated function DoAutoSwitch() { } simulated function vector CenteredEffectStart() { local Vector X,Y,Z; GetViewAxes(X, Y, Z); return (Instigator.Location + Instigator.CalcDrawOffset(self) + EffectOffset.X * X + EffectOffset.Z * Z); } simulated event RenderOverlays( Canvas Canvas ) { local int m; if ((Hand < -1.0) || (Hand > 1.0)) { for (m = 0; m < NUM_FIRE_MODES; m++) { if (FireMode[m] != None) { FireMode[m].DrawMuzzleFlash(Canvas); } } } Super.RenderOverlays(Canvas); } // AI Interface function GiveTo(Pawn Other, optional Pickup Pickup) { Super.GiveTo(Other, Pickup); if ( Bot(Other.Controller) != None ) Bot(Other.Controller).bHasImpactHammer = true; } function bool CanAttack(Actor Other) { return true; } simulated function BringUp(optional Weapon PrevWeapon) { Super.Bringup(PrevWeapon); if ( !AmmoMaxed(1) ) { while ( (FireMode[1].NextTimerPop < Level.TimeSeconds) && (FireMode[1].TimerInterval > 0.f) ) { FireMode[1].Timer(); if ( FireMode[1].bTimerLoop ) FireMode[1].NextTimerPop = FireMode[1].NextTimerPop + FireMode[1].TimerInterval; else FireMode[1].TimerInterval = 0.f; } } } simulated function Timer() { local Bot B; if (ClientState == WS_BringUp) { // check if owner is bot waiting to do impact jump B = Bot(Instigator.Controller); if ( (B != None) && B.bPreparingMove && (B.ImpactTarget != None) ) { B.ImpactJump(); B = None; } } Super.Timer(); if ( (B != None) && (B.Enemy != None) ) BotFire(false); } function FireHack(byte Mode) { if ( Mode == 0 ) { FireMode[0].PlayFiring(); FireMode[0].FlashMuzzleFlash(); FireMode[0].StartMuzzleSmoke(); IncrementFlashCount(0); } } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { local float EnemyDist; local bot B; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 1; if ( B.bShieldSelf && B.ShouldKeepShielding() ) return 1; EnemyDist = VSize(B.Enemy.Location - Instigator.Location); if ( EnemyDist > 4 * Instigator.GroundSpeed ) return 1; if ( (B.MoveTarget != B.Enemy) && (B.IsRetreating() || (EnemyDist > 2 * Instigator.GroundSpeed)) ) return 1; return 0; } // super desireable for bot waiting to impact jump function float GetAIRating() { local Bot B; local float EnemyDist; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( B.bShieldSelf && B.ShouldKeepShielding() ) return 9; if ( B.bPreparingMove && (B.ImpactTarget != None) ) return 9; if ( B.PlayerReplicationInfo.HasFlag != None ) { if ( Instigator.Health < 50 ) return AIRating + 0.35; return AIRating + 0.25; } if ( B.Enemy == None ) return AIRating; EnemyDist = VSize(B.Enemy.Location - Instigator.Location); if ( B.Stopped() && (EnemyDist > 100) ) return 0.1; if ( (EnemyDist < 750) && (B.Skill <= 2) && !B.Enemy.IsA('Bot') && (ShieldGun(B.Enemy.Weapon) != None) ) return FClamp(300/(EnemyDist + 1), 0.6, 0.75); if ( EnemyDist > 400 ) return 0.1; if ( (Instigator.Weapon != self) && (EnemyDist < 120) ) return 0.25; return ( FMin(0.6, 90/(EnemyDist + 1)) ); } // End AI interface function AdjustPlayerDamage( out int Damage, Pawn InstigatedBy, Vector HitLocation, out Vector Momentum, class DamageType) { local int Drain; local vector Reflect; local vector HitNormal; local float DamageMax; DamageMax = 100.0; if ( DamageType == class'Fell' ) DamageMax = 20.0; else if( !DamageType.default.bArmorStops || (DamageType == class'DamTypeShieldImpact' && InstigatedBy == Instigator) ) return; if ( CheckReflect(HitLocation, HitNormal, 0) ) { Drain = Min( AmmoAmount(1)*2, Damage ); Drain = Min(Drain,DamageMax); Reflect = MirrorVectorByNormal( Normal(Location - HitLocation), Vector(Instigator.Rotation) ); Damage -= Drain; Momentum *= 1.25; if ( (Instigator != None) && (Instigator.PlayerReplicationInfo != None) && (Instigator.PlayerReplicationInfo.HasFlag != None) ) { Drain = Min(AmmoAmount(1), Drain); ConsumeAmmo(1,Drain); DoReflectEffect(Drain); } else { ConsumeAmmo(1,Drain/2); DoReflectEffect(Drain/2); } } } function DoReflectEffect(int Drain) { PlaySound(ShieldHitSound, SLOT_None); ShieldAltFire(FireMode[1]).TakeHit(Drain); ClientTakeHit(Drain); } simulated function ClientTakeHit(int Drain) { ClientPlayForceFeedback(ShieldHitForce); ShieldAltFire(FireMode[1]).TakeHit(Drain); } simulated function float AmmoStatus(optional int Mode) // returns float value for ammo amount { if ( Instigator == None || Instigator.Weapon != self ) { if ( (FireMode[1].TimerInterval != 0.f) && (FireMode[1].NextTimerPop < Level.TimeSeconds) ) { FireMode[1].Timer(); if ( FireMode[1].bTimerLoop ) FireMode[1].NextTimerPop = FireMode[1].NextTimerPop + FireMode[1].TimerInterval; else FireMode[1].TimerInterval = 0.f; } } return Super.AmmoStatus(Mode); } function bool CheckReflect( Vector HitLocation, out Vector RefNormal, int AmmoDrain ) { local Vector HitDir; local Vector FaceDir; if (!FireMode[1].bIsFiring || AmmoAmount(0) == 0) return false; FaceDir = Vector(Instigator.Controller.Rotation); HitDir = Normal(Instigator.Location - HitLocation + Vect(0,0,8)); //Log(self@"HitDir"@(FaceDir dot HitDir)); RefNormal = FaceDir; if ( FaceDir dot HitDir < -0.37 ) // 68 degree protection arc { if (AmmoDrain > 0) ConsumeAmmo(0,AmmoDrain); return true; } return false; } function AnimEnd(int channel) { if (FireMode[0].bIsFiring) { LoopAnim('Charged'); } else if (!FireMode[1].bIsFiring) { Super.AnimEnd(channel); } } function float SuggestAttackStyle() { return 0.8; } function float SuggestDefenseStyle() { return -0.8; } simulated function float ChargeBar() { return FMin(1,FireMode[0].HoldTime/ShieldFire(FireMode[0]).FullyChargedTime); } Y%_yclass ShieldFire extends WeaponFire; var class DamageType; // weapon fire damage type (no projectile, so we put this here) var float ShieldRange; // from pawn centre var float MinHoldTime; // held for this time or less will do minimum damage/force. held for MaxHoldTime will do max var float MinForce, MaxForce; // force to other players var float MinDamage, MaxDamage; // damage to other players var float SelfForceScale; // %force to self (when shielding a wall) var float SelfDamageScale; // %damage to self (when shielding a wall) var float MinSelfDamage; var Sound ChargingSound; // charging sound var xEmitter ChargingEmitter; // emitter class while charging var float AutoFireTestFreq; var float FullyChargedTime; // held for this long will do max damage var bool bAutoRelease; var bool bStartedChargingForce; var byte ChargingSoundVolume; var Pawn AutoHitPawn; var float AutoHitTime; // jdf --- var String ChargingForce; // --- jdf simulated function DestroyEffects() { if (ChargingEmitter != None) ChargingEmitter.Destroy(); Super.DestroyEffects(); } simulated function InitEffects() { if ( Level.NetMode != NM_DedicatedServer ) { ChargingEmitter = Weapon.Spawn(class'XEffects.ShieldCharge'); ChargingEmitter.mRegenPause = true; } bStartedChargingForce = false; // jdf Super.InitEffects(); } function DrawMuzzleFlash(Canvas Canvas) { if (ChargingEmitter != None && HoldTime > 0.0 && !bNowWaiting) { ChargingEmitter.SetLocation( Weapon.GetEffectStart() ); Canvas.DrawActor( ChargingEmitter, false, false, Weapon.DisplayFOV ); } if (FlashEmitter != None) { FlashEmitter.SetLocation( Weapon.GetEffectStart() ); if ( Weapon.WeaponCentered() ) FlashEmitter.SetRotation(Weapon.Instigator.GetViewRotation()); else FlashEmitter.SetRotation(Weapon.Rotation); Canvas.DrawActor( FlashEmitter, false, false, Weapon.DisplayFOV ); } if ( (Instigator.AmbientSound == ChargingSound) && ((HoldTime <= 0.0) || bNowWaiting) ) { Instigator.AmbientSound = None; Instigator.SoundVolume = Instigator.Default.SoundVolume; } } function Rotator AdjustAim(Vector Start, float InAimError) { local rotator Aim, EnemyAim; if ( AIController(Instigator.Controller) != None ) { Aim = Instigator.Rotation; if ( Instigator.Controller.Enemy != None ) { EnemyAim = rotator(Instigator.Controller.Enemy.Location - Start); Aim.Pitch = EnemyAim.Pitch; } return Aim; } else return super.AdjustAim(Start,InAimError); } function DoFireEffect() { local Vector HitLocation, HitNormal, StartTrace, EndTrace, X,Y,Z; local Rotator Aim; local Actor Other; local float Scale, Damage, Force; Instigator.MakeNoise(1.0); Weapon.GetViewAxes(X,Y,Z); bAutoRelease = false; if ( (AutoHitPawn != None) && (Level.TimeSeconds - AutoHitTime < 0.15) ) { Other = AutoHitPawn; HitLocation = Other.Location; AutoHitPawn = None; } else { StartTrace = Instigator.Location; Aim = AdjustAim(StartTrace, AimError); EndTrace = StartTrace + ShieldRange * Vector(Aim); Other = Weapon.Trace(HitLocation, HitNormal, EndTrace, StartTrace, true); } Scale = (FClamp(HoldTime, MinHoldTime, FullyChargedTime) - MinHoldTime) / (FullyChargedTime - MinHoldTime); // result 0 to 1 Damage = MinDamage + Scale * (MaxDamage - MinDamage); Force = MinForce + Scale * (MaxForce - MinForce); Instigator.AmbientSound = None; Instigator.SoundVolume = Instigator.Default.SoundVolume; if (ChargingEmitter != None) ChargingEmitter.mRegenPause = true; if ( Other != None && Other != Instigator ) { if ( Pawn(Other) != None || (Decoration(Other) != None && Decoration(Other).bDamageable) ) Other.TakeDamage(Damage, Instigator, HitLocation, Force*(X+vect(0,0,0.5)), DamageType); else { if ( xPawn(Instigator).bBerserk ) Force *= 2.0; Instigator.TakeDamage(MinSelfDamage+SelfDamageScale*Damage, Instigator, HitLocation, -SelfForceScale*Force*X, DamageType); if ( DestroyableObjective(Other) != None ) Other.TakeDamage(Damage, Instigator, HitLocation, Force*(X+vect(0,0,0.5)), DamageType); } } SetTimer(0, false); } function ModeHoldFire() { SetTimer(AutoFireTestFreq, true); } function bool IsFiring() { return ( bIsFiring || bAutoRelease ); } function Timer() { local Actor Other; local Vector HitLocation, HitNormal, StartTrace, EndTrace; local Rotator Aim; local float Regen; local float ChargeScale; if (HoldTime > 0.0 && !bNowWaiting) { StartTrace = Instigator.Location; Aim = AdjustAim(StartTrace, AimError); EndTrace = StartTrace + ShieldRange * Vector(Aim); Other = Weapon.Trace(HitLocation, HitNormal, EndTrace, StartTrace, true); if ( (Pawn(Other) != None) && (Other != Instigator) ) { bAutoRelease = true; bIsFiring = false; Instigator.AmbientSound = None; Instigator.SoundVolume = Instigator.Default.SoundVolume; AutoHitPawn = Pawn(Other); AutoHitTime = Level.TimeSeconds; if (ChargingEmitter != None) ChargingEmitter.mRegenPause = true; } else { Instigator.AmbientSound = ChargingSound; Instigator.SoundVolume = ChargingSoundVolume; ChargeScale = FMin(HoldTime, FullyChargedTime); if (ChargingEmitter != None) { ChargingEmitter.mRegenPause = false; Regen = ChargeScale * 10 + 20; ChargingEmitter.mRegenRange[0] = Regen; ChargingEmitter.mRegenRange[1] = Regen; ChargingEmitter.mSpeedRange[0] = ChargeScale * -15.0; ChargingEmitter.mSpeedRange[1] = ChargeScale * -15.0; Regen = FMax((ChargeScale / 30.0),0.20); ChargingEmitter.mLifeRange[0] = Regen; ChargingEmitter.mLifeRange[1] = Regen; } if (!bStartedChargingForce) { bStartedChargingForce = true; ClientPlayForceFeedback( ChargingForce ); } } } else { if ( Instigator.AmbientSound == ChargingSound ) { Instigator.AmbientSound = None; Instigator.SoundVolume = Instigator.Default.SoundVolume; } SetTimer(0, false); } } simulated function vector GetFireStart(vector X, vector Y, vector Z) { return Instigator.Location; } function StartBerserk() { if ( (Level.GRI != None) && (Level.GRI.WeaponBerserk > 1.0) ) return; MaxHoldTime = default.MaxHoldTime * 0.75; FullyChargedTime = default.FullyChargedTime * 0.75; } function StopBerserk() { if ( (Level.GRI != None) && (Level.GRI.WeaponBerserk > 1.0) ) return; MaxHoldTime = default.MaxHoldTime; FullyChargedTime = default.FullyChargedTime; } function StartSuperBerserk() { MaxHoldTime = default.MaxHoldTime/Level.GRI.WeaponBerserk; FullyChargedTime = default.FullyChargedTime/Level.GRI.WeaponBerserk; MinDamage = Default.MinDamage * Level.GRI.WeaponBerserk; MaxDamage = Default.MaxDamage * Level.GRI.WeaponBerserk; } function PlayPreFire() { Weapon.PlayAnim('Charge', 1.0/FullyChargedTime, 0.1); } // jdf --- function PlayFiring() { bStartedChargingForce = false; StopForceFeedback(ChargingForce); Super.PlayFiring(); } // --- jdf Y%6class ShieldEffect3rdRED extends ShieldEffect3rd; Y%7class ShieldEffect3rdBLUE extends ShieldEffect3rd; Y%eclass ShieldEffect3rd extends AimedAttachment; #exec OBJ LOAD FILE=XEffectMat.utx var float Brightness, DesiredBrightness; var int HitCount, OldHitCount; var ShieldSparks Sparks; replication { unreliable if (Role == ROLE_Authority && !bHidden) HitCount; } simulated function Destroyed() { if (Sparks != None) Sparks.Destroy(); } simulated function Flash(int Drain) { if ( Level.NetMode != NM_DedicatedServer ) { if (Sparks == None) { Sparks = Spawn(class'ShieldSparks'); } if (Instigator != None && Instigator.IsFirstPerson()) { Sparks.SetLocation(Location+Vect(0,0,20)+VRand()*12.0); Sparks.SetRotation(Rotation); Sparks.mStartParticles = 16; } else if ( EffectIsRelevant(Location,false) ) { Sparks.SetLocation(Location+VRand()*8.0); Sparks.SetRotation(Rotation); Sparks.mStartParticles = 16; } } Brightness = FMin(Brightness + Drain / 2, 250.0); Skins[0] = Skins[1]; SetTimer(0.2, false); } simulated function Timer() { Skins[0] = default.Skins[0]; } function SetBrightness(int b, bool hit) // server only please { DesiredBrightness = FMin(50+b*2, 250.0); if (hit) { HitCount++; Flash(50); } } simulated function PostNetReceive() { if (OldHitCount == -1) { OldHitCount = HitCount; } else if (HitCount != OldHitCount) { Flash(50); OldHitCount = HitCount; } } Y%Xclass ShieldEffect extends Actor; #exec OBJ LOAD FILE=XEffectMat.utx var float Brightness, DesiredBrightness; function Flash(int Drain) { Brightness = FMin(Brightness + Drain / 2, 250.0); Skins[0] = Skins[1]; SetTimer(0.2, false); } function Timer() { Skins[0] = default.Skins[0]; } function SetBrightness(int b) { DesiredBrightness = FMin(50+b*2, 250.0); } Y%Aclass ShieldAttachment extends xWeaponAttachment; var ForceRing ForceRing3rd; var ShieldEffect3rd ShieldEffect3rd; replication { reliable if (bNetInitial && Role == ROLE_Authority) ShieldEffect3rd; } simulated function Destroyed() { if (ShieldEffect3rd != None) ShieldEffect3rd.Destroy(); if (ForceRing3rd != None) ForceRing3rd.Destroy(); Super.Destroyed(); } function InitFor(Inventory I) { Super.InitFor(I); if ( (Instigator.PlayerReplicationInfo == None) || (Instigator.PlayerReplicationInfo.Team == None) || (Instigator.PlayerReplicationInfo.Team.TeamIndex > 1) ) ShieldEffect3rd = Spawn(class'ShieldEffect3rd', I.Instigator); else if ( Instigator.PlayerReplicationInfo.Team.TeamIndex == 0 ) ShieldEffect3rd = Spawn(class'ShieldEffect3rdRED', I.Instigator); else ShieldEffect3rd = Spawn(class'ShieldEffect3rdBLUE', I.Instigator); ShieldEffect3rd.SetBase(I.Instigator); } simulated event ThirdPersonEffects() { if ( Level.NetMode != NM_DedicatedServer && FlashCount > 0 ) { if ( FiringMode == 0 ) { if (ForceRing3rd == None) { ForceRing3rd = Spawn(class'ForceRing'); AttachToBone(ForceRing3rd, 'tip'); } ForceRing3rd.Fire(); } } Super.ThirdPersonEffects(); } function SetBrightness(int b, bool hit) { if (ShieldEffect3rd != None) ShieldEffect3rd.SetBrightness(b, hit); } Y%)class ShieldAmmo extends Ammunition; Y%Q0class ShieldAltFire extends WeaponFire; var ShieldEffect ShieldEffect; var() float AmmoRegenTime; var() float ChargeupTime; var float RampTime; var Sound ChargingSound; // charging sound var() byte ShieldSoundVolume; simulated function DestroyEffects() { if ( Weapon.Role == ROLE_Authority ) { if ( ShieldEffect != None ) ShieldEffect.Destroy(); } Super.DestroyEffects(); } function DoFireEffect() { local ShieldAttachment Attachment; Attachment = ShieldAttachment(Weapon.ThirdPersonActor); Instigator.AmbientSound = ChargingSound; Instigator.SoundVolume = ShieldSoundVolume; if( Attachment != None && Attachment.ShieldEffect3rd != None ) Attachment.ShieldEffect3rd.bHidden = false; SetTimer(AmmoRegenTime, true); } function PlayFiring() { ClientPlayForceFeedback("ShieldNoise"); // jdf SetTimer(AmmoRegenTime, true); Weapon.LoopAnim('Shield'); } function StopFiring() { local ShieldAttachment Attachment; Attachment = ShieldAttachment(Weapon.ThirdPersonActor); Instigator.AmbientSound = None; Instigator.SoundVolume = Instigator.Default.SoundVolume; if( Attachment != None && Attachment.ShieldEffect3rd != None ) { Attachment.ShieldEffect3rd.bHidden = true; StopForceFeedback( "ShieldNoise" ); // jdf } SetTimer(AmmoRegenTime, true); } function TakeHit(int Drain) { if (ShieldEffect != None) { ShieldEffect.Flash(Drain); } SetBrightness(true); } function StartBerserk() { } function StopBerserk() { } function StartSuperBerserk() { } function SetBrightness(bool bHit) { local ShieldAttachment Attachment; local float Brightness; Brightness = Weapon.AmmoAmount(1); if ( RampTime < ChargeUpTime ) Brightness *= RampTime/ChargeUpTime; if (ShieldEffect != None) ShieldEffect.SetBrightness(Brightness); Attachment = ShieldAttachment(Weapon.ThirdPersonActor); if( Attachment != None ) Attachment.SetBrightness(Brightness, bHit); } function DrawMuzzleFlash(Canvas Canvas) { Super.DrawMuzzleFlash(Canvas); if (ShieldEffect == None) ShieldEffect = Weapon.Spawn(class'ShieldEffect', instigator); if ( bIsFiring && Weapon.AmmoAmount(1) > 0 ) { ShieldEffect.SetLocation( Weapon.GetEffectStart() ); ShieldEffect.SetRotation( Instigator.GetViewRotation() ); Canvas.DrawActor( ShieldEffect, false, false, Weapon.DisplayFOV ); } } function Timer() { if (!bIsFiring) { RampTime = 0; if ( !Weapon.AmmoMaxed(1) ) Weapon.AddAmmo(1,1); else SetTimer(0, false); } else { if ( !Weapon.ConsumeAmmo(1,1) ) { if (Weapon.ClientState == WS_ReadyToFire) Weapon.PlayIdle(); StopFiring(); } else RampTime += AmmoRegenTime; } SetBrightness(false); } Y%wclass SeekingRocketProj extends RocketProj; var Actor Seeking; var vector InitialDir; replication { reliable if( bNetInitial && (Role==ROLE_Authority) ) Seeking, InitialDir; } simulated function Timer() { local vector ForceDir; local float VelMag; if ( InitialDir == vect(0,0,0) ) InitialDir = Normal(Velocity); Acceleration = vect(0,0,0); Super.Timer(); if ( (Seeking != None) && (Seeking != Instigator) ) { // Do normal guidance to target. ForceDir = Normal(Seeking.Location - Location); if( (ForceDir Dot InitialDir) > 0 ) { VelMag = VSize(Velocity); // track vehicles better if ( Seeking.Physics == PHYS_Karma ) ForceDir = Normal(ForceDir * 0.8 * VelMag + Velocity); else ForceDir = Normal(ForceDir * 0.5 * VelMag + Velocity); Velocity = VelMag * ForceDir; Acceleration += 5 * ForceDir; } // Update rocket so it faces in the direction its going. SetRotation(rotator(Velocity)); } } simulated function PostBeginPlay() { Super.PostBeginPlay(); SetTimer(0.1, true); } Y%~@//============================================================================= // rocket. //============================================================================= class RocketProj extends Projectile; var bool bRing,bHitWater,bWaterStart; var int NumExtraRockets; var xEmitter SmokeTrail; var Effects Corona; var byte FlockIndex; var RocketProj Flock[2]; var() float FlockRadius; var() float FlockStiffness; var() float FlockMaxForce; var() float FlockCurlForce; var bool bCurl; var vector Dir; replication { reliable if ( bNetInitial && (Role == ROLE_Authority) ) FlockIndex, bCurl; } simulated function Destroyed() { if ( SmokeTrail != None ) SmokeTrail.mRegen = False; if ( Corona != None ) Corona.Destroy(); Super.Destroyed(); } simulated function PostBeginPlay() { if ( Level.NetMode != NM_DedicatedServer) { SmokeTrail = Spawn(class'RocketTrailSmoke',self); Corona = Spawn(class'RocketCorona',self); } Dir = vector(Rotation); Velocity = speed * Dir; if (PhysicsVolume.bWaterVolume) { bHitWater = True; Velocity=0.6*Velocity; } Super.PostBeginPlay(); } simulated function PostNetBeginPlay() { local RocketProj R; local int i; local PlayerController PC; Super.PostNetBeginPlay(); if ( FlockIndex != 0 ) { SetTimer(0.1, true); // look for other rockets if ( Flock[1] == None ) { ForEach DynamicActors(class'RocketProj',R) if ( R.FlockIndex == FlockIndex ) { Flock[i] = R; if ( R.Flock[0] == None ) R.Flock[0] = self; else if ( R.Flock[0] != self ) R.Flock[1] = self; i++; if ( i == 2 ) break; } } } if ( Level.NetMode == NM_DedicatedServer ) return; if ( Level.bDropDetail || (Level.DetailMode == DM_Low) ) { bDynamicLight = false; LightType = LT_None; } else { PC = Level.GetLocalPlayerController(); if ( (Instigator != None) && (PC == Instigator.Controller) ) return; if ( (PC == None) || (PC.ViewTarget == None) || (VSize(PC.ViewTarget.Location - Location) > 3000) ) { bDynamicLight = false; LightType = LT_None; } } } simulated function Landed( vector HitNormal ) { Explode(Location,HitNormal); } simulated function ProcessTouch (Actor Other, Vector HitLocation) { if ( (Other != instigator) && (!Other.IsA('Projectile') || Other.bProjTarget) ) Explode(HitLocation, vector(rotation)*-1 ); } function BlowUp(vector HitLocation) { HurtRadius(Damage, DamageRadius, MyDamageType, MomentumTransfer, HitLocation ); MakeNoise(1.0); } simulated function Explode(vector HitLocation, vector HitNormal) { local PlayerController PC; PlaySound(sound'WeaponSounds.BExplosion3',,2.5*TransientSoundVolume); if ( EffectIsRelevant(Location,false) ) { Spawn(class'NewExplosionA',,,HitLocation + HitNormal*20,rotator(HitNormal)); PC = Level.GetLocalPlayerController(); if ( (PC.ViewTarget != None) && VSize(PC.ViewTarget.Location - Location) < 5000 ) Spawn(class'ExplosionCrap',,, HitLocation + HitNormal*20, rotator(HitNormal)); // if ( (ExplosionDecal != None) && (Level.NetMode != NM_DedicatedServer) ) // Spawn(ExplosionDecal,self,,Location, rotator(-HitNormal)); } BlowUp(HitLocation); Destroy(); } simulated function Timer() { local vector ForceDir, CurlDir; local float ForceMag; local int i; Velocity = Default.Speed * Normal(Dir * 0.5 * Default.Speed + Velocity); // Work out force between flock to add madness for(i=0; i<2; i++) { if(Flock[i] == None) continue; // Attract if distance between rockets is over 2*FlockRadius, repulse if below. ForceDir = Flock[i].Location - Location; ForceMag = FlockStiffness * ( (2 * FlockRadius) - VSize(ForceDir) ); Acceleration = Normal(ForceDir) * Min(ForceMag, FlockMaxForce); // Vector 'curl' CurlDir = Flock[i].Velocity Cross ForceDir; if ( bCurl == Flock[i].bCurl ) Acceleration += Normal(CurlDir) * FlockCurlForce; else Acceleration -= Normal(CurlDir) * FlockCurlForce; } } Y%v> class RocketMultiFire extends ProjectileFire; var() float TightSpread, LooseSpread; var byte FlockIndex; var int MaxLoad; event ModeHoldFire() { if (Instigator.IsLocallyControlled()) PlayStartHold(); else ServerPlayLoading(); } simulated function ServerPlayLoading() { RocketLauncher(Weapon).PlayOwnedSound(Sound'WeaponSounds.RocketLauncher.RocketLauncherLoad', SLOT_None,,,,,false); } function PlayFireEnd() { } function PlayStartHold() { RocketLauncher(Weapon).PlayLoad(false); } function PlayFiring() { if (Load > 1.0) FireAnim = 'AltFire'; else FireAnim = 'Fire'; Super.PlayFiring(); RocketLauncher(Weapon).PlayFiring((Load == MaxLoad)); Weapon.OutOfAmmo(); } event ModeDoFire() { if ( RocketLauncher(Weapon).bTightSpread || ((Bot(Instigator.Controller) != None) && (FRand() < 0.65)) ) { Spread = TightSpread; SpreadStyle = SS_Ring; } else { SpreadStyle = SS_Line; Spread = LooseSpread; } RocketLauncher(Weapon).bTightSpread = false; Super.ModeDoFire(); NextFireTime = FMax(NextFireTime, Level.TimeSeconds + FireRate); } function DoFireEffect() { local Vector StartProj, StartTrace, X,Y,Z; local Rotator Aim; local Vector HitLocation, HitNormal,FireLocation; local Actor Other; local int p,q, SpawnCount, i; local RocketProj FiredRockets[4]; local bool bCurl; if ( (SpreadStyle == SS_Line) || (Load < 2) ) { 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); SpawnCount = Max(1, int(Load)); for ( p=0; p 0.0 && Load >= Weapon.AmmoAmount(ThisModeNum) && !bNowWaiting) { bIsFiring = false; } Super.ModeTick(dt); if (Load == 1.0 && HoldTime >= FireRate) { if (Instigator.IsLocallyControlled()) RocketLauncher(Weapon).PlayLoad(false); else ServerPlayLoading(); Load = Load + 1.0; } else if (Load == 2.0 && HoldTime >= FireRate*2.0) { Load = Load + 1.0; } } function InitEffects() { Super.InitEffects(); if ( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'tip'); } function Projectile SpawnProjectile(Vector Start, Rotator Dir) { local Projectile p; p = RocketLauncher(Weapon).SpawnProjectile(Start, Dir); if ( P != None ) p.Damage *= DamageAtten; return p; } Y%T//============================================================================= // RocketLauncherPickup. //============================================================================= class RocketLauncherPickup extends UTWeaponPickup; static function StaticPrecache(LevelInfo L) { L.AddPrecacheMaterial(Material'WeaponSkins.RocketShellTex'); L.AddPrecacheMaterial(Material'XEffects.RocketFlare'); L.AddPrecacheMaterial(Material'XEffects.SmokeAlphab_t'); L.AddPrecacheMaterial(Material'EmitterTextures.rockchunks02'); L.AddPrecacheMaterial(Material'EmitterTextures.fire3'); L.AddPrecacheMaterial(Material'EmitterTextures.LargeFlames'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.rocketproj'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.RocketLauncherPickup'); } simulated function UpdatePrecacheMaterials() { Level.AddPrecacheMaterial(Material'EmitterTextures.fire3'); Level.AddPrecacheMaterial(Material'EmitterTextures.LargeFlames'); Level.AddPrecacheMaterial(Material'WeaponSkins.RocketShellTex'); Level.AddPrecacheMaterial(Material'XEffects.RocketFlare'); Level.AddPrecacheMaterial(Material'XEffects.SmokeAlphab_t'); Level.AddPrecacheMaterial(Material'EmitterTextures.rockchunks02'); super.UpdatePrecacheMaterials(); } simulated function UpdatePrecacheStaticMeshes() { Level.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.rocketproj'); Super.UpdatePrecacheStaticMeshes(); } Y%a//============================================================================= // RocketLaucher //============================================================================= class RocketLauncher extends Weapon config(user); #EXEC OBJ LOAD FILE=InterfaceContent.utx const NUM_BARRELS = 3; const BARREL_ROTATION_RATE = 2.95; var float BarrelRotation; var float FinalRotation; var bool bRotateBarrel; var Pawn SeekTarget; var float LockTime, UnLockTime, SeekCheckTime; var bool bLockedOn, bBreakLock; var bool bTightSpread; 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) ServerSetTightSpread, ServerClearTightSpread; } 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(Sound'WeaponSounds.LockOn'); } } 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(Sound'WeaponSounds.SeekLost'); } } } 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); } function Projectile SpawnProjectile(Vector Start, Rotator Dir) { local RocketProj Rocket; local SeekingRocketProj SeekingRocket; local bot B; bBreakLock = true; // decide if bot should be locked on B = Bot(Instigator.Controller); if ( (B != None) && (B.Skill > 2 + 5 * FRand()) && (FRand() < 0.6) && (B.Target != None) && (B.Target == B.Enemy) && (VSize(B.Enemy.Location - B.Pawn.Location) > 2000 + 2000 * FRand()) && (Level.TimeSeconds - B.LastSeenTime < 0.4) && (Level.TimeSeconds - B.AcquireTime > 1.5) ) { bLockedOn = true; SeekTarget = B.Enemy; } if (bLockedOn && SeekTarget != None) { SeekingRocket = Spawn(class'SeekingRocketProj',,, Start, Dir); SeekingRocket.Seeking = SeekTarget; if ( B != None ) { //log("LOCKED"); bLockedOn = false; SeekTarget = None; } return SeekingRocket; } else { Rocket = Spawn(class'RocketProj',,, Start, Dir); return Rocket; } } simulated function PlayIdle() { LoopAnim(IdleAnim, IdleAnimRate, 0.25); } simulated function PlayFiring(bool plunge) { if (plunge) { GotoState('AnimateLoad', 'Begin'); } } simulated function PlayLoad(bool full) { if (!full) { GotoState('AnimateLoad', 'Begin'); } } simulated function AnimEnd(int Channel) { if ( (Channel == 0) && (ClientState == WS_ReadyToFire) ) { PlayIdle(); if ( (Role < ROLE_Authority) && !HasAmmo() ) DoAutoSwitch(); //FIXME HACK } } simulated function RotateBarrel() { FinalRotation += 65535.0 / NUM_BARRELS; if (FinalRotation >= 65535.0) { FinalRotation -= 65535.0; BarrelRotation -= 65535.0; } bRotateBarrel = true; } simulated function UpdateBarrel(float dt) { local Rotator R; BarrelRotation += dt * 65535.0 * BARREL_ROTATION_RATE / NUM_BARRELS; if (BarrelRotation > FinalRotation) { BarrelRotation = FinalRotation; bRotateBarrel = false; } R.Roll = BarrelRotation; SetBoneRotation('Bone_Barrel', R, 0, 1); } simulated function Plunge() { PlayAnim('load', 0.8, 0.0, 1); PlayAnim('load', 0.8, 0.0, 2); } simulated event ClientStartFire(int Mode) { local int OtherMode; if ( RocketMultiFire(FireMode[Mode]) != None ) { SetTightSpread(false); } else { if ( Mode == 0 ) OtherMode = 1; else OtherMode = 0; if ( FireMode[OtherMode].bIsFiring || (FireMode[OtherMode].NextFireTime > Level.TimeSeconds) ) { if ( FireMode[OtherMode].Load > 0 ) SetTightSpread(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); } simulated function SetTightSpread(bool bNew, optional bool bForce) { if ( (bTightSpread != bNew) || bForce ) { bTightSpread = bNew; if ( bTightSpread ) ServerSetTightSpread(); else ServerClearTightSpread(); } } function ServerClearTightSpread() { bTightSpread = false; } function ServerSetTightSpread() { bTightSpread = true; } simulated function BringUp(optional Weapon PrevWeapon) { SetTightSpread(false,true); if (Instigator.IsLocallyControlled()) { AnimBlendParams( 1, 1.0, 0.0, 0.0, 'bone_shell' ); AnimBlendParams( 2, 1.0, 0.0, 0.0, 'bone_feed' ); SetBoneRotation('Bone_Barrel', Rot(0,0,0), 0, 1); } Super.BringUp(PrevWeapon); } simulated state AnimateLoad { simulated function Tick(float dt) { if (bRotateBarrel) UpdateBarrel(dt); } Begin: Sleep(0.15); RotateBarrel(); Sleep(0.07); PlayOwnedSound(Sound'WeaponSounds.RocketLauncher.RocketLauncherLoad', SLOT_None,,,,,false); ClientPlayForceFeedback( "RocketLauncherLoad" ); // jdf Sleep(0.28); Plunge(); PlayOwnedSound(Sound'WeaponSounds.RocketLauncher.RocketLauncherPlunger', SLOT_None,,,,,false); ClientPlayForceFeedback( "RocketLauncherPlunger" ); // jdf Sleep(0.29); GotoState(''); } // AI Interface function float SuggestAttackStyle() { local float EnemyDist; // recommend backing off if target is too close EnemyDist = VSize(Instigator.Controller.Enemy.Location - Owner.Location); if ( EnemyDist < 750 ) { if ( EnemyDist < 500 ) return -1.5; else return -0.7; } else if ( EnemyDist > 1600 ) return 0.5; else return -0.1; } // tell bot how valuable this weapon would be to use, based on the bot's combat situation // also suggest whether to use regular or alternate fire mode function float GetAIRating() { local Bot B; local float EnemyDist, Rating, ZDiff; local vector EnemyDir; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return AIRating; // if standing on a lift, make sure not about to go around a corner and lose sight of target // (don't want to blow up a rocket in bot's face) if ( (Instigator.Base != None) && (Instigator.Base.Velocity != vect(0,0,0)) && !B.CheckFutureSight(0.1) ) return 0.1; EnemyDir = B.Enemy.Location - Instigator.Location; EnemyDist = VSize(EnemyDir); Rating = AIRating; // don't pick rocket launcher if enemy is too close if ( EnemyDist < 360 ) { if ( Instigator.Weapon == self ) { // don't switch away from rocket launcher unless really bad tactical situation if ( (EnemyDist > 250) || ((Instigator.Health < 50) && (Instigator.Health < B.Enemy.Health - 30)) ) return Rating; } return 0.05 + EnemyDist * 0.001; } // rockets are good if higher than target, bad if lower than target ZDiff = Instigator.Location.Z - B.Enemy.Location.Z; if ( ZDiff > 120 ) Rating += 0.25; else if ( ZDiff < -160 ) Rating -= 0.35; else if ( ZDiff < -80 ) Rating -= 0.05; if ( (B.Enemy.Weapon != None) && B.Enemy.Weapon.bMeleeWeapon && (EnemyDist < 2500) ) Rating += 0.25; return Rating; } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { local bot B; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 0; if ( (FRand() < 0.3) && !B.IsStrafing() && (Instigator.Physics != PHYS_Falling) ) return 1; return 0; } // end AI Interface Y%b class RocketFire extends ProjectileFire; function PlayFireEnd() { } function InitEffects() { Super.InitEffects(); if ( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'tip'); } function PlayFiring() { Super.PlayFiring(); RocketLauncher(Weapon).PlayFiring(true); } function Projectile SpawnProjectile(Vector Start, Rotator Dir) { local Projectile p; p = RocketLauncher(Weapon).SpawnProjectile(Start, Dir); if ( p != None ) p.Damage *= DamageAtten; return p; } Y%W class RocketAttachment extends xWeaponAttachment; var class MuzFlashClass; var xEmitter MuzFlash; simulated function Destroyed() { if (MuzFlash != None) MuzFlash.Destroy(); Super.Destroyed(); } simulated event ThirdPersonEffects() { local rotator r; if ( Level.NetMode != NM_DedicatedServer && FlashCount > 0 ) { if (MuzFlash == None) { MuzFlash = Spawn(MuzFlashClass); if ( MuzFlash != None ) AttachToBone(MuzFlash, 'tip'); } if (MuzFlash != None) { MuzFlash.mStartParticles++; r.Roll = Rand(65536); SetBoneRotation('Bone_Flash', r, 0, 1.f); } } Super.ThirdPersonEffects(); } Y%1class RocketAmmoPickup extends UTAmmoPickup; Y%Uclass RocketAmmo extends Ammunition; #EXEC OBJ LOAD FILE=InterfaceContent.utx Y%Nclass RedeemerWarhead extends Pawn; #EXEC OBJ LOAD FILE=2K4Hud.utx var float Damage, DamageRadius, MomentumTransfer; var class MyDamageType; var Pawn OldPawn; var RedeemerTrail SmokeTrail; var float YawAccel, PitchAccel; // banking related var Shader InnerScopeShader, OuterScopeShader, OuterEdgeShader; var FinalBlend AltitudeFinalBlend; var float YawToBankingRatio, BankingResetRate, BankingToScopeRotationRatio; var int Banking, BankingVelocity, MaxBanking, BankingDamping; var float VelocityToAltitudePanRate, MaxAltitudePanRate; // camera shakes // var() vector ShakeRotMag; // how far to rot view var() vector ShakeRotRate; // how fast to rot view var() float ShakeRotTime; // how much time to rot the instigator's view var() vector ShakeOffsetMag; // max view offset vertically var() vector ShakeOffsetRate; // how fast to offset view vertically var() float ShakeOffsetTime; // how much time to offset view var bool bStaticScreen; var bool bFireForce; var TeamInfo MyTeam; replication { reliable if (Role == ROLE_Authority && bNetOwner) bStaticScreen; reliable if ( Role < ROLE_Authority ) ServerBlowUp; } function PlayerChangedTeam() { Died( None, class'DamageType', Location ); OldPawn.Died(None, class'DamageType', OldPawn.Location); } function TeamInfo GetTeam() { if ( PlayerReplicationInfo != None ) return PlayerReplicationInfo.Team; return MyTeam; } simulated function Destroyed() { RelinquishController(); if ( SmokeTrail != None ) SmokeTrail.Destroy(); Super.Destroyed(); } simulated function bool IsPlayerPawn() { return false; } event bool EncroachingOn( actor Other ) { if ( Other.bWorldGeometry ) return true; return false; } event EncroachedBy( actor Other ) { BlowUp(Location); } function RelinquishController() { if ( Controller == None ) return; Controller.Pawn = None; if ( !Controller.IsInState('GameEnded') ) { if ( (OldPawn != None) && (OldPawn.Health > 0) ) Controller.Possess(OldPawn); else { if ( OldPawn != None ) Controller.Pawn = OldPawn; else Controller.Pawn = self; Controller.PawnDied(Controller.Pawn); } } RemoteRole = Default.RemoteRole; Instigator = OldPawn; Controller = None; } simulated function PostBeginPlay() { local vector Dir; Dir = Vector(Rotation); Velocity = AirSpeed * Dir; Acceleration = Velocity; if ( Level.NetMode != NM_DedicatedServer) { SmokeTrail = Spawn(class'RedeemerTrail',self,,Location - 40 * Dir); SmokeTrail.SetBase(self); } } simulated function PostNetBeginPlay() { Super.PostNetBeginPlay(); if ( PlayerController(Controller) != None ) { Controller.SetRotation(Rotation); PlayerController(Controller).SetViewTarget(self); Controller.GotoState(LandMovementState); PlayOwnedSound(Sound'WeaponSounds.redeemer_shoot',SLOT_Interact,1.0); } } simulated function FaceRotation( rotator NewRotation, float DeltaTime ) { } function UpdateRocketAcceleration(float DeltaTime, float YawChange, float PitchChange) { local vector X,Y,Z; local float PitchThreshold; local int Pitch; local rotator TempRotation; local TexRotator ScopeTexRotator; local VariableTexPanner AltitudeTexPanner; YawAccel = (1-2*DeltaTime)*YawAccel + DeltaTime*YawChange; PitchAccel = (1-2*DeltaTime)*PitchAccel + DeltaTime*PitchChange; SetRotation(rotator(Velocity)); GetAxes(Rotation,X,Y,Z); PitchThreshold = 3000; Pitch = Rotation.Pitch & 65535; if ( (Pitch > 16384 - PitchThreshold) && (Pitch < 49152 + PitchThreshold) ) { if ( Pitch > 49152 - PitchThreshold ) PitchAccel = Max(PitchAccel,0); else if ( Pitch < 16384 + PitchThreshold ) PitchAccel = Min(PitchAccel,0); } Acceleration = Velocity + 5*(YawAccel*Y + PitchAccel*Z); if ( Acceleration == vect(0,0,0) ) Acceleration = Velocity; Acceleration = Normal(Acceleration) * AccelRate; BankingVelocity += DeltaTime * (YawToBankingRatio * YawChange - BankingResetRate * Banking - BankingDamping * BankingVelocity); Banking += DeltaTime * (BankingVelocity); Banking = Clamp(Banking, -MaxBanking, MaxBanking); TempRotation = Rotation; TempRotation.Roll = Banking; SetRotation(TempRotation); ScopeTexRotator = TexRotator(OuterScopeShader.Diffuse); if (ScopeTexRotator != None) ScopeTexRotator.Rotation.Yaw = Rotation.Roll; AltitudeTexPanner = VariableTexPanner(Shader(AltitudeFinalBlend.Material).Diffuse); if (AltitudeTexPanner != None) AltitudeTexPanner.PanRate = FClamp(Velocity.Z * VelocityToAltitudePanRate, -MaxAltitudePanRate, MaxAltitudePanRate); } simulated function PhysicsVolumeChange( PhysicsVolume Volume ) { } simulated function Landed( vector HitNormal ) { BlowUp(Location); } simulated function HitWall(vector HitNormal, actor Wall) { BlowUp(Location); } function UnPossessed() { BlowUp(Location); } simulated singular function Touch(Actor Other) { if ( Other.bBlockActors ) BlowUp(Location); } simulated singular function Bump(Actor Other) { if (Other.bBlockActors) BlowUp(Location); } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { if ( (Damage > 0) && ((InstigatedBy == None) || (InstigatedBy.Controller == None) || (Instigator == None) || (Instigator.Controller == None) || !InstigatedBy.Controller.SameTeamAs(Instigator.Controller)) ) { if ( (InstigatedBy == None) || DamageType.Default.bVehicleHit || (DamageType == class'Crushed') ) BlowUp(Location); else { if ( PlayerController(Controller) != None ) PlayerController(Controller).PlayRewardAnnouncement('Denied',1, true); if ( PlayerController(InstigatedBy.Controller) != None ) PlayerController(InstigatedBy.Controller).PlayRewardAnnouncement('Denied',1, true); Spawn(class'SmallRedeemerExplosion'); RelinquishController(); SetCollision(false,false,false); HurtRadius(Damage, DamageRadius*0.125, MyDamageType, MomentumTransfer, Location); Destroy(); } } } function Fire( optional float F ) { ServerBlowUp(); if ( F == 1 ) { OldPawn.Health = -1; OldPawn.KilledBy(OldPawn); } } function ServerBlowUp() { BlowUp(Location); } function BlowUp(vector HitLocation) { if ( Role == ROLE_Authority ) { bHidden = true; Spawn(class'RedeemerExplosion',,, HitLocation - 100 * Normal(Velocity), Rot(0,16384,0)); GotoState('Dying'); } } function bool DoJump( bool bUpdating ) { return false; } singular event BaseChange() { } simulated function DrawHUD(Canvas Canvas) { local float Offset; local Plane SavedCM; SavedCM = Canvas.ColorModulate; Canvas.ColorModulate.X = 1; Canvas.ColorModulate.Y = 1; Canvas.ColorModulate.Z = 1; Canvas.ColorModulate.W = 1; Canvas.Style = 255; Canvas.SetPos(0,0); Canvas.DrawColor = class'Canvas'.static.MakeColor(255,255,255); if ( bStaticScreen ) Canvas.DrawTile( Material'ScreenNoiseFB', Canvas.SizeX, Canvas.SizeY, 0.0, 0.0, 512, 512 ); else if ( !Level.IsSoftwareRendering() ) { if (Canvas.ClipX >= Canvas.ClipY) { Offset = Canvas.ClipX / Canvas.ClipY; Canvas.DrawTile( OuterEdgeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512 * (1 - Offset), 0, Offset * 512, 512 ); Canvas.SetPos(0.5*Canvas.SizeX,0); Canvas.DrawTile( OuterEdgeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512, 0, -512 * Offset, 512 ); Canvas.SetPos(0,0.5* Canvas.SizeY); Canvas.DrawTile( OuterEdgeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512 * (1 - Offset), 512, Offset * 512, -512); Canvas.SetPos(0.5*Canvas.SizeX,0.5* Canvas.SizeY); Canvas.DrawTile( OuterEdgeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512, 512, -512 * Offset, -512 ); Canvas.SetPos(0, 0); Canvas.DrawTile( InnerScopeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512 * (1 - Offset), 0, Offset * 512, 512 ); Canvas.SetPos(0.5* Canvas.SizeX,0); Canvas.DrawTile( InnerScopeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512, 0, -512 * Offset, 512 ); Canvas.SetPos(0,0.5* Canvas.SizeY); Canvas.DrawTile( InnerScopeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512 * (1 - Offset), 512, Offset * 512, -512 ); Canvas.SetPos(0.5* Canvas.SizeX,0.5* Canvas.SizeY); Canvas.DrawTile( InnerScopeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512, 512, -512 * Offset, -512 ); Canvas.SetPos(0.5 * (Canvas.SizeX - Canvas.SizeY), 0); Canvas.DrawTile( OuterScopeShader, Canvas.SizeX, Canvas.SizeY, 0, 0, 1024 * Offset, 1024 ); Canvas.SetPos((512 * (Offset - 1) + 383) * (Canvas.SizeX / (1024 * Offset)), Canvas.SizeY *(451.0/(1024.0))); Canvas.DrawTile( AltitudeFinalBlend, Canvas.SizeX / (8 * Offset), Canvas.SizeY / 8, 0, 0, 128, 128); Canvas.SetPos((512 * (Offset - 1) + 383 + 2*(512-383) - 128) * (Canvas.SizeX / (1024 * Offset)), Canvas.SizeY *(451.0/1024.0)); Canvas.DrawTile( AltitudeFinalBlend, Canvas.SizeX / (8 * Offset), Canvas.SizeY / 8, 128, 0, -128, 128); } else { Offset = Canvas.ClipY / Canvas.ClipX; Canvas.DrawTile( OuterEdgeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 0, 512 * (1 - Offset), 512, 512 * Offset); Canvas.SetPos(0.5*Canvas.SizeX,0); Canvas.DrawTile( OuterEdgeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512, 512 * (1 - Offset), -512, 512 * Offset); Canvas.SetPos(0,0.5* Canvas.SizeY); Canvas.DrawTile( OuterEdgeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 0, 512, 512, -512 * Offset); Canvas.SetPos(0.5*Canvas.SizeX,0.5* Canvas.SizeY); Canvas.DrawTile( OuterEdgeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512, 512, -512, -512 * Offset); Canvas.SetPos(0, 0); Canvas.DrawTile( InnerScopeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 0, 512 * (1 - Offset), 512, 512 * Offset); Canvas.SetPos(0.5*Canvas.SizeX,0); Canvas.DrawTile( InnerScopeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512, 512 * (1 - Offset), -512, 512 * Offset); Canvas.SetPos(0,0.5* Canvas.SizeY); Canvas.DrawTile( InnerScopeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 0, 512, 512, -512 * Offset); Canvas.SetPos(0.5*Canvas.SizeX,0.5* Canvas.SizeY); Canvas.DrawTile( InnerScopeShader, 0.5 * Canvas.SizeX, 0.5 * Canvas.SizeY, 512, 512, -512, -512 * Offset); Canvas.SetPos(0, 0.5 * (Canvas.SizeY - Canvas.SizeX)); Canvas.DrawTile( OuterScopeShader, Canvas.SizeX, Canvas.SizeY, 0, 0, 1024, 1024 * Offset ); Canvas.SetPos(Canvas.SizeX * (383.0/1024.0), (512 * (Offset - 1) + 451) * (Canvas.SizeY / (1024 * Offset))); Canvas.DrawTile( AltitudeFinalBlend, Canvas.SizeX / 8, Canvas.SizeY / (8 * Offset), 0, 0, 128, 128); Canvas.SetPos(Canvas.SizeX * ((383 + 2*(512-383) - 128)) / 1024, (512 * (Offset - 1) + 451) * (Canvas.SizeY / (1024 * Offset))); Canvas.DrawTile( AltitudeFinalBlend, Canvas.SizeX / 8, Canvas.SizeY / (8 * Offset), 128, 0, -128, 128); } } Canvas.ColorModulate = SavedCM; } simulated event PlayDying(class DamageType, vector HitLoc); function Died(Controller Killer, class damageType, vector HitLocation) { BlowUp(Location); } function bool CheatWalk() { return false; } function bool CheatGhost() { return false; } function bool CheatFly() { return false; } function ShouldCrouch(bool Crouch) {} event SetWalking(bool bNewIsWalking) {} function Suicide() { Blowup(Location); if ( (OldPawn != None) && (OldPawn.Health > 0) ) OldPawn.KilledBy(OldPawn); } auto state Flying { function Tick(float DeltaTime) { if ( !bFireForce && (PlayerController(Controller) != None) ) { bFireForce = true; PlayerController(Controller).ClientPlayForceFeedback("FlakCannonAltFire"); // jdf } if ( (OldPawn == None) || (OldPawn.Health <= 0) ) BlowUp(Location); else if ( Controller == None ) { if ( OldPawn.Controller == None ) OldPawn.KilledBy(OldPawn); BlowUp(Location); } } } state Dying { ignores Trigger, Bump, HitWall, HeadVolumeChange, PhysicsVolumeChange, Falling, BreathTimer; function Fire( optional float F ) {} function BlowUp(vector HitLocation) {} function ServerBlowUp() {} function Timer() {} function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) {} function BeginState() { bHidden = true; bStaticScreen = true; SetPhysics(PHYS_None); SetCollision(false,false,false); Spawn(class'IonCore',,, Location, Rotation); if ( SmokeTrail != None ) SmokeTrail.Destroy(); ShakeView(); } function ShakeView() { local Controller C; local PlayerController PC; local float Dist, Scale; for ( C=Level.ControllerList; C!=None; C=C.NextController ) { PC = PlayerController(C); if ( PC != None && PC.ViewTarget != None ) { Dist = VSize(Location - PC.ViewTarget.Location); if ( Dist < DamageRadius * 2.0) { if (Dist < DamageRadius) Scale = 1.0; else Scale = (DamageRadius*2.0 - Dist) / (DamageRadius); C.ShakeView(ShakeRotMag*Scale, ShakeRotRate, ShakeRotTime, ShakeOffsetMag*Scale, ShakeOffsetRate, ShakeOffsetTime); } } } } Begin: Instigator = self; PlaySound(sound'WeaponSounds.redeemer_explosionsound'); HurtRadius(Damage, DamageRadius*0.125, MyDamageType, MomentumTransfer, Location); Sleep(0.5); HurtRadius(Damage, DamageRadius*0.300, MyDamageType, MomentumTransfer, Location); Sleep(0.2); HurtRadius(Damage, DamageRadius*0.475, MyDamageType, MomentumTransfer, Location); Sleep(0.2); RelinquishController(); HurtRadius(Damage, DamageRadius*0.650, MyDamageType, MomentumTransfer, Location); Sleep(0.2); HurtRadius(Damage, DamageRadius*0.825, MyDamageType, MomentumTransfer, Location); Sleep(0.2); HurtRadius(Damage, DamageRadius*1.000, MyDamageType, MomentumTransfer, Location); Destroy(); } Y%fT//============================================================================= // rocket. //============================================================================= class RedeemerProjectile extends Projectile; var NewRedeemerTrail SmokeTrail; // camera shakes // var() vector ShakeRotMag; // how far to rot view var() vector ShakeRotRate; // how fast to rot view var() float ShakeRotTime; // how much time to rot the instigator's view var() vector ShakeOffsetMag; // max view offset vertically var() vector ShakeOffsetRate; // how fast to offset view vertically var() float ShakeOffsetTime; // how much time to offset view var class ExplosionEffectClass; var byte Team; simulated function Destroyed() { if ( SmokeTrail != None ) SmokeTrail.Destroy(); Super.Destroyed(); } function BeginPlay() { Super.BeginPlay(); if (Instigator != None) Team = Instigator.GetTeamNum(); SetTimer(0.5, true); } simulated function PostBeginPlay() { local vector Dir; if ( bDeleteMe || IsInState('Dying') ) return; Dir = vector(Rotation); Velocity = speed * Dir; if ( Level.NetMode != NM_DedicatedServer) { SmokeTrail = Spawn(class'NewRedeemerTrail',self,,Location - 40 * Dir, Rotation); SmokeTrail.SetBase(self); } Super.PostBeginPlay(); } event bool EncroachingOn( actor Other ) { if ( Other.bWorldGeometry ) return true; return false; } simulated function ProcessTouch (Actor Other, Vector HitLocation) { if ( Other != instigator ) Explode(HitLocation,Vect(0,0,1)); } simulated function Explode(vector HitLocation, vector HitNormal) { BlowUp(HitLocation); } simulated function PhysicsVolumeChange( PhysicsVolume Volume ) { } simulated function Landed( vector HitNormal ) { BlowUp(Location); } simulated function HitWall(vector HitNormal, actor Wall) { BlowUp(Location); } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { if ( (Damage > 0) && ((InstigatedBy == None) || (InstigatedBy.Controller == None) || (Instigator == None) || (Instigator.Controller == None) || !InstigatedBy.Controller.SameTeamAs(Instigator.Controller)) ) { if ( (InstigatedBy == None) || DamageType.Default.bVehicleHit || (DamageType == class'Crushed') ) BlowUp(Location); else { Spawn(class'SmallRedeemerExplosion'); SetCollision(false,false,false); HurtRadius(Damage, DamageRadius*0.125, MyDamageType, MomentumTransfer, Location); Destroy(); } } } simulated event FellOutOfWorld(eKillZType KillType) { BlowUp(Location); } function BlowUp(vector HitLocation) { Spawn(ExplosionEffectClass,,, HitLocation - 100 * Normal(Velocity), Rot(0,16384,0)); MakeNoise(1.0); SetPhysics(PHYS_None); bHidden = true; GotoState('Dying'); } function Timer() { local Controller C; //Enemies who don't have anything else to shoot at will try to shoot redeemer down for (C = Level.ControllerList; C != None; C = C.NextController) if ( AIController(C) != None && C.Pawn != None && C.GetTeamNum() != Team && AIController(C).Skill >= 2.0 && !C.Pawn.IsFiring() && (C.Enemy == None || !C.LineOfSightTo(C.Enemy)) && C.Pawn.CanAttack(self) ) { C.Focus = self; C.FireWeaponAt(self); } } state Dying { function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) {} function Timer() {} function BeginState() { bHidden = true; SetPhysics(PHYS_None); SetCollision(false,false,false); Spawn(class'IonCore',,, Location, Rotation); ShakeView(); InitialState = 'Dying'; if ( SmokeTrail != None ) SmokeTrail.Destroy(); SetTimer(0, false); } function ShakeView() { local Controller C; local PlayerController PC; local float Dist, Scale; for ( C=Level.ControllerList; C!=None; C=C.NextController ) { PC = PlayerController(C); if ( PC != None && PC.ViewTarget != None ) { Dist = VSize(Location - PC.ViewTarget.Location); if ( Dist < DamageRadius * 2.0) { if (Dist < DamageRadius) Scale = 1.0; else Scale = (DamageRadius*2.0 - Dist) / (DamageRadius); C.ShakeView(ShakeRotMag*Scale, ShakeRotRate, ShakeRotTime, ShakeOffsetMag*Scale, ShakeOffsetRate, ShakeOffsetTime); } } } } Begin: PlaySound(sound'WeaponSounds.redeemer_explosionsound'); HurtRadius(Damage, DamageRadius*0.125, MyDamageType, MomentumTransfer, Location); Sleep(0.5); HurtRadius(Damage, DamageRadius*0.300, MyDamageType, MomentumTransfer, Location); Sleep(0.2); HurtRadius(Damage, DamageRadius*0.475, MyDamageType, MomentumTransfer, Location); Sleep(0.2); HurtRadius(Damage, DamageRadius*0.650, MyDamageType, MomentumTransfer, Location); Sleep(0.2); HurtRadius(Damage, DamageRadius*0.825, MyDamageType, MomentumTransfer, Location); Sleep(0.2); HurtRadius(Damage, DamageRadius*1.000, MyDamageType, MomentumTransfer, Location); Destroy(); } Y%f##exec OBJ LOAD FILE=EpicParticles.utx #exec OBJ LOAD FILE=2K4HUD.utx class RedeemerPickup extends UTWeaponPickup; var material PrecacheHUDTextures[4]; function PrebeginPlay() { Super.PreBeginPlay(); if ( Level.Game.IsA('xMutantGame') ) Destroy(); } function SetWeaponStay() { bWeaponStay = false; } function float GetRespawnTime() { return ReSpawnTime; } static function StaticPrecache(LevelInfo L) { local int i; for ( i=0; i<4; i++ ) L.AddPrecacheMaterial(Default.PrecacheHUDTextures[i]); L.AddPrecacheMaterial(Material'EpicParticles.Smokepuff2'); L.AddPrecacheMaterial(Material'EpicParticles.IonBurn'); L.AddPrecacheMaterial(Material'EpicParticles.IonWave'); L.AddPrecacheMaterial(Material'EpicParticles.BurnFlare1'); L.AddPrecacheMaterial(Material'EpicParticles.WhiteStreak01aw'); L.AddPrecacheMaterial(Material'EpicParticles.Smokepuff'); L.AddPrecacheMaterial(Material'EpicParticles.SoftFlare'); L.AddPrecacheMaterial(Material'WeaponSkins.RDMR_Missile'); L.AddPrecacheMaterial(Material'AW-2004Explosions.Part_explode2'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.RedeemerPickup'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.RedeemerMissile'); } simulated function UpdatePrecacheMaterials() { local int i; for ( i=0; i<4; i++ ) Level.AddPrecacheMaterial(Default.PrecacheHUDTextures[i]); Level.AddPrecacheMaterial(Material'EpicParticles.Smokepuff2'); Level.AddPrecacheMaterial(Material'EpicParticles.IonBurn'); Level.AddPrecacheMaterial(Material'EpicParticles.IonWave'); Level.AddPrecacheMaterial(Material'EpicParticles.BurnFlare1'); Level.AddPrecacheMaterial(Material'EpicParticles.WhiteStreak01aw'); Level.AddPrecacheMaterial(Material'EpicParticles.Smokepuff'); Level.AddPrecacheMaterial(Material'EpicParticles.SoftFlare'); Level.AddPrecacheMaterial(Material'WeaponSkins.RDMR_Missile'); Level.AddPrecacheMaterial(Material'AW-2004Explosions.Part_explode2'); super.UpdatePrecacheMaterials(); } simulated function UpdatePrecacheStaticMeshes() { Level.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.RedeemerMissile'); Level.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.RedeemerPickup'); Super.UpdatePrecacheStaticMeshes(); } Y%lclass RedeemerGuidedFire extends RedeemerFire; function Projectile SpawnProjectile(Vector Start, Rotator Dir) { local RedeemerWarhead Warhead; local PlayerController Possessor; Warhead = Weapon.Spawn(class'XWeapons.RedeemerWarhead', Instigator,, Start, Dir); if (Warhead == None) Warhead = Weapon.Spawn(class'XWeapons.RedeemerWarhead', Instigator,, Instigator.Location, Dir); if (Warhead != None) { Warhead.OldPawn = Instigator; Warhead.PlaySound(FireSound); Possessor = PlayerController(Instigator.Controller); Possessor.bAltFire = 0; if ( Possessor != None ) { if ( Instigator.InCurrentCombo() ) Possessor.Adrenaline = 0; Possessor.UnPossess(); Instigator.SetOwner(Possessor); Instigator.PlayerReplicationInfo = Possessor.PlayerReplicationInfo; Possessor.Possess(Warhead); } Warhead.Velocity = Warhead.AirSpeed * Vector(Warhead.Rotation); Warhead.Acceleration = Warhead.Velocity; WarHead.MyTeam = Possessor.PlayerReplicationInfo.Team; } else { Weapon.Spawn(class'SmallRedeemerExplosion'); Weapon.HurtRadius(500, 400, class'DamTypeRedeemer', 100000, Instigator.Location); } bIsFiring = false; StopFiring(); return None; } Y%yclass RedeemerFire extends ProjectileFire; function Projectile SpawnProjectile(Vector Start, Rotator Dir) { local Projectile p; p = Super.SpawnProjectile(Start,Dir); if ( p == None ) p = Super.SpawnProjectile(Instigator.Location,Dir); if ( p == None ) { Weapon.Spawn(class'SmallRedeemerExplosion'); Weapon.HurtRadius(500, 400, class'DamTypeRedeemer', 100000, Instigator.Location); } return p; } function float MaxRange() { return 20000; } Y%I class RedeemerAttachment extends xWeaponAttachment; var LinkMuzFlashProj3rd MuzFlash; simulated function Destroyed() { if (MuzFlash != None) MuzFlash.Destroy(); Super.Destroyed(); } simulated event ThirdPersonEffects() { local Rotator R; if ( Level.NetMode != NM_DedicatedServer && FlashCount > 0 ) { if ( FiringMode == 0 ) { if (MuzFlash == None) { //MuzFlash = Spawn(class'LinkMuzFlashProj3rd'); //AttachToBone(MuzFlash, 'tip'); } if (MuzFlash != None) { MuzFlash.Trigger(self, None); R.Roll = Rand(65536); SetBoneRotation('bone flash', R, 0, 1.0); } } } Super.ThirdPersonEffects(); } Y%+class RedeemerAmmo extends Ammunition; Y%u"@IY%@IY%hwua  GY%v"$<wP *P -(3wu*ua GY%Oclass Redeemer extends Weapon config(user); function PrebeginPlay() { Super.PreBeginPlay(); } simulated function SuperMaxOutAmmo() {} simulated event ClientStopFire(int Mode) { if (Role < ROLE_Authority) { StopFire(Mode); } if ( Mode == 0 ) ServerStopFire(Mode); } simulated event WeaponTick(float dt) { if ( (Instigator.Controller == None) || HasAmmo() ) return; Instigator.Controller.SwitchToBestWeapon(); } // AI Interface function float SuggestAttackStyle() { return -1.0; } function float SuggestDefenseStyle() { return -1.0; } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { return 0; } function float GetAIRating() { local Bot B; B = Bot(Instigator.Controller); if ( B == None ) return 0.4; if ( B.IsShootingObjective() ) return 1.0; if ( (B.Enemy == None) || B.Enemy.bCanFly || VSize(B.Enemy.Location - Instigator.Location) < 2400 ) return 0.4; return AIRating; } Y%)class RedBeacon extends TransBeacon; Y%a$ class ProjectileFire extends WeaponFire; var() int ProjPerFire; var() Vector ProjSpawnOffset; // +x forward, +y right, +z up function DoFireEffect() { local Vector StartProj, StartTrace, X,Y,Z; local Rotator R, Aim; local Vector HitLocation, HitNormal; local Actor Other; local int p; local int SpawnCount; local float theta; Instigator.MakeNoise(1.0); Weapon.GetViewAxes(X,Y,Z); StartTrace = Instigator.Location + Instigator.EyePosition();// + X*Instigator.CollisionRadius; StartProj = StartTrace + X*ProjSpawnOffset.X; if ( !Weapon.WeaponCentered() ) StartProj = StartProj + Weapon.Hand * Y*ProjSpawnOffset.Y + Z*ProjSpawnOffset.Z; // 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); SpawnCount = Max(1, ProjPerFire * int(Load)); switch (SpreadStyle) { case SS_Random: X = Vector(Aim); for (p = 0; p < SpawnCount; p++) { R.Yaw = Spread * (FRand()-0.5); R.Pitch = Spread * (FRand()-0.5); R.Roll = Spread * (FRand()-0.5); SpawnProjectile(StartProj, Rotator(X >> R)); } break; case SS_Line: for (p = 0; p < SpawnCount; p++) { theta = Spread*PI/32768*(p - float(SpawnCount-1)/2.0); X.X = Cos(theta); X.Y = Sin(theta); X.Z = 0.0; SpawnProjectile(StartProj, Rotator(X >> Aim)); } break; default: SpawnProjectile(StartProj, Aim); } } function projectile SpawnProjectile(Vector Start, Rotator Dir) { local Projectile p; if( ProjectileClass != None ) p = Weapon.Spawn(ProjectileClass,,, Start, Dir); if( p == None ) return None; p.Damage *= DamageAtten; return p; } simulated function vector GetFireStart(vector X, vector Y, vector Z) { return Instigator.Location + Instigator.EyePosition() + X*ProjSpawnOffset.X + Y*ProjSpawnOffset.Y + Z*ProjSpawnOffset.Z; } Y%*class PainterZoom extends WeaponFire; Y%Gclass PainterPickup extends UTWeaponPickup; function PrebeginPlay() { Super.PreBeginPlay(); if ( Level.Game.IsA('xMutantGame') ) Destroy(); } function SetWeaponStay() { bWeaponStay = false; } function float GetRespawnTime() { return ReSpawnTime; } static function StaticPrecache(LevelInfo L) { L.AddPrecacheMaterial(Material'XEffectMat.painter_beam'); L.AddPrecacheMaterial(Material'XEffectMat.ion_grey'); L.AddPrecacheMaterial(Material'XEffectMat.Ion_beam'); L.AddPrecacheMaterial(Material'EpicParticles.Smokepuff2'); L.AddPrecacheMaterial(Material'EpicParticles.IonBurn2'); L.AddPrecacheMaterial(Material'EpicParticles.BurnFlare1'); L.AddPrecacheMaterial(Material'EpicParticles.WhiteStreak01aw'); L.AddPrecacheMaterial(Material'EpicParticles.Smokepuff'); L.AddPrecacheMaterial(Material'EpicParticles.SoftFlare'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.PainterPickup'); } simulated function UpdatePrecacheMaterials() { Level.AddPrecacheMaterial(Material'XEffectMat.painter_beam'); Level.AddPrecacheMaterial(Material'XEffectMat.ion_grey'); Level.AddPrecacheMaterial(Material'XEffectMat.Ion_beam'); Level.AddPrecacheMaterial(Material'EpicParticles.Smokepuff2'); Level.AddPrecacheMaterial(Material'EpicParticles.IonBurn2'); Level.AddPrecacheMaterial(Material'EpicParticles.BurnFlare1'); Level.AddPrecacheMaterial(Material'EpicParticles.WhiteStreak01aw'); Level.AddPrecacheMaterial(Material'EpicParticles.Smokepuff'); Level.AddPrecacheMaterial(Material'EpicParticles.SoftFlare'); super.UpdatePrecacheMaterials(); } Y%^xclass PainterFire extends WeaponFire; var PainterBeamEffect Beam; var float UpTime; var bool bDoHit; var bool bValidMark; var bool bInitialMark; var bool bAlreadyMarked; var bool bMarkStarted; var IonCannon IonCannon; var float MarkTime; var Vector MarkLocation; var() float TraceRange; var() float PaintDuration; var Vector EndEffect; var() Sound MarkSound; var() Sound AquiredSound; var() String TAGFireForce; var() String TAGMarkForce; var() String TAGAquiredForce; function DestroyEffects() { if (Beam != None) Beam.Destroy(); Super.DestroyEffects(); } state Paint { function Rotator AdjustAim(Vector Start, float InAimError) { local bool bRealAimHelp; local rotator Result; if ( Bot(Instigator.Controller) != None ) { Instigator.Controller.Focus = None; if ( bAlreadyMarked ) Instigator.Controller.FocalPoint = MarkLocation; else Instigator.Controller.FocalPoint = Painter(Instigator.Weapon).MarkLocation; return rotator(Instigator.Controller.FocalPoint - Start); } else { if ( PlayerController(Instigator.Controller) != None ) { bRealAimHelp = PlayerController(Instigator.Controller).bAimingHelp; PlayerController(Instigator.Controller).bAimingHelp = false; } Result = Global.AdjustAim(Start, InAimError); if ( PlayerController(Instigator.Controller) != None ) PlayerController(Instigator.Controller).bAimingHelp = bRealAimHelp; return Result; } } function BeginState() { if (Weapon.Role == ROLE_Authority) { if (Beam == None) { Beam = Weapon.Spawn(class'PainterBeamEffect'); } bInitialMark = true; bValidMark = false; MarkTime = Level.TimeSeconds; SetTimer(0.25, true); } ClientPlayForceFeedback(TAGFireForce); } function Timer() { bDoHit = true; } function ModeTick(float dt) { local Vector StartTrace, EndTrace, X,Y,Z; local Vector HitLocation, HitNormal; local Actor Other; local Rotator Aim; local bool bEngageCannon; //if (Weapon.Role < ROLE_Authority) return; // ---- server only from here on ---- // if (!bIsFiring) { StopFiring(); } Weapon.GetViewAxes(X,Y,Z); // the to-hit trace always starts right in front of the eye StartTrace = Instigator.Location + Instigator.EyePosition() + X*Instigator.CollisionRadius; Aim = AdjustAim(StartTrace, AimError); X = Vector(Aim); EndTrace = StartTrace + TraceRange * X; Other = Weapon.Trace(HitLocation, HitNormal, EndTrace, StartTrace, false); if (Other != None && Other != Instigator) { if ( bDoHit ) { bValidMark = false; if (Other.bWorldGeometry) { if (VSize(HitLocation - MarkLocation) < 50.0) { Instigator.MakeNoise(3.0); if (Level.TimeSeconds - MarkTime > 0.3) { bEngageCannon = (Level.TimeSeconds - MarkTime > PaintDuration); if ( IonCannon == None ) IonCannon = Painter(Weapon).CheckMark(HitLocation, bEngageCannon); if ( (IonCannon != None) && IonCannon.CheckMark(Instigator,HitLocation,bEngageCannon)) { if ( IonCannon.IsFiring() ) { Instigator.PendingWeapon = None; Painter(Weapon).ReallyConsumeAmmo(ThisModeNum, 1); Instigator.Controller.ClientSwitchToBestWeapon(); if (Beam != None) Beam.SetTargetState(PTS_Aquired); StopForceFeedback(TAGMarkForce); ClientPlayForceFeedback(TAGAquiredForce); StopFiring(); } else { bValidMark = true; if (!bMarkStarted) { bMarkStarted = true; ClientPlayForceFeedback(TAGMarkForce); } } } else { MarkTime = Level.TimeSeconds; bValidMark = false; bMarkStarted = false; if ( Bot(Instigator.Controller) != None ) { Instigator.Controller.Focus = Instigator.Controller.Enemy; MarkLocation = Bot(Instigator.Controller).Enemy.Location - Bot(Instigator.Controller).Enemy.CollisionHeight * vect(0,0,2); } } } } else { bAlreadyMarked = true; MarkTime = Level.TimeSeconds; MarkLocation = HitLocation; bValidMark = false; bMarkStarted = false; } } else { MarkTime = Level.TimeSeconds; bValidMark = false; bMarkStarted = false; } bDoHit = false; } EndEffect = HitLocation; } else { EndEffect = EndTrace; } Painter(Weapon).EndEffect = EndEffect; if (Beam != None) { Beam.EndEffect = EndEffect; if (bValidMark) Beam.SetTargetState(PTS_Marked); else Beam.SetTargetState(PTS_Aiming); } if ( IonCannon != None ) { if ( bValidMark ) { if ( IonCannon.Fear == None ) { IonCannon.Fear = Weapon.Spawn(class'AvoidMarker',,,MarkLocation); IonCannon.Fear.SetCollisionSize(0.4 * IonCannon.DamageRadius,100); if ( (Instigator != None) && (Instigator.PlayerReplicationInfo != None) && (Instigator.PlayerReplicationInfo.Team != None) ) IonCannon.Fear.TeamNum = Instigator.PlayerReplicationInfo.Team.TeamIndex; IonCannon.Fear.StartleBots(); } } else if ( IonCannon.Fear != None ) IonCannon.RemoveFear(); } } function StopFiring() { bMarkStarted = false; if (Beam != None) { Beam.SetTargetState(PTS_Cancelled); } GotoState(''); } function EndState() { bAlreadyMarked = false; SetTimer(0, false); StopForceFeedback(TAGFireForce); } } function DoFireEffect() { } function ModeHoldFire() { GotoState('Paint'); } function StartBerserk() { } function StopBerserk() { } function StartSuperBerserk() { } function vector GetFireStart(vector X, vector Y, vector Z) { return Instigator.Location + Instigator.EyePosition() + X*Instigator.CollisionRadius; } function float MaxRange() { return TraceRange; } Y%vGclass PainterBeamEffect extends xEmitter; #exec OBJ LOAD FILE=XEffectMat.utx var PainterBeamSpot Spot; var Vector StartEffect, EndEffect; var Vector EffectOffset; var LinkMuzFlashBeam3rd MuzFlash; var float Brightness; var enum EPainterTargetingState { PTS_Aiming, PTS_Marked, PTS_Aquired, PTS_Cancelled } TargetState; var() Sound MarkSound; var() Sound AquiredSound; var() String MarkForce; // jdf var() String AmbientForce; // jdf replication { unreliable if (Role == ROLE_Authority) StartEffect, EndEffect, TargetState; } simulated function PostBeginPlay() { Spot = Spawn(class'PainterBeamSpot', self); } simulated function Destroyed() { if (MuzFlash != None) MuzFlash.mRegen = false; if (Spot != None) Spot.Destroy(); Super.Destroyed(); } function SetTargetState(EPainterTargetingState NewState) { TargetState = NewState; if (TargetState == PTS_Aquired) { GotoState('Aquired'); } else if (TargetState == PTS_Cancelled) { GotoState('Cancelled'); } } simulated function Tick(float dt) { local Vector BeamDir; local Vector X,Y,Z; local xWeaponAttachment Attachment; if (Role == ROLE_Authority && (Instigator == None || Instigator.Controller == None)) { Destroy(); return; } if (Level.NetMode == NM_DedicatedServer) { StartEffect = Instigator.Location + Instigator.EyeHeight*Vect(0,0,1); return; } // set beam start location if ( Instigator == None ) { SetLocation(StartEffect); } else { if ( Instigator.IsFirstPerson() && Instigator.Weapon != None ) { if ( Instigator.Weapon.WeaponCentered() ) SetLocation( Instigator.Location ); else { Instigator.Weapon.GetViewAxes(X, Y, Z); SetLocation( (Instigator.Location + Instigator.CalcDrawOffset(Instigator.Weapon) + EffectOffset.X * X + Instigator.Weapon.Hand * EffectOffset.Y * Y + EffectOffset.Z * Z) ); } EndEffect = Painter(Instigator.Weapon).EndEffect; } else { Attachment = xPawn(Instigator).WeaponAttachment; if (Attachment != None && (Level.TimeSeconds - Attachment.LastRenderTime) < 1) SetLocation( Attachment.GetTipLocation() ); else SetLocation( Instigator.Location + Instigator.EyeHeight*Vect(0,0,1) + Normal(EndEffect - Instigator.Location) * 25.0 ); } if (Role == ROLE_Authority) // what clients will use if their instigator is not relevant yet StartEffect = Location; } BeamDir = Normal(EndEffect - Location); SetRotation(Rotator(BeamDir)); mSpawnVecA = EndEffect; if (Spot != None) { Spot.SetLocation(EndEffect - BeamDir*10.0); } if (TargetState == PTS_Marked) { if (Brightness == 40.0) PlaySound(MarkSound); SetBrightness( FMax(FMin(Brightness+dt*100.0, 250.0), 100.0) ); } else SetBrightness( 40.0 ); if (TargetState == PTS_Aquired) GotoState('Aquired'); else if (TargetState == PTS_Cancelled) GotoState('Cancelled'); } state Aquired { simulated function BeginState() { PlaySound(AquiredSound); AmbientSound = None; SetTimer(0.4, false); } simulated function Timer() { GotoState('Cancelled'); } simulated function Tick(float dt) { if (Level.NetMode != NM_DedicatedServer) { SetBrightness( 250.0 ); mSizeRange[0] = FMin(mSizeRange[0]+dt*40.0, 16.0); } } simulated function SetTargetState(EPainterTargetingState NewState) { } } state Cancelled { simulated function BeginState() { SetTimer(0.4, false); } simulated function Timer() { Destroy(); } simulated function Tick(float dt) { if (Level.NetMode != NM_DedicatedServer) { SetBrightness( FMax(Brightness-dt*100.0, 40.0) ); mSizeRange[0] = FMax(mSizeRange[0]-dt*40.0, 1.0); } } simulated function SetTargetState(EPainterTargetingState NewState) { } } simulated function SetBrightness(float b) { Brightness = b; mColorRange[0].R = b; mColorRange[0].G = b; mColorRange[0].B = b; mColorRange[1] = mColorRange[0]; } Y%I class PainterAttachment extends xWeaponAttachment; var LinkMuzFlashProj3rd MuzFlash; simulated function Destroyed() { if (MuzFlash != None) MuzFlash.Destroy(); Super.Destroyed(); } simulated event ThirdPersonEffects() { local Rotator R; if ( Level.NetMode != NM_DedicatedServer && FlashCount > 0 ) { if ( FiringMode == 0 ) { if (MuzFlash == None) { //MuzFlash = Spawn(class'LinkMuzFlashProj3rd'); //AttachToBone(MuzFlash, 'tip'); } if (MuzFlash != None) { MuzFlash.Trigger(self, None); R.Roll = Rand(65536); SetBoneRotation('bone flashA', R, 0, 1.0); } } } Super.ThirdPersonEffects(); } Y%Yclass Painter extends Weapon config(user); #exec OBJ LOAD FILE=XGameShaders.utx var(Gfx) float borderX; var(Gfx) float borderY; var(Gfx) float focusX; var(Gfx) float focusY; var(Gfx) float innerArrowsX; var(Gfx) float innerArrowsY; var(Gfx) Color ArrowColor; var(Gfx) Color FocusColor; var(Gfx) Color ChargeColor; var(Gfx) vector RechargeOrigin; var(Gfx) vector RechargeSize; var transient float LastFOV; var bool zoomed; var Vector EndEffect; var vector MarkLocation; var IonCannon FirstCannon; function bool ConsumeAmmo(int Mode, float load, optional bool bAmountNeededIsMax) { return true; } function ReallyConsumeAmmo(int Mode, float load) { Super.ConsumeAmmo(Mode,load); } simulated function ClientWeaponThrown() { if( (Instigator != None) && (PlayerController(Instigator.Controller) != None) ) PlayerController(Instigator.Controller).EndZoom(); Super.ClientWeaponThrown(); } // compensate for bright fog simulated function SetZoomBlendColor(Canvas c) { local Byte val; local Color clr; local Color fog; clr.R = 255; clr.G = 255; clr.B = 255; clr.A = 255; if( Instigator.Region.Zone.bDistanceFog ) { fog = Instigator.Region.Zone.DistanceFogColor; val = 0; val = Max( val, fog.R); val = Max( val, fog.G); val = Max( val, fog.B); if( val > 128 ) { val -= 128; clr.R -= val; clr.G -= val; clr.B -= val; } } c.DrawColor = clr; } simulated event RenderOverlays( Canvas Canvas ) { local float tileScaleX; local float tileScaleY; local float bX; local float bY; local float fX; local float fY; local float ChargeBar; local float barOrgX; local float barOrgY; local float barSizeX; local float barSizeY; local PainterFire PainterFire; CheckOutOfAmmo(); // FireSound=Sound'WeaponSounds.LightningGun.LightningScope' if ( LastFOV > PlayerController(Instigator.Controller).DesiredFOV ) { PlaySound(Sound'WeaponSounds.LightningGun.LightningZoomIn', SLOT_Misc,,,,,false); } else if ( LastFOV < PlayerController(Instigator.Controller).DesiredFOV ) { PlaySound(Sound'WeaponSounds.LightningGun.LightningZoomOut', SLOT_Misc,,,,,false); } LastFOV = PlayerController(Instigator.Controller).DesiredFOV; if ( PlayerController(Instigator.Controller).DesiredFOV == PlayerController(Instigator.Controller).DefaultFOV ) { Super.RenderOverlays(Canvas); zoomed=false; } else { PainterFire = PainterFire(FireMode[0]); if (PainterFire.bIsFiring && PainterFire.bValidMark && Level.TimeSeconds - PainterFire.MarkTime > 0.4) { ChargeBar = FMin(1.0, ((Level.TimeSeconds - PainterFire.MarkTime) / PainterFire.PaintDuration)); if (ChargeBar >= 1.0) ChargeBar = 0.0; } else ChargeBar = 0.0; tileScaleX = Canvas.SizeX / 640.0f; tileScaleY = Canvas.SizeY / 480.0f; bX = borderX * tileScaleX; bY = borderY * tileScaleY; fX = focusX * tileScaleX; fY = focusY * tileScaleX; barOrgX = RechargeOrigin.X * tileScaleX; barOrgY = RechargeOrigin.Y * tileScaleY; barSizeX = RechargeSize.X * tileScaleX; barSizeY = RechargeSize.Y * tileScaleY; SetZoomBlendColor(Canvas); Canvas.Style = 255; Canvas.SetPos(0,0); Canvas.DrawTile( Material'ZoomFB', Canvas.SizeX, Canvas.SizeY, 0.0, 0.0, 512, 512 ); // !! hardcoded size // draw border corners Canvas.Style = ERenderStyle.STY_Alpha; Canvas.SetPos(0,0); Canvas.DrawTile( Texture'SniperBorder', bX, bY, 0.0, 0.0, Texture'SniperBorder'.USize, Texture'SniperBorder'.VSize ); Canvas.SetPos(Canvas.SizeX-bX,0); Canvas.DrawTile( Texture'SniperBorder', bX, bY, 0.0, 0.0, -Texture'SniperBorder'.USize, Texture'SniperBorder'.VSize ); Canvas.SetPos(Canvas.SizeX-bX,Canvas.SizeY-bY); Canvas.DrawTile( Texture'SniperBorder', bX, bY, 0.0, 0.0, -Texture'SniperBorder'.USize, -Texture'SniperBorder'.VSize ); Canvas.SetPos(0,Canvas.SizeY-bY); Canvas.DrawTile( Texture'SniperBorder', bX, bY, 0.0, 0.0, Texture'SniperBorder'.USize, -Texture'SniperBorder'.VSize ); Canvas.DrawColor = FocusColor; Canvas.DrawColor.A = 255; // 255 was the original -asp. WTF??!?!?! Canvas.Style = ERenderStyle.STY_Alpha; Canvas.SetPos((Canvas.SizeX*0.5)-fX,(Canvas.SizeY*0.5)-fY); Canvas.DrawTile( Texture'SniperFocus', fX*2.0, fY*2.0, 0.0, 0.0, Texture'SniperFocus'.USize, Texture'SniperFocus'.VSize ); fX = innerArrowsX * tileScaleX; fY = innerArrowsY * tileScaleY; Canvas.DrawColor = ArrowColor; Canvas.SetPos((Canvas.SizeX*0.5)-fX,(Canvas.SizeY*0.5)-fY); Canvas.DrawTile( Texture'SniperArrows', fX*2.0, fY*2.0, 0.0, 0.0, Texture'SniperArrows'.USize, Texture'SniperArrows'.VSize ); // Draw the Charging meter -AsP Canvas.DrawColor = ChargeColor; Canvas.DrawColor.A = 255; if(ChargeBar <1) Canvas.DrawColor.R = 255*ChargeBar; else { Canvas.DrawColor.R = 0; Canvas.DrawColor.B = 0; } if(ChargeBar == 1) Canvas.DrawColor.G = 255; else Canvas.DrawColor.G = 0; Canvas.Style = ERenderStyle.STY_Alpha; Canvas.SetPos( barOrgX, barOrgY ); Canvas.DrawTile(Texture'Engine.WhiteTexture',barSizeX,barSizeY*ChargeBar, 0.0, 0.0,Texture'Engine.WhiteTexture'.USize,Texture'Engine.WhiteTexture'.VSize*ChargeBar); zoomed = true; } } simulated function ClientStartFire(int mode) { if (mode == 1) { FireMode[mode].bIsFiring = true; if( Instigator.Controller.IsA( 'PlayerController' ) ) PlayerController(Instigator.Controller).ToggleZoom(); } else { Super.ClientStartFire(mode); } } simulated function ClientStopFire(int mode) { if (mode == 1) { FireMode[mode].bIsFiring = false; if( Instigator.Controller.IsA( 'PlayerController' ) ) PlayerController(Instigator.Controller).StopZoom(); } else { Super.ClientStopFire(mode); } } simulated function BringUp(optional Weapon PrevWeapon) { if( Instigator.Controller.IsA( 'PlayerController' ) ) LastFOV = PlayerController(Instigator.Controller).DesiredFOV; Super.BringUp(PrevWeapon); } simulated function bool PutDown() { if( Instigator.Controller.IsA( 'PlayerController' ) ) PlayerController(Instigator.Controller).EndZoom(); return Super.PutDown(); } simulated function bool HasAmmo() { return (FireMode[0] != None && AmmoAmount(0) >= 1); } function IonCannon CheckMark(vector MarkLocation, bool bFire) { if ( FirstCannon != None ) return FirstCannon; foreach DynamicActors(class'IonCannon', FirstCannon) return FirstCannon; FirstCannon = spawn(class'IonCannon',,,Location+vect(0,0,2000)); return FirstCannon; } // AI Interface function float GetAIRating() { local Bot B; local vector HitLocation, HitNormal; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( B.IsShootingObjective() && Trace(HitLocation, HitNormal, B.Target.Location - vect(0,0,2000), B.Target.Location, false) != None ) { MarkLocation = HitLocation; if ( CheckMark(MarkLocation, false) != None ) return AIRating; } if ( (B.Enemy == None) || (Instigator.Location.Z < B.Enemy.Location.Z) || !B.EnemyVisible() ) return 0; MarkLocation = B.Enemy.Location - B.Enemy.CollisionHeight * vect(0,0,2); if ( CheckMark(MarkLocation, false) != None ) return 2.0; if ( TerrainInfo(B.Enemy.Base) == None ) return 0; return 0.1; } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { return 0; } function float SuggestAttackStyle() { return 0; } function float SuggestDefenseStyle() { return 2; } function float RangedAttackTime() { return 6; } function bool RecommendRangedAttack() { return true; } function bool RecommendLongRangedAttack() { return true; } // End AI Interface Y%s F#S-GY%BB aS*a>( GY%B# q!E GY%s C#@C)KH9:9:$IzC%%@ BA GY%//============================================================================= // NoSuperWeapon - removes Redeemer and Painter //============================================================================= class MutNoSuperWeapon extends Mutator; function bool CheckReplacement( Actor Other, out byte bSuperRelevant ) { bSuperRelevant = 0; if ( xWeaponBase(Other) != None ) { if ( xWeaponBase(Other).WeaponType == class'Painter' ) xWeaponBase(Other).WeaponType = class'SniperRifle'; else if ( xWeaponBase(Other).WeaponType == class'Redeemer' ) xWeaponBase(Other).WeaponType = class'RocketLauncher'; else return true; } else if ( WeaponPickup(Other) != None ) { if ( string(Other.Class) == "xWeapons.PainterPickup" ) ReplaceWith( Other, "xWeapons.SniperRiflePickup"); else if ( string(Other.Class) == "xWeapons.RedeemerPickup" ) ReplaceWith( Other, "xWeapons.RocketLauncherPickup"); else return true; } else return true; return false; } Y%z D#G#]* GY%Y%hY%A#M#E1GY%Bz a>( GY%I#a GY%s J#f C`]9:9:$Igf B B%%f  B? GE#\!E 2L#BݴjW;;;;ʁ)ʁ)x{XL_al] SuperWeaponb]No SuperWeapons{]/.SuperWeapon pickups are removed from the map.Y%Y%z K#N#]. GY%Y%hY%H#xIhYgx6%9Cx6%9Cx6%9Cx&% GY%m,class MutArena extends Mutator config; var() config string ArenaWeaponClassName; var bool bInitialized; var class ArenaWeaponClass; var string ArenaWeaponPickupClassName; var string ArenaAmmoPickupClassName; var localized string ArenaDisplayText, ArenaDescText; simulated function BeginPlay() { local WeaponLocker L; foreach AllActors(class'WeaponLocker', L) L.GotoState('Disabled'); Super.BeginPlay(); } function Initialize() { local int FireMode; bInitialized = true; DefaultWeaponName = ArenaWeaponClassName; ArenaWeaponClass = class(DynamicLoadObject(ArenaWeaponClassName,class'Class')); DefaultWeapon = ArenaWeaponClass; ArenaWeaponPickupClassName = string(ArenaWeaponClass.default.PickupClass); for( FireMode = 0; FireMode<2; FireMode++ ) { if( (ArenaWeaponClass.default.FireModeClass[FireMode] != None) && (ArenaWeaponClass.default.FireModeClass[FireMode].default.AmmoClass != None) && (ArenaWeaponClass.default.FireModeClass[FireMode].default.AmmoClass.default.PickupClass != None) ) { ArenaAmmoPickupClassName = string(ArenaWeaponClass.default.FireModeClass[FireMode].default.AmmoClass.default.PickupClass); break; } } } function bool CheckReplacement( Actor Other, out byte bSuperRelevant ) { if ( !bInitialized ) Initialize(); bSuperRelevant = 0; if ( xWeaponBase(Other) != None ) xWeaponBase(Other).WeaponType = ArenaWeaponClass; else if ( (Weapon(Other) != None) && (Other.Class != ArenaWeaponClass) ) { if ( Weapon(Other).bNoInstagibReplace ) { bSuperRelevant = 0; return true; } return false; } else if ( (WeaponPickup(Other) != None) && (string(Other.Class) != ArenaWeaponPickupClassName) ) ReplaceWith( Other, ArenaWeaponPickupClassName); else if ( (Ammo(Other) != None) && (string(Other.Class) != ArenaAmmoPickupClassName) ) ReplaceWith( Other, ArenaAmmoPickupClassName); else { if ( Other.IsA('WeaponLocker') ) Other.GotoState('Disabled'); return true; } return false; } static function FillPlayInfo(PlayInfo PlayInfo) { local array Recs; local string WeaponOptions; local int i; Super.FillPlayInfo(PlayInfo); class'CacheManager'.static.GetWeaponList(Recs); for (i = 0; i < Recs.Length; i++) { if (WeaponOptions != "") WeaponOptions $= ";"; WeaponOptions $= Recs[i].ClassName $ ";" $ Recs[i].FriendlyName; } PlayInfo.AddSetting(default.RulesGroup, "ArenaWeaponClassName", default.ArenaDisplayText, 0, 1, "Select", WeaponOptions); } static event string GetDescriptionText(string PropName) { if (PropName == "ArenaWeaponClassName") return default.ArenaDescText; return Super.GetDescriptionText(PropName); } P#P)v6!Q#͌AjWв;ʁ)qYԃʁ)ʁ)ʁ)ʁ)qYԖqYԖqYԖKiqYԖKi\"qYԖKi\"V)|Rx{XL_ao ]XWeapons.RocketLauncherT] Arena Weapon_]98Determines which weapon will be used in the arena matchl]Arenab]Arena{]"!Replace weapons and ammo in map.m[!hY%Y%1HHN81NH59:9:$G GY%P //============================================================================= // Minigun. //============================================================================= class MinigunPickup extends UTWeaponPickup; static function StaticPrecache(LevelInfo L) { L.AddPrecacheMaterial(Texture'XEffects.ShellCasingTex'); L.AddPrecacheMaterial(Texture'AW-2004Explosions.Part_explode2s'); L.AddPrecacheMaterial(Texture'AW-2004Particles.TracerShot'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.MinigunPickup'); } simulated function UpdatePrecacheMaterials() { Level.AddPrecacheMaterial(Texture'XEffects.ShellCasingTex'); Level.AddPrecacheMaterial(Texture'AW-2004Explosions.Part_explode2s'); Level.AddPrecacheMaterial(Texture'AW-2004Particles.TracerShot'); super.UpdatePrecacheMaterials(); } Y%pYclass MinigunFire extends InstantFire; // For controlling the roll of the barrel var() float MaxRollSpeed; var() float RollSpeed; var() float BarrelRotationsPerSec; var() int RoundsPerRotation; var() float FireTime; var() Sound WindingSound; var() Sound FiringSound; var() byte MinigunSoundVolume; var MiniGun Gun; var() float WindUpTime; var() String FiringForce; var() String WindingForce; function StartBerserk() { if ( (Level.GRI != None) && (Level.GRI.WeaponBerserk > 1.0) ) return; DamageMin = default.DamageMin * 1.33; DamageMax = default.DamageMax * 1.33; } function StopBerserk() { if ( (Level.GRI != None) && (Level.GRI.WeaponBerserk > 1.0) ) return; DamageMin = default.DamageMin; DamageMax = default.DamageMax; } function StartSuperBerserk() { DamageMin = default.DamageMin * 1.5; DamageMax = default.DamageMax * 1.5; BarrelRotationsPerSec = Default.BarrelRotationsPerSec * 0.667 * Level.GRI.WeaponBerserk; FireRate = 1.f / (RoundsPerRotation * BarrelRotationsPerSec); MaxRollSpeed = 65536.f*BarrelRotationsPerSec; } function PostBeginPlay() { Super.PostBeginPlay(); FireRate = 1.f / (RoundsPerRotation * BarrelRotationsPerSec); MaxRollSpeed = 65536.f*BarrelRotationsPerSec; Gun = Minigun(Weapon); } function FlashMuzzleFlash() { local rotator r; r.Roll = Rand(65536); Weapon.SetBoneRotation('Bone_Flash', r, 0, 1.f); Super.FlashMuzzleFlash(); } function InitEffects() { Super.InitEffects(); if ( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'flash'); } function PlayAmbientSound(Sound aSound) { if ( (Minigun(Weapon) == None) || (Instigator == None) || (aSound == None && ThisModeNum != Gun.CurrentMode) ) return; if(aSound == None) Instigator.SoundVolume = Instigator.default.SoundVolume; else Instigator.SoundVolume = MinigunSoundVolume; Instigator.AmbientSound = aSound; Gun.CurrentMode = ThisModeNum; } function StopRolling() { if (Gun == None || ThisModeNum != Gun.CurrentMode) return; RollSpeed = 0.f; Gun.RollSpeed = 0.f; } function PlayPreFire() {} function PlayStartHold() {} function PlayFiring() {} function PlayFireEnd() {} function StartFiring(); function StopFiring(); function bool IsIdle() { return false; } auto state Idle { function bool IsIdle() { return true; } function BeginState() { PlayAmbientSound(None); StopRolling(); } function EndState() { PlayAmbientSound(WindingSound); } function StartFiring() { RollSpeed = 0; FireTime = (RollSpeed/MaxRollSpeed) * WindUpTime; GotoState('WindUp'); } } state WindUp { function BeginState() { ClientPlayForceFeedback(WindingForce); // jdf } function EndState() { if (ThisModeNum == 0) { if ( (Weapon == None) || !Weapon.GetFireMode(1).bIsFiring ) StopForceFeedback(WindingForce); } else { if ( (Weapon == None) || !Weapon.GetFireMode(0).bIsFiring ) StopForceFeedback(WindingForce); } } function ModeTick(float dt) { FireTime += dt; RollSpeed = (FireTime/WindUpTime) * MaxRollSpeed; if ( !bIsFiring ) { GotoState('WindDown'); return; } if (RollSpeed >= MaxRollSpeed) { RollSpeed = MaxRollSpeed; FireTime = WindUpTime; Gun.UpdateRoll(dt, RollSpeed, ThisModeNum); GotoState('FireLoop'); return; } Gun.UpdateRoll(dt, RollSpeed, ThisModeNum); } function StopFiring() { GotoState('WindDown'); } } state FireLoop { function BeginState() { NextFireTime = Level.TimeSeconds - 0.1; //fire now! PlayAmbientSound(FiringSound); ClientPlayForceFeedback(FiringForce); // jdf Gun.LoopAnim(FireLoopAnim, FireLoopAnimRate, TweenTime); Gun.SpawnShells(RoundsPerRotation*BarrelRotationsPerSec); } function StopFiring() { GotoState('WindDown'); } function EndState() { PlayAmbientSound(WindingSound); StopForceFeedback(FiringForce); // jdf Gun.LoopAnim(Gun.IdleAnim, Gun.IdleAnimRate, TweenTime); Gun.SpawnShells(0.f); } function ModeTick(float dt) { Super.ModeTick(dt); Gun.UpdateRoll(dt, RollSpeed, ThisModeNum); if ( !bIsFiring ) { GotoState('WindDown'); return; } } } state WindDown { function BeginState() { ClientPlayForceFeedback(WindingForce); // jdf } function EndState() { if (ThisModeNum == 0) { if ( (Weapon == None) || !Weapon.GetFireMode(1).bIsFiring ) StopForceFeedback(WindingForce); } else { if ( (Weapon == None) || !Weapon.GetFireMode(0).bIsFiring ) StopForceFeedback(WindingForce); } } function ModeTick(float dt) { FireTime -= dt; RollSpeed = (FireTime/WindUpTime) * MaxRollSpeed; if (RollSpeed <= 0.f) { RollSpeed = 0.f; FireTime = 0.f; Gun.UpdateRoll(dt, RollSpeed, ThisModeNum); GotoState('Idle'); return; } Gun.UpdateRoll(dt, RollSpeed, ThisModeNum); } function StartFiring() { GotoState('WindUp'); } } Y%R#`9:9:$G GY%O]class MinigunAttachment extends xWeaponAttachment; var class mMuzFlashClass; var Emitter mMuzFlash3rd; var class mTracerClass; var() editinline Emitter mTracer; var float mTracerInterval; var() float mTracerIntervalPrimary; var() float mTracerIntervalSecondary; var() float mTracerPullback; var() float mTracerMinDistance; var() float mTracerSpeed; var float mLastTracerTime; var byte OldSpawnHitCount; var float mCurrentRoll; var float mRollInc; var float mRollUpdateTime; var class mShellCaseEmitterClass; var xEmitter mShellCaseEmitter; var() vector mShellEmitterOffset; var vector mOldHitLocation; function Destroyed() { if (mTracer != None) mTracer.Destroy(); if (mMuzFlash3rd != None) mMuzFlash3rd.Destroy(); if (mShellCaseEmitter != None) mShellCaseEmitter.Destroy(); Super.Destroyed(); } simulated function UpdateRoll(float dt) { local rotator r; UpdateRollTime(false); if (mRollInc <= 0.f) return; mCurrentRoll += dt*mRollInc; mCurrentRoll = mCurrentRoll % 65536.f; r.Roll = int(mCurrentRoll); SetBoneRotation('Bone Barrels', r, 0, 1.f); } simulated function UpdateRollTime(bool bUpdate) { local float diff; diff = Level.TimeSeconds - mRollUpdateTime; if (bUpdate) mRollUpdateTime = Level.TimeSeconds; // TODO: clean up! if (diff > 0.2) { mRollInc = 0.f; } } simulated function vector GetTracerStart() { local Pawn p; p = Pawn(Owner); if ( (p != None) && p.IsFirstPerson() && p.Weapon != None ) { // 1st person return p.Weapon.GetEffectStart(); } // 3rd person if ( mMuzFlash3rd != None ) return mMuzFlash3rd.Location; else return Location; } simulated function UpdateTracer() { local vector SpawnLoc, SpawnDir, SpawnVel; local float hitDist; if (Level.NetMode == NM_DedicatedServer) return; if (mTracer == None) { mTracer = Spawn(mTracerClass); //AttachToBone(mTracer, 'tip'); } if (mTracer != None && Level.TimeSeconds > mLastTracerTime + mTracerInterval) { SpawnLoc = GetTracerStart(); mTracer.SetLocation(SpawnLoc); hitDist = VSize(mHitLocation - SpawnLoc) - mTracerPullback; // If we have a hit but the hit location has not changed if(mHitLocation == mOldHitLocation) SpawnDir = vector( Instigator.GetViewRotation() ); else SpawnDir = Normal(mHitLocation - SpawnLoc); if(hitDist > mTracerMinDistance) { SpawnVel = SpawnDir * mTracerSpeed; mTracer.Emitters[0].StartVelocityRange.X.Min = SpawnVel.X; mTracer.Emitters[0].StartVelocityRange.X.Max = SpawnVel.X; mTracer.Emitters[0].StartVelocityRange.Y.Min = SpawnVel.Y; mTracer.Emitters[0].StartVelocityRange.Y.Max = SpawnVel.Y; mTracer.Emitters[0].StartVelocityRange.Z.Min = SpawnVel.Z; mTracer.Emitters[0].StartVelocityRange.Z.Max = SpawnVel.Z; mTracer.Emitters[0].LifetimeRange.Min = hitDist / mTracerSpeed; mTracer.Emitters[0].LifetimeRange.Max = mTracer.Emitters[0].LifetimeRange.Min; mTracer.SpawnParticle(1); } mLastTracerTime = Level.TimeSeconds; GotoState('TickTracer'); } mOldHitLocation = mHitLocation; } /* UpdateHit - used to update properties so hit effect can be spawn client side */ function UpdateHit(Actor HitActor, vector HitLocation, vector HitNormal) { NetUpdateTime = Level.TimeSeconds - 1; SpawnHitCount++; mHitLocation = HitLocation; mHitActor = HitActor; mHitNormal = HitNormal; } simulated event ThirdPersonEffects() { local PlayerController PC; if ( (Level.NetMode == NM_DedicatedServer) || (Instigator == None) ) return; if ( FlashCount > 0 ) { PC = Level.GetLocalPlayerController(); if ( OldSpawnHitCount != SpawnHitCount ) { OldSpawnHitCount = SpawnHitCount; GetHitInfo(); PC = Level.GetLocalPlayerController(); if ( (Instigator.Controller == PC) || (VSize(PC.ViewTarget.Location - mHitLocation) < 2000) ) { if ( FiringMode == 0 ) Spawn(class'HitEffect'.static.GetHitEffect(mHitActor, mHitLocation, mHitNormal),,, mHitLocation, Rotator(mHitNormal)); else Spawn(class'XEffects.ExploWallHit',,, mHitLocation, Rotator(mHitNormal)); CheckForSplash(); } } if ( (Level.TimeSeconds - LastRenderTime > 0.2) && (Instigator.Controller != PC) ) return; WeaponLight(); if (FiringMode == 0) { mTracerInterval = mTracerIntervalPrimary; mRollInc = 65536.f*3.f; } else { mTracerInterval = mTracerIntervalSecondary; mRollInc = 65536.f; } if ( Level.bDropDetail || Level.DetailMode == DM_Low ) mTracerInterval *= 2.0; UpdateRollTime(true); UpdateTracer(); if (mMuzFlash3rd == None) { mMuzFlash3rd = Spawn(mMuzFlashClass); AttachToBone(mMuzFlash3rd, 'tip'); } if (mMuzFlash3rd != None) { mMuzFlash3rd.SpawnParticle(1); } if ( (mShellCaseEmitter == None) && (Level.DetailMode != DM_Low) && !Level.bDropDetail ) { mShellCaseEmitter = Spawn(mShellCaseEmitterClass); if ( mShellCaseEmitter != None ) AttachToBone(mShellCaseEmitter, 'shell'); } if (mShellCaseEmitter != None) mShellCaseEmitter.mStartParticles++; } else { GotoState(''); } Super.ThirdPersonEffects(); } state TickTracer { simulated function Tick(float deltaTime) { UpdateRoll(deltaTime); } } Y%2class MinigunAmmoPickup extends UTAmmoPickup; Y%Vclass MinigunAmmo extends Ammunition; #EXEC OBJ LOAD FILE=InterfaceContent.utx Y%.class MinigunAltFire extends MinigunFire; Y%jU//============================================================================= // Minigun //============================================================================= class Minigun extends Weapon config(user); #EXEC OBJ LOAD FILE=InterfaceContent.utx var float CurrentRoll; var float RollSpeed; //var float FireTime; var() xEmitter ShellCaseEmitter; var() vector AttachLoc; var() rotator AttachRot; var int CurrentMode; var() float GearRatio; var() float GearOffset; var() float Blend; simulated function PostBeginPlay() { Super.PostBeginPlay(); if ( Level.NetMode == NM_DedicatedServer ) return; ShellCaseEmitter = spawn(class'ShellSpewer'); if ( ShellCaseEmitter != None ) { ShellCaseEmitter.Trigger(Self, Instigator); //turn off AttachToBone(ShellCaseEmitter, 'shell'); } } function DropFrom(vector StartLocation) { Super.DropFrom(StartLocation); } simulated function OutOfAmmo() { if ( (Instigator == None) || !Instigator.IsLocallyControlled() || HasAmmo() ) return; Instigator.AmbientSound = None; Instigator.SoundVolume = Instigator.default.SoundVolume; DoAutoSwitch(); } simulated function Destroyed() { if (ShellCaseEmitter != None) { ShellCaseEmitter.Destroy(); ShellCaseEmitter = None; } Super.Destroyed(); } /* BotFire() called by NPC firing weapon. Weapon chooses appropriate firing Mode to use (typically no change) bFinished should only be true if called from the Finished() function FiringMode can be passed in to specify a firing Mode (used by scripted sequences) */ function bool BotFire(bool bFinished, optional name FiringMode) { local int newmode; local Controller C; C = Instigator.Controller; newMode = BestMode(); if ( newMode == 0 ) { C.bFire = 1; C.bAltFire = 0; } else { C.bFire = 0; C.bAltFire = 1; } if ( bFinished ) return true; if ( FireMode[BotMode].bIsFiring && (NewMode != BotMode) ) StopFire(BotMode); if ( !ReadyToFire(newMode) || ClientState != WS_ReadyToFire ) return false; BotMode = NewMode; StartFire(NewMode); return true; } // AI Interface function float GetAIRating() { local Bot B; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( B.Enemy == None ) { if ( (B.Target != None) && VSize(B.Target.Location - B.Pawn.Location) > 8000 ) return 0.5; return AIRating; } if ( !B.EnemyVisible() ) return AIRating - 0.15; return AIRating * FMin(Pawn(Owner).DamageScaling, 1.5); } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { local float EnemyDist; local bot B; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 0; if ( FireMode[0].bIsFiring ) return 0; else if ( FireMode[1].bIsFiring ) return 1; EnemyDist = VSize(B.Enemy.Location - Instigator.Location); if ( EnemyDist < 2000 ) return 0; return 1; } // end AI Interface simulated function SpawnShells(float amountPerSec) { if(ShellCaseEmitter == None || !FirstPersonView()) return; if ( Bot(Instigator.Controller) != None ) { ShellCaseEmitter.Destroy(); return; } ShellCaseEmitter.mRegenRange[0] = amountPerSec; ShellCaseEmitter.mRegenRange[1] = amountPerSec; ShellCaseEmitter.Trigger(self, Instigator); } simulated function bool FirstPersonView() { return (Instigator.IsLocallyControlled() && (PlayerController(Instigator.Controller) != None) && !PlayerController(Instigator.Controller).bBehindView); } // Prevents wrong anims from playing simulated function AnimEnd(int channel) { } // Client-side only: update the first person barrel rotation simulated function UpdateRoll(float dt, float speed, int mode) { local rotator r; if (Level.NetMode == NM_DedicatedServer) return; if (mode == CurrentMode) // to limit to one mode { // log(self$" updateroll (mode="$mode$") speed="$speed); RollSpeed = speed; CurrentRoll += dt*RollSpeed; CurrentRoll = CurrentRoll % 65536.f; r.Roll = int(CurrentRoll); SetBoneRotation('Bone Barrels', r, 0, Blend); r.Roll = GearOffset + r.Roll*GearRatio; SetBoneRotation('Bone gear', r, 0, Blend); } } simulated function bool StartFire(int mode) { local bool bStart; if ( !MinigunFire(FireMode[0]).IsIdle() || !MinigunFire(FireMode[1]).IsIdle() ) return false; bStart = Super.StartFire(mode); if (bStart) FireMode[mode].StartFiring(); return bStart; } // Allow fire modes to return to idle on weapon switch (server) simulated function DetachFromPawn(Pawn P) { //log(self$" detach from pawn p="$p); ReturnToIdle(); Super.DetachFromPawn(P); } // Allow fire modes to return to idle on weapon switch (client) simulated function bool PutDown() { // log(self$" putdown"); ReturnToIdle(); return Super.PutDown(); } simulated function ReturnToIdle() { local int mode; for (mode=0; mode 0) { if ( Trail != None ) Trail.MakeYellow(); MaxSpeed = default.MaxSpeed + 350*Links; Skins[0] = FinalBlend'XEffectMat.LinkProjYellowFB'; LightHue = 40; } } simulated function PostNetBeginPlay() { local float dist; local PlayerController PC; Acceleration = Normal(Velocity) * 3000.0; if ( (Level.NetMode != NM_DedicatedServer) && (Level.DetailMode != DM_Low) ) Trail = Spawn(class'newLinkTrail',self); if ( (Trail != None) && (Instigator != None) && Instigator.IsLocallyControlled() ) { if ( Role == ROLE_Authority ) Trail.Delay(0.1); else { dist = VSize(Location - Instigator.Location); if ( dist < 100 ) Trail.Delay(0.1 - dist/1000); } } if (Role < ROLE_Authority) LinkAdjust(); if ( Level.NetMode == NM_DedicatedServer ) return; if ( Level.bDropDetail || (Level.DetailMode == DM_Low) ) { bDynamicLight = false; LightType = LT_None; } else { PC = Level.GetLocalPlayerController(); if ( (PC == None) || (Instigator == None) || (PC != Instigator.Controller) ) { bDynamicLight = false; LightType = LT_None; } } } simulated function Explode(vector HitLocation, vector HitNormal) { if ( EffectIsRelevant(Location,false) ) { if (Links == 0) Spawn(class'LinkProjSparks',,, HitLocation, rotator(HitNormal)); else Spawn(class'LinkProjSparksYellow',,, HitLocation, rotator(HitNormal)); } PlaySound(Sound'WeaponSounds.BioRifle.BioRifleGoo2'); Destroy(); } simulated function ProcessTouch (Actor Other, vector HitLocation) { local Vector X, RefNormal, RefDir; if (Other == Instigator) return; if (Other == Owner) return; if (Other.IsA('xPawn') && xPawn(Other).CheckReflect(HitLocation, RefNormal, Damage*0.25)) { if (Role == ROLE_Authority) { X = Normal(Velocity); RefDir = X - 2.0*RefNormal*(X dot RefNormal); //Log("reflecting off"@Other@X@RefDir); Spawn(Class, Other,, HitLocation+RefDir*20, Rotator(RefDir)); } Destroy(); } else if ( !Other.IsA('Projectile') || Other.bProjTarget ) { if ( Role == ROLE_Authority ) { if ( Instigator == None || Instigator.Controller == None ) Other.SetDelayedDamageInstigatorController( InstigatorController ); Other.TakeDamage(Damage * (1.0 + float(Links)),Instigator,HitLocation,MomentumTransfer * Normal(Velocity),MyDamageType); } Explode(HitLocation, vect(0,0,1)); } } simulated function HitWall(vector HitNormal, Actor Wall) { Damage *= 1 + Links; Super.HitWall(HitNormal, Wall); } Y%R9//============================================================================= // LinkGunPickup. //============================================================================= class LinkGunPickup extends UTWeaponPickup; #exec OBJ LOAD FILE=NewWeaponPickups.usx static function StaticPrecache(LevelInfo L) { if ( class'LinkGun'.Default.bUseOldWeaponMesh ) L.AddPrecacheMaterial(Texture'WeaponSkins.Skins.LinkTex0'); L.AddPrecacheMaterial(Texture'XEffectMat.link_muz_green'); L.AddPrecacheMaterial(Texture'XEffectMat.link_muzmesh_green'); L.AddPrecacheMaterial(Texture'XEffectMat.link_beam_green'); L.AddPrecacheMaterial(Texture'XEffectMat.link_spark_green'); L.AddPrecacheMaterial(Texture'AW-2004Particles.Weapons.PlasmaShaft'); L.AddPrecacheMaterial(Texture'XEffectMat.Link.link_muz_blue'); L.AddPrecacheMaterial(Texture'XEffectMat.Link.link_beam_blue'); L.AddPrecacheMaterial(Texture'XEffectMat.Link.link_muz_red'); L.AddPrecacheMaterial(Texture'XEffectMat.Link.link_beam_red'); L.AddPrecacheMaterial(Texture'XEffectMat.link_muz_yellow'); L.AddPrecacheMaterial(Texture'XEffectMat.link_muzmesh_yellow'); L.AddPrecacheMaterial(Texture'XEffectMat.link_beam_yellow'); L.AddPrecacheMaterial(Texture'XEffectMat.link_spark_yellow'); L.AddPrecacheMaterial(Texture'UT2004Weapons.NewWeaps.LinkPowerBlue'); L.AddPrecacheMaterial(Texture'UT2004Weapons.NewWeaps.LinkPowerRed'); L.AddPrecacheMaterial(Texture'EpicParticles.Flares.FlickerFlare'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.linkprojectile'); L.AddPrecacheStaticMesh(StaticMesh'NewWeaponPickups.LinkPickupSM'); } simulated function UpdatePrecacheMaterials() { if ( class'LinkGun'.Default.bUseOldWeaponMesh ) Level.AddPrecacheMaterial(Texture'WeaponSkins.Skins.LinkTex0'); Level.AddPrecacheMaterial(Texture'XEffectMat.link_muz_green'); Level.AddPrecacheMaterial(Texture'XEffectMat.link_muzmesh_green'); Level.AddPrecacheMaterial(Texture'XEffectMat.link_beam_green'); Level.AddPrecacheMaterial(Texture'XEffectMat.link_spark_green'); Level.AddPrecacheMaterial(Texture'XEffectMat.Link.link_muz_blue'); Level.AddPrecacheMaterial(Texture'XEffectMat.Link.link_beam_blue'); Level.AddPrecacheMaterial(Texture'XEffectMat.Link.link_muz_red'); Level.AddPrecacheMaterial(Texture'XEffectMat.Link.link_beam_red'); Level.AddPrecacheMaterial(Texture'AW-2004Particles.Weapons.PlasmaShaft'); Level.AddPrecacheMaterial(Texture'XEffectMat.link_muz_yellow'); Level.AddPrecacheMaterial(Texture'XEffectMat.link_muzmesh_yellow'); Level.AddPrecacheMaterial(Texture'XEffectMat.link_beam_yellow'); Level.AddPrecacheMaterial(Texture'XEffectMat.link_spark_yellow'); Level.AddPrecacheMaterial(Texture'UT2004Weapons.NewWeaps.LinkPowerBlue'); Level.AddPrecacheMaterial(Texture'UT2004Weapons.NewWeaps.LinkPowerRed'); Level.AddPrecacheMaterial(Texture'EpicParticles.Flares.FlickerFlare'); super.UpdatePrecacheMaterials(); } simulated function UpdatePrecacheStaticMeshes() { Level.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.linkprojectile'); Super.UpdatePrecacheStaticMeshes(); } function float BotDesireability(Pawn Bot) { local Bot B; local DestroyableObjective O; B = Bot(Bot.Controller); if (B != None && B.Squad != None) { O = DestroyableObjective(B.Squad.SquadObjective); if ( O != None && O.TeamLink(B.GetTeamNum()) && O.Health < O.DamageCapacity && VSize(Bot.Location - O.Location) < 2000 && (AllowRepeatPickup() || Bot.FindInventoryType(InventoryType) == None) ) return MaxDesireability * 2; } return Super.BotDesireability(Bot); } Y%m//============================================================================= // Link Gun //============================================================================= class LinkGun extends Weapon config(user); #EXEC OBJ LOAD FILE=InterfaceContent.utx var() int Links; var() bool Linking; replication { unreliable if (Role == ROLE_Authority) Linking, Links; } simulated function UpdateLinkColor( LinkAttachment.ELinkColor Color ) { if ( FireMode[1] != None ) LinkFire(FireMode[1]).UpdateLinkColor( Color ); if ( Mesh == OldMesh ) // no support for old mesh return; switch ( Color ) { case LC_Green : Skins[0] = material'LinkgunShader'; Skins[1] = material'PowerPulseShader'; break; case LC_Red : Skins[0] = material'LinkgunRedShader'; Skins[1] = material'PowerPulseShaderRed'; break; case LC_Blue : Skins[0] = material'LinkgunBlueShader'; Skins[1] = material'PowerPulseShaderBlue'; break; case LC_Gold : Skins[0] = material'LinkgunYellowShader'; Skins[1] = material'PowerPulseShaderYellow'; break; } } simulated event RenderOverlays( Canvas Canvas ) { if ( (FireMode[1] != None) && !FireMode[1].bIsFiring && (ThirdPersonActor != None) ) { if ( Links > 0 ) LinkAttachment(ThirdPersonActor).SetLinkColor( LC_Gold ); else LinkAttachment(ThirdPersonActor).SetLinkColor( LC_Green ); } super.RenderOverlays( Canvas ); } simulated function vector GetEffectStart() { local Vector X,Y,Z, Offset; local float Extra; // 1st person if ( Instigator.IsFirstPerson() ) { if ( WeaponCentered() ) return CenteredEffectStart(); GetViewAxes(X, Y, Z); if ( class'PlayerController'.Default.bSmallWeapons ) Offset = SmallEffectOffset; else Offset = EffectOffset; if ( Hand == 0 ) { if ( bUseOldWeaponMesh ) Offset.Z -= 10; else Offset.Z -= 14; Extra = 3; } else if ( !bUseOldWeaponMesh ) Offset.Z -= 10; return (Instigator.Location + Instigator.CalcDrawOffset(self) + Offset.X * X + (Offset.Y * Hand + Extra) * Y + Offset.Z * Z); } // 3rd person else { return (Instigator.Location + Instigator.EyeHeight*Vect(0,0,0.5) + Vector(Instigator.Rotation) * 40.0); } } simulated function Destroyed() { if (Role == ROLE_Authority) { if ( LinkFire(FireMode[1]) != None ) LinkFire(FireMode[1]).SetLinkTo(None); } Super.Destroyed(); } simulated function bool StartFire(int Mode) { local SquadAI S; local Bot B; local vector AimDir; if ( (Role == ROLE_Authority) && (PlayerController(Instigator.Controller) != None) && (UnrealTeamInfo(Instigator.PlayerReplicationInfo.Team) != None)) { S = UnrealTeamInfo(Instigator.PlayerReplicationInfo.Team).AI.GetSquadLedBy(Instigator.Controller); if ( S != None ) { AimDir = vector(Instigator.Controller.Rotation); for ( B=S.SquadMembers; B!=None; B=B.NextSquadMember ) if ( (HoldSpot(B.GoalScript) == None) && (B.Pawn != None) && (LinkGun(B.Pawn.Weapon) != None) && B.Pawn.Weapon.FocusOnLeader(true) && ((AimDir dot Normal(B.Pawn.Location - Instigator.Location)) < 0.9) ) { B.Focus = Instigator; B.FireWeaponAt(Instigator); } } } return Super.StartFire(Mode); } // AI Interface function bool FocusOnLeader(bool bLeaderFiring) { local Bot B; local Pawn LeaderPawn; local Actor Other; local vector HitLocation, HitNormal, StartTrace; local Vehicle V; B = Bot(Instigator.Controller); if ( B == None ) return false; if ( PlayerController(B.Squad.SquadLeader) != None ) LeaderPawn = B.Squad.SquadLeader.Pawn; else { V = B.Squad.GetLinkVehicle(B); if ( V != None ) { LeaderPawn = V; bLeaderFiring = (LeaderPawn.Health < LeaderPawn.HealthMax) && (V.LinkHealMult > 0) && ((B.Enemy == None) || V.bKeyVehicle); } } if ( LeaderPawn == None ) { LeaderPawn = B.Squad.SquadLeader.Pawn; if ( LeaderPawn == None ) return false; } if ( !bLeaderFiring && (LeaderPawn.Weapon == None || !LeaderPawn.Weapon.IsFiring()) ) return false; if ( (Vehicle(LeaderPawn) != None) || ((LinkGun(LeaderPawn.Weapon) != None) && ((vector(B.Squad.SquadLeader.Rotation) dot Normal(Instigator.Location - LeaderPawn.Location)) < 0.9)) ) { StartTrace = Instigator.Location + Instigator.EyePosition(); if ( VSize(LeaderPawn.Location - StartTrace) < LinkFire(FireMode[1]).TraceRange ) { Other = Trace(HitLocation, HitNormal, LeaderPawn.Location, StartTrace, true); if ( Other == LeaderPawn ) { B.Focus = Other; return true; } } } return false; } function float GetAIRating() { local Bot B; local DestroyableObjective O; local Vehicle V; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( (PlayerController(B.Squad.SquadLeader) != None) && (B.Squad.SquadLeader.Pawn != None) && (LinkGun(B.Squad.SquadLeader.Pawn.Weapon) != None) ) return 1.2; V = B.Squad.GetLinkVehicle(B); if ( (V != None) && (VSize(Instigator.Location - V.Location) < 1.5 * LinkFire(FireMode[1]).TraceRange) && (V.Health < V.HealthMax) && (V.LinkHealMult > 0) ) return 1.2; if ( Vehicle(B.RouteGoal) != None && B.Enemy == None && VSize(Instigator.Location - B.RouteGoal.Location) < 1.5 * LinkFire(FireMode[1]).TraceRange && Vehicle(B.RouteGoal).TeamLink(B.GetTeamNum()) ) return 1.2; O = DestroyableObjective(B.Squad.SquadObjective); if ( O != None && B.Enemy == None && O.TeamLink(B.GetTeamNum()) && O.Health < O.DamageCapacity && VSize(Instigator.Location - O.Location) < 1.1 * LinkFire(FireMode[1]).TraceRange && B.LineOfSightTo(O) ) return 1.2; return AIRating * FMin(Pawn(Owner).DamageScaling, 1.5); } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { local float EnemyDist; local bot B; local Vehicle V; B = Bot(Instigator.Controller); if ( B == None ) return 0; if ( ( (DestroyableObjective(B.Squad.SquadObjective) != None && B.Squad.SquadObjective.TeamLink(B.GetTeamNum())) || (B.Squad.SquadObjective == None && DestroyableObjective(B.Target) != None && B.Target.TeamLink(B.GetTeamNum())) ) && VSize(B.Squad.SquadObjective.Location - B.Pawn.Location) < FireMode[1].MaxRange() && (B.Enemy == None || !B.EnemyVisible()) ) return 1; if ( FocusOnLeader(B.Focus == B.Squad.SquadLeader.Pawn) ) return 1; V = B.Squad.GetLinkVehicle(B); if ( V == None ) V = Vehicle(B.MoveTarget); if ( V == B.Target ) return 1; if ( (V != None) && (VSize(Instigator.Location - V.Location) < LinkFire(FireMode[1]).TraceRange) && (V.Health < V.HealthMax) && (V.LinkHealMult > 0) && B.LineOfSightTo(V) ) return 1; if ( B.Enemy == None ) return 0; EnemyDist = VSize(B.Enemy.Location - Instigator.Location); if ( EnemyDist > LinkFire(FireMode[1]).TraceRange ) return 0; return 1; } function float SuggestAttackStyle() { return 0.8; } function float SuggestDefenseStyle() { return -0.4; } function bool CanHeal(Actor Other) { if (DestroyableObjective(Other) != None && DestroyableObjective(Other).LinkHealMult > 0) return true; if (Vehicle(Other) != None && Vehicle(Other).LinkHealMult > 0) return true; return false; } // End AI Interface function bool LinkedTo(LinkGun L) { local Pawn Other; local LinkGun OtherWeapon, Head; local int sanity; Head = self; while (Head != None && Head.Linking && sanity < 20) { Other = LinkFire(Head.FireMode[1]).LockedPawn; if (Other == None) return false; else { OtherWeapon = LinkGun(Other.Weapon); if (OtherWeapon == None) return false; else Head = OtherWeapon; } if (Head == L) return true; sanity++; } return false; } function bool ConsumeAmmo(int Mode, float load, optional bool bAmountNeededIsMax) { local Controller C; if (Linking && LinkFire(FireMode[1]).LockedPawn != None && Vehicle(LinkFire(FireMode[1]).LockedPawn) == None) return true; if ( mode == 0 ) bAmountNeededIsMax = true; //use ammo from linking teammates if (Instigator != None && Instigator.PlayerReplicationInfo != None && Instigator.PlayerReplicationInfo.Team != None) { for (C = Level.ControllerList; C != None; C = C.NextController) if (C.Pawn != None && LinkGun(C.Pawn.Weapon) != None && LinkGun(C.Pawn.Weapon).LinkedTo(self)) LinkGun(C.Pawn.Weapon).LinkedConsumeAmmo(Mode, load, bAmountNeededIsMax); } return Super.ConsumeAmmo(Mode, load, bAmountNeededIsMax); } function bool LinkedConsumeAmmo(int Mode, float load, optional bool bAmountNeededIsMax) { if ( mode == 0 ) bAmountNeededIsMax = true; return Super.ConsumeAmmo(Mode, load, bAmountNeededIsMax); } simulated function IncrementFlashCount(int mode) { Super.IncrementFlashCount(mode); if ( LinkAttachment(ThirdPersonActor) != None ) LinkAttachment(ThirdPersonActor).Links = Links; } simulated function bool PutDown() { LinkFire(FireMode[1]).SetLinkTo(None); Links = 0; return Super.PutDown(); } simulated function BringUp(optional Weapon PrevWeapon) { Links = 0; Super.BringUp(PrevWeapon); } // jdf --- simulated event WeaponTick(float dt) { local PlayerController PC; local LinkFire LF; PC = PlayerController(Instigator.Controller); LF = LinkFire(FireMode[1]); if (PC != None && LF != None) { if (Links > 0 && !LF.bLinkFeedbackPlaying) { LF.bLinkFeedbackPlaying = true; PC.ClientPlayForceFeedback(LF.MakeLinkForce); if (!LF.bIsFiring) PC.ClientPlayForceFeedback("BLinkGunBeam1"); } else if (Links <= 0 && LF.bLinkFeedbackPlaying) { LF.bLinkFeedbackPlaying = false; PC.StopForceFeedback("BLinkGunBeam1"); } } } // --- jdf Y%Mclass LinkFire extends WeaponFire; var LinkBeamEffect Beam; var class BeamEffectClass; var Sound MakeLinkSound; var float UpTime; var Pawn LockedPawn; var float LinkBreakTime; var() float LinkBreakDelay; var float LinkScale[6]; var String MakeLinkForce; var() class DamageType; var() int Damage; var() float MomentumTransfer; var() float TraceRange; var() float LinkFlexibility; var bool bDoHit; var() bool bFeedbackDeath; var bool bInitAimError; var bool bLinkFeedbackPlaying; var bool bStartFire; var byte LinkVolume; var byte SentLinkVolume; var rotator DesiredAimError, CurrentAimError; var Sound BeamSounds[4]; simulated function DestroyEffects() { super.DestroyEffects(); if ( Level.NetMode != NM_Client ) { if ( Beam != None ) Beam.Destroy(); } } simulated function bool myHasAmmo( LinkGun LinkGun ) { return (LinkGun.AmmoAmount(ThisModeNum) >= AmmoPerFire); } simulated function Rotator GetPlayerAim( vector StartTrace, float InAimError ) { return AdjustAim(StartTrace, InAimError); } simulated function float AdjustLinkDamage( LinkGun LinkGun, Actor Other, float Damage ) { return Damage * (1.5*Linkgun.Links+1); } simulated function ModeTick(float dt) { local Vector StartTrace, EndTrace, V, X, Y, Z; local Vector HitLocation, HitNormal, EndEffect; local Actor Other; local Rotator Aim; local LinkGun LinkGun; local float Step, ls; local bot B; local bool bShouldStop, bIsHealingObjective; local int AdjustedDamage; local LinkBeamEffect LB; local DestroyableObjective HealObjective; local Vehicle LinkedVehicle; if ( !bIsFiring ) { bInitAimError = true; return; } LinkGun = LinkGun(Weapon); if ( LinkGun.Links < 0 ) { log("warning:"@Instigator@"linkgun had"@LinkGun.Links@"links"); LinkGun.Links = 0; } ls = LinkScale[Min(LinkGun.Links,5)]; if ( myHasAmmo(LinkGun) && ((UpTime > 0.0) || (Instigator.Role < ROLE_Authority)) ) { UpTime -= dt; // the to-hit trace always starts right in front of the eye LinkGun.GetViewAxes(X, Y, Z); StartTrace = GetFireStart( X, Y, Z); TraceRange = default.TraceRange + LinkGun.Links*250; if ( Instigator.Role < ROLE_Authority ) { if ( Beam == None ) ForEach Weapon.DynamicActors(class'LinkBeamEffect', LB ) if ( !LB.bDeleteMe && (LB.Instigator != None) && (LB.Instigator == Instigator) ) { Beam = LB; break; } if ( Beam != None ) LockedPawn = Beam.LinkedPawn; } if ( LockedPawn != None ) TraceRange *= 1.5; if ( Instigator.Role == ROLE_Authority ) { if ( bDoHit ) LinkGun.ConsumeAmmo(ThisModeNum, AmmoPerFire); B = Bot(Instigator.Controller); if ( (B != None) && (PlayerController(B.Squad.SquadLeader) != None) && (B.Squad.SquadLeader.Pawn != None) ) { if ( IsLinkable(B.Squad.SquadLeader.Pawn) && (B.Squad.SquadLeader.Pawn.Weapon != None && B.Squad.SquadLeader.Pawn.Weapon.GetFireMode(1).bIsFiring) && (VSize(B.Squad.SquadLeader.Pawn.Location - StartTrace) < TraceRange) ) { Other = Weapon.Trace(HitLocation, HitNormal, B.Squad.SquadLeader.Pawn.Location, StartTrace, true); if ( Other == B.Squad.SquadLeader.Pawn ) { B.Focus = B.Squad.SquadLeader.Pawn; if ( B.Focus != LockedPawn ) SetLinkTo(B.Squad.SquadLeader.Pawn); B.SetRotation(Rotator(B.Focus.Location - StartTrace)); X = Normal(B.Focus.Location - StartTrace); } else if ( B.Focus == B.Squad.SquadLeader.Pawn ) bShouldStop = true; } else if ( B.Focus == B.Squad.SquadLeader.Pawn ) bShouldStop = true; } } if ( LockedPawn != None ) { EndTrace = LockedPawn.Location + LockedPawn.BaseEyeHeight*Vect(0,0,0.5); // beam ends at approx gun height if ( Instigator.Role == ROLE_Authority ) { V = Normal(EndTrace - StartTrace); if ( (V dot X < LinkFlexibility) || LockedPawn.Health <= 0 || LockedPawn.bDeleteMe || (VSize(EndTrace - StartTrace) > 1.5 * TraceRange) ) { SetLinkTo( None ); } } } if ( LockedPawn == None ) { if ( Bot(Instigator.Controller) != None ) { if ( bInitAimError ) { CurrentAimError = AdjustAim(StartTrace, AimError); bInitAimError = false; } else { BoundError(); CurrentAimError.Yaw = CurrentAimError.Yaw + Instigator.Rotation.Yaw; } // smooth aim error changes Step = 7500.0 * dt; if ( DesiredAimError.Yaw ClockWiseFrom CurrentAimError.Yaw ) { CurrentAimError.Yaw += Step; if ( !(DesiredAimError.Yaw ClockWiseFrom CurrentAimError.Yaw) ) { CurrentAimError.Yaw = DesiredAimError.Yaw; DesiredAimError = AdjustAim(StartTrace, AimError); } } else { CurrentAimError.Yaw -= Step; if ( DesiredAimError.Yaw ClockWiseFrom CurrentAimError.Yaw ) { CurrentAimError.Yaw = DesiredAimError.Yaw; DesiredAimError = AdjustAim(StartTrace, AimError); } } CurrentAimError.Yaw = CurrentAimError.Yaw - Instigator.Rotation.Yaw; if ( BoundError() ) DesiredAimError = AdjustAim(StartTrace, AimError); CurrentAimError.Yaw = CurrentAimError.Yaw + Instigator.Rotation.Yaw; if ( Instigator.Controller.Target == None ) Aim = Rotator(Instigator.Controller.FocalPoint - StartTrace); else Aim = Rotator(Instigator.Controller.Target.Location - StartTrace); Aim.Yaw = CurrentAimError.Yaw; // save difference CurrentAimError.Yaw = CurrentAimError.Yaw - Instigator.Rotation.Yaw; } else Aim = GetPlayerAim(StartTrace, AimError); X = Vector(Aim); EndTrace = StartTrace + TraceRange * X; } Other = Weapon.Trace(HitLocation, HitNormal, EndTrace, StartTrace, true); if ( Other != None && Other != Instigator ) EndEffect = HitLocation; else EndEffect = EndTrace; if ( Beam != None ) Beam.EndEffect = EndEffect; if ( Instigator.Role < ROLE_Authority ) { if ( LinkGun.ThirdPersonActor != None ) { if ( LinkGun.Linking || ((Other != None) && (Instigator.PlayerReplicationInfo.Team != None) && Other.TeamLink(Instigator.PlayerReplicationInfo.Team.TeamIndex)) ) { if (Instigator.PlayerReplicationInfo.Team == None || Instigator.PlayerReplicationInfo.Team.TeamIndex == 0) LinkAttachment(LinkGun.ThirdPersonActor).SetLinkColor( LC_Red ); else LinkAttachment(LinkGun.ThirdPersonActor).SetLinkColor( LC_Blue ); } else { if ( LinkGun.Links > 0 ) LinkAttachment(LinkGun.ThirdPersonActor).SetLinkColor( LC_Gold ); else LinkAttachment(LinkGun.ThirdPersonActor).SetLinkColor( LC_Green ); } } return; } if ( Other != None && Other != Instigator ) { // target can be linked to if ( IsLinkable(Other) ) { if ( Other != lockedpawn ) SetLinkTo( Pawn(Other) ); if ( lockedpawn != None ) LinkBreakTime = LinkBreakDelay; } else { // stop linking if ( lockedpawn != None ) { if ( LinkBreakTime <= 0.0 ) SetLinkTo( None ); else LinkBreakTime -= dt; } // beam is updated every frame, but damage is only done based on the firing rate if ( bDoHit ) { if ( Beam != None ) Beam.bLockedOn = false; Instigator.MakeNoise(1.0); AdjustedDamage = AdjustLinkDamage( LinkGun, Other, Damage ); if ( !Other.bWorldGeometry ) { if ( Level.Game.bTeamGame && Pawn(Other) != None && Pawn(Other).PlayerReplicationInfo != None && Pawn(Other).PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team) // so even if friendly fire is on you can't hurt teammates AdjustedDamage = 0; HealObjective = DestroyableObjective(Other); if ( HealObjective == None ) HealObjective = DestroyableObjective(Other.Owner); if ( HealObjective != None && HealObjective.TeamLink(Instigator.GetTeamNum()) ) { SetLinkTo(None); bIsHealingObjective = true; if (!HealObjective.HealDamage(AdjustedDamage, Instigator.Controller, DamageType)) LinkGun.ConsumeAmmo(ThisModeNum, -AmmoPerFire); } else Other.TakeDamage(AdjustedDamage, Instigator, HitLocation, MomentumTransfer*X, DamageType); if ( Beam != None ) Beam.bLockedOn = true; } } } } // vehicle healing LinkedVehicle = Vehicle(LockedPawn); if ( LinkedVehicle != None && bDoHit ) { AdjustedDamage = Damage * (1.5*Linkgun.Links+1) * Instigator.DamageScaling; if (Instigator.HasUDamage()) AdjustedDamage *= 2; if (!LinkedVehicle.HealDamage(AdjustedDamage, Instigator.Controller, DamageType)) LinkGun.ConsumeAmmo(ThisModeNum, -AmmoPerFire); } LinkGun(Weapon).Linking = (LockedPawn != None) || bIsHealingObjective; if ( bShouldStop ) B.StopFiring(); else { // beam effect is created and destroyed when firing starts and stops if ( (Beam == None) && bIsFiring ) { Beam = Weapon.Spawn( BeamEffectClass, Instigator ); // vary link volume to make sure it gets replicated (in case owning player changed it client side) if ( SentLinkVolume == Default.LinkVolume ) SentLinkVolume = Default.LinkVolume + 1; else SentLinkVolume = Default.LinkVolume; } if ( Beam != None ) { if ( LinkGun.Linking || ((Other != None) && (Instigator.PlayerReplicationInfo.Team != None) && Other.TeamLink(Instigator.PlayerReplicationInfo.Team.TeamIndex)) ) { Beam.LinkColor = Instigator.PlayerReplicationInfo.Team.TeamIndex + 1; if ( LinkGun.ThirdPersonActor != None ) { if ( Instigator.PlayerReplicationInfo.Team == None || Instigator.PlayerReplicationInfo.Team.TeamIndex == 0 ) LinkAttachment(LinkGun.ThirdPersonActor).SetLinkColor( LC_Red ); else LinkAttachment(LinkGun.ThirdPersonActor).SetLinkColor( LC_Blue ); } } else { Beam.LinkColor = 0; if ( LinkGun.ThirdPersonActor != None ) { if ( LinkGun.Links > 0 ) LinkAttachment(LinkGun.ThirdPersonActor).SetLinkColor( LC_Gold ); else LinkAttachment(LinkGun.ThirdPersonActor).SetLinkColor( LC_Green ); } } Beam.Links = LinkGun.Links; Instigator.AmbientSound = BeamSounds[Min(Beam.Links,3)]; Instigator.SoundVolume = SentLinkVolume; Beam.LinkedPawn = LockedPawn; Beam.bHitSomething = (Other != None); Beam.EndEffect = EndEffect; } } } else StopFiring(); bStartFire = false; bDoHit = false; } simulated function UpdateLinkColor( LinkAttachment.ELinkColor Color ) { if ( FlashEmitter == None ) return; switch ( Color ) { case LC_Green : FlashEmitter.Skins[0] = Texture'XEffectMat.link_muz_green'; break; case LC_Gold : FlashEmitter.Skins[0] = Texture'XEffectMat.link_muz_yellow'; break; case LC_Red : FlashEmitter.Skins[0] = Texture'XEffectMat.link_muz_red'; break; case LC_Blue : FlashEmitter.Skins[0] = Texture'XEffectMat.link_muz_blue'; break; } } function bool BoundError() { CurrentAimError.Yaw = CurrentAimError.Yaw & 65535; if ( CurrentAimError.Yaw > 2048 ) { if ( CurrentAimError.Yaw < 32768 ) { CurrentAimError.Yaw = 2048; return true; } else if ( CurrentAimError.Yaw < 63487 ) { CurrentAimError.Yaw = 63487; return true; } } return false; } event ModeDoFire() { Load = 0; //don't use ammo here - it will be consumed in ModeTick() where it's sync'ed with damage dealing Super.ModeDoFire(); } function DoFireEffect() { bDoHit = true; UpTime = FireRate+0.1; } function PlayFiring() { if (LinkGun(Weapon).Links <= 0 && Weapon.AmmoAmount(ThisModeNum) >= AmmoPerFire) ClientPlayForceFeedback("BLinkGunBeam1"); Super.PlayFiring(); } function StopFiring() { Instigator.AmbientSound = None; Instigator.SoundVolume = Instigator.Default.SoundVolume; if (Beam != None) { Beam.Destroy(); Beam = None; } SetLinkTo(None); bStartFire = true; bFeedbackDeath = false; if (LinkGun(Weapon).Links <= 0) StopForceFeedback("BLinkGunBeam1"); } function SetLinkTo(Pawn Other) { if (LockedPawn != None && Weapon != None) { RemoveLink(1 + LinkGun(Weapon).Links, Instigator); LinkGun(Weapon).Linking = false; } LockedPawn = Other; if (LockedPawn != None) { if (!AddLink(1 + LinkGun(Weapon).Links, Instigator)) { bFeedbackDeath = true; } LinkGun(Weapon).Linking = true; LockedPawn.PlaySound(MakeLinkSound, SLOT_None); } } function bool AddLink(int Size, Pawn Starter) { local Inventory Inv; if (LockedPawn != None && !bFeedbackDeath) { if (LockedPawn == Starter) { return false; } else { Inv = LockedPawn.FindInventoryType(class'LinkGun'); if (Inv != None) { if (LinkFire(LinkGun(Inv).GetFireMode(1)).AddLink(Size, Starter)) LinkGun(Inv).Links += Size; else return false; } } } return true; } function RemoveLink(int Size, Pawn Starter) { local Inventory Inv; if (LockedPawn != None && !bFeedbackDeath) { if (LockedPawn != Starter) { Inv = LockedPawn.FindInventoryType(class'LinkGun'); if (Inv != None) { LinkFire(LinkGun(Inv).GetFireMode(1)).RemoveLink(Size, Starter); LinkGun(Inv).Links -= Size; } } } } function bool IsLinkable(Actor Other) { local Pawn P; local LinkGun LG; local LinkFire LF; local int sanity; if ( Other.IsA('Pawn') && Other.bProjTarget ) { P = Pawn(Other); if ( P.Weapon == None || !P.Weapon.IsA('LinkGun') ) { if ( Vehicle(P) != None ) return P.TeamLink( Instigator.GetTeamNum() ); return false; } // pro-actively prevent link cycles from happening LG = LinkGun(P.Weapon); LF = LinkFire(LG.GetFireMode(1)); while ( LF != None && LF.LockedPawn != None && LF.LockedPawn != P && sanity < 32 ) { if ( LF.LockedPawn == Instigator ) return false; LG = LinkGun(LF.LockedPawn.Weapon); if ( LG == None ) break; LF = LinkFire(LG.GetFireMode(1)); sanity++; } return ( Level.Game.bTeamGame && P.GetTeamNum() == Instigator.GetTeamNum() ); } return false; } simulated function vector GetFireStart(vector X, vector Y, vector Z) { return Instigator.Location + Instigator.EyePosition() + X*Instigator.CollisionRadius; } function StartBerserk() { if ( (Level.GRI != None) && (Level.GRI.WeaponBerserk > 1.0) ) return; Damage = default.Damage * 1.33; Damage = default.Damage * 1.33; } function StopBerserk() { if ( (Level.GRI != None) && (Level.GRI.WeaponBerserk > 1.0) ) return; Damage = default.Damage; Damage = default.Damage; } Y%C class LinkBeamEffect extends xEmitter; #exec OBJ LOAD FILE=XEffectMat.utx var Vector StartEffect, EndEffect; var byte Links, OldLinks; var byte LinkColor, OldLinkColor; var bool bLockedOn, bHitSomething; var Pawn LinkedPawn; var Vector EffectOffset; var Vector PrevLoc; var Rotator PrevRot; var float scorchtime; var LinkSparks Sparks; var LinkProtSphere ProtSphere; var LinkMuzFlashBeam3rd MuzFlash, OldMuzFlash; const MAX_CHILDREN = 4; var int NumChildren; var LinkBeamChild Child[MAX_CHILDREN]; replication { unreliable if (Role == ROLE_Authority) Links, LinkColor, LinkedPawn, bLockedOn, bHitSomething; unreliable if ( (Role == ROLE_Authority) && (!bNetOwner || bDemoRecording || bRepClientDemo) ) StartEffect, EndEffect; } simulated function Destroyed() { local int c; if ( Sparks != None ) { Sparks.SetTimer(0, false); Sparks.mRegen = false; Sparks.LightType = LT_None; } if ( MuzFlash != None ) MuzFlash.mRegen = false; if ( ProtSphere != None ) ProtSphere.Destroy(); for (c=0; c 0 ) { Skins[0] = FinalBlend'XEffectMat.LinkBeamYellowFB'; if ( MuzFlash != None ) MuzFlash.Skins[0] = Texture'XEffectMat.link_muz_yellow'; LightHue = 40; } else { Skins[0] = FinalBlend'XEffectMat.LinkBeamGreenFB'; if ( MuzFlash != None ) MuzFlash.Skins[0] = Texture'XEffectMat.link_muz_green'; LightHue = 100; } } else if ( LinkColor == 1 ) { Skins[0] = FinalBlend'XEffectMat.LinkBeamRedFB'; if ( MuzFlash != None ) MuzFlash.Skins[0] = Texture'XEffectMat.link_muz_red'; LightHue = 0; } else { Skins[0] = FinalBlend'XEffectMat.LinkBeamBlueFB'; if ( MuzFlash != None ) MuzFlash.Skins[0] = Texture'XEffectMat.link_muz_blue'; LightHue = 160; } if ( MuzFlash != None ) { MuzFlash.mSizeRange[0] = MuzFlash.default.mSizeRange[0] * (ls*0.5 + 1); MuzFlash.mSizeRange[1] = MuzFlash.mSizeRange[0]; } LightBrightness = 180 + 40*ls; LightRadius = 6 + 3*ls; if ( Sparks != None ) { Sparks.SetLinkStatus(Links, (LinkColor > 0), ls); Sparks.bHidden = (LinkColor > 0); Sparks.LightHue = LightHue; Sparks.LightBrightness = LightBrightness; Sparks.LightRadius = LightRadius - 3; } if ( LinkColor > 0 && LinkedPawn != None ) { if ( (ProtSphere == None) && (Level.NetMode != NM_DedicatedServer) ) { ProtSphere = Spawn(class'LinkProtSphere'); if (LinkColor == 2) ProtSphere.Skins[0] = Texture'XEffectMat.link_muz_blue'; } } OldLinks = Links; OldLinkColor = LinkColor; OldMuzFlash = MuzFlash; } if ( Level.bDropDetail || Level.DetailMode == DM_Low ) { bDynamicLight = false; LightType = LT_None; } else if ( bDynamicLight ) LightType = LT_Steady; if ( LinkedPawn != None ) { EndEffect = LinkedPawn.Location + LinkedPawn.EyeHeight*Vect(0,0,0.5) - BeamDir*30.0; } mSpawnVecA = EndEffect; mWaveLockEnd = bLockedOn || (LinkColor > 0); // magic wiggle code if ( bLockedOn || (LinkColor > 0) ) { mWaveAmplitude = FMax(0.0, mWaveAmplitude - (mWaveAmplitude+5)*4.0*dt); } else { LocDiff = VSize((Location - PrevLoc) * Vect(1,1,5)); RotDiff = VSize(Vector(Rotation) - Vector(PrevRot)); WiggleMe = FMax(LocDiff*0.02, RotDiff*4.0); mWaveAmplitude = FMax(1.0, mWaveAmplitude - mWaveAmplitude*1.0*dt); mWaveAmplitude = FMin(16.0, mWaveAmplitude + WiggleMe); } PrevLoc = Location; PrevRot = Rotation; for (c=0; c 0); //mWaveLockEnd; Child[c].Skins[0] = Skins[0]; } } if ( Sparks != None ) { Sparks.SetLocation( EndEffect - BeamDir*10.0 ); if ( bHitSomething ) Sparks.SetRotation( Rotation); else Sparks.SetRotation( Rotator(-BeamDir) ); Sparks.mRegenRange[0] = Sparks.DesiredRegen; Sparks.mRegenRange[1] = Sparks.DesiredRegen; Sparks.bDynamicLight = true; } if ( LinkColor > 0 && LinkedPawn != None ) { if ( ProtSphere != None ) { ProtSphere.SetLocation( EndEffect ); ProtSphere.SetRotation( Rotation ); ProtSphere.bHidden = false; if ( LinkedPawn.IsFirstPerson() ) ProtSphere.mSizeRange[0] = 20.0; else ProtSphere.mSizeRange[0] = 35.0; ProtSphere.mSizeRange[1] = ProtSphere.mSizeRange[0]; } } else { if ( ProtSphere != None ) ProtSphere.bHidden = true; } if ( bHitSomething && (Level.NetMode != NM_DedicatedServer) && (Level.TimeSeconds - ScorchTime > 0.07) ) { ScorchTime = Level.TimeSeconds; HitActor = Trace(HitLocation, HitNormal, EndEffect + 100*BeamDir, EndEffect - 100*BeamDir, true); if ( (HitActor != None) && HitActor.bWorldGeometry ) spawn(class'LinkScorch',,,HitLocation,rotator(-HitNormal)); } } Y%R class LinkBeamChild extends xEmitter; #exec OBJ LOAD FILE=XEffectMat.utx Y%c#class LinkAttachment extends xWeaponAttachment; var LinkMuzFlashProj3rd MuzFlash; var int Links; var bool bReplicateLinkColor; enum ELinkColor { LC_Green, LC_Red, LC_Blue, LC_Gold, }; var ELinkColor LinkColor; replication { reliable if ( Role == ROLE_Authority ) Links; reliable if ( bReplicateLinkColor && !bNetOwner && bNetDirty && Role == ROLE_Authority ) LinkColor; } /* change link color, and update all effects */ simulated function SetLinkColor( ELinkColor NewColor ) { if ( NewColor == LinkColor ) return; if ( bReplicateLinkColor ) NetUpdateTime = Level.TimeSeconds - 1; LinkColor = NewColor; if ( Level.NetMode != NM_DedicatedServer ) UpdateLinkColor(); } simulated function UpdateLinkColor() { if ( Instigator != None && Instigator.Weapon != None ) LinkGun(Instigator.Weapon).UpdateLinkColor( LinkColor ); if ( MuzFlash != None ) { switch ( LinkColor ) { case LC_Gold : MuzFlash.Skins[0] = FinalBlend'XEffectMat.LinkMuzProjYellowFB'; break; case LC_Green : default : MuzFlash.Skins[0] = FinalBlend'XEffectMat.LinkMuzProjGreenFB'; break; } } } simulated function Destroyed() { if ( MuzFlash != None ) MuzFlash.Destroy(); super.Destroyed(); } simulated event ThirdPersonEffects() { local Rotator R; if ( Level.NetMode != NM_DedicatedServer && FlashCount > 0 ) { if (FiringMode == 0) { if (MuzFlash == None) { MuzFlash = Spawn(class'LinkMuzFlashProj3rd'); AttachToBone(MuzFlash, 'tip'); UpdateLinkColor(); } if (MuzFlash != None) { MuzFlash.mSizeRange[0] = MuzFlash.default.mSizeRange[0] * (class'LinkFire'.default.LinkScale[Min(Links,5)]+1); // (1.0 + 0.3*float(Links)); MuzFlash.mSizeRange[1] = MuzFlash.mSizeRange[0]; if ( Links > 0 ) SetLinkColor( LC_Gold ); else SetLinkColor( LC_Green ); MuzFlash.Trigger(self, None); R.Roll = Rand(65536); SetBoneRotation('bone flashA', R, 0, 1.0); } } } super.ThirdPersonEffects(); } Y%lclass LinkAmmoPickup extends UTAmmoPickup; function PostBeginPlay() { Super.PostBeginPlay(); if ( Level.Game.bAllowVehicles ) MaxDesireability *= 1.9; } Y%Sclass LinkAmmo extends Ammunition; #EXEC OBJ LOAD FILE=InterfaceContent.utx Y%j class LinkAltFire extends ProjectileFire; var sound LinkedFireSound; var string LinkedFireForce; // jdf function DrawMuzzleFlash(Canvas Canvas) { if (FlashEmitter != None) { FlashEmitter.SetRotation(Weapon.Rotation); Super.DrawMuzzleFlash(Canvas); } } simulated function bool AllowFire() { return ( Weapon.AmmoAmount(ThisModeNum) >= 1 ); } function Projectile SpawnProjectile(Vector Start, Rotator Dir) { local LinkProjectile Proj; Start += Vector(Dir) * 10.0 * LinkGun(Weapon).Links; Proj = Weapon.Spawn(class'XWeapons.LinkProjectile',,, Start, Dir); if ( Proj != None ) { Proj.Links = LinkGun(Weapon).Links; Proj.LinkAdjust(); } return Proj; } function FlashMuzzleFlash() { if (FlashEmitter != None) { if (LinkGun(Weapon).Links > 0) FlashEmitter.Skins[0] = FinalBlend'XEffectMat.LinkMuzProjYellowFB'; else FlashEmitter.Skins[0] = FinalBlend'XEffectMat.LinkMuzProjGreenFB'; } Super.FlashMuzzleFlash(); } function ServerPlayFiring() { if (LinkGun(Weapon).Links > 0) FireSound = LinkedFireSound; else FireSound = default.FireSound; Super.ServerPlayFiring(); } function PlayFiring() { if (LinkGun(Weapon).Links > 0) FireSound = LinkedFireSound; else FireSound = default.FireSound; Super.PlayFiring(); } Y%i // ==================================================================== // Class: XWeapons.LimitationVolume // Parent: Engine.Volume // // Used to limit where various objects can go. // ==================================================================== class LimitationVolume extends Volume; var (Limits) bool bLimitTransDisc; var (Limits) bool bLimitProjectiles; var (Limits) class LimitEffectClass; event touch( Actor Other ) { if ( ((bLimitTransDisc) && (TransBeacon(Other)!=None)) || ((bLimitProjectiles) && (Projectile(Other)!=None)) ) { if (LimitEffectClass!=None) Spawn(LimitEffectClass,,,Other.Location, Other.Rotation); Projectile(Other).bNoFX = true; Other.Destroy(); } } f#@T 2g#8ޤʁ)ʁ)ȵʁ)Y%Y%U\//============================================================================= // The IonCannon //============================================================================= class IonCannon extends Actor placeable; var() Sound FireSound; var() Vector MarkLocation; var() class IonEffectClass; var() int Damage; // per wave var() float MomentumTransfer; // per wave var() float DamageRadius; // of final wave var() class DamageType; var Vector BeamDirection; var Vector DamageLocation; var AvoidMarker Fear; // camera shakes // var() vector ShakeRotMag; // how far to rot view var() vector ShakeRotRate; // how fast to rot view var() float ShakeRotTime; // how much time to rot the instigator's view var() vector ShakeOffsetMag; // max view offset vertically var() vector ShakeOffsetRate; // how fast to offset view vertically var() float ShakeOffsetTime; // how much time to offset view function PostBeginPlay() { local IonCannon C; Super.PostBeginPlay(); if ( bDeleteMe ) return; ForEach DynamicActors(Class'IonCannon',C) { if ( C != self ) C.Destroy(); } } function bool CheckMark(Pawn Aimer, Vector TestMark, bool bFire) { return false; } auto state Ready { function bool CheckMark(Pawn Aimer, Vector TestMark, bool bFire) { local Actor Other; local Vector HitLocation, HitNormal,Top; if (IsFiring()) return false; Top = TestMark; Top.Z = Location.Z; Other = Trace(HitLocation, HitNormal, Top, TestMark, false); if ( Other != None ) return false; if (bFire) { Instigator = Aimer; MarkLocation = TestMark; GotoState('FireSequence'); } return true; } } function RemoveFear() { if ( Fear != None ) Fear.Destroy(); } state FireSequence { function RemoveFear(); function bool IsFiring() { return true; } function BeginState() { BeamDirection = vect(0,0,-1); DamageLocation = MarkLocation - BeamDirection * 200.0; } function SpawnEffect() { local IonEffect IonBeamEffect; local Actor Other; local Vector HitLocation, HitNormal, Top, CP; Other = Trace(HitLocation, HitNormal, MarkLocation + vect(0,0,10000), MarkLocation, false); Top = MarkLocation; Top.Z = FMax(HitLocation.Z,Location.Z); IonBeamEffect = Spawn(IonEffectClass,,, Top); if (IonBeamEffect != None) IonBeamEffect.AimAt(MarkLocation, Vect(0,0,1)); if ( Instigator != None ) CP = Normal(vect(0,0,1) Cross (Location - Instigator.Location)); else CP = vect(1,0,0); CP *= 0.5 * (Location.Z - MarkLocation.Z); Other = Trace(HitLocation, HitNormal, Top + CP, MarkLocation, false); if ( Other == None ) { IonBeamEffect = Spawn(IonEffectClass,,, Top + CP); if (IonBeamEffect != None) IonBeamEffect.AimAt(MarkLocation, Vect(0,0,1)); } Other = Trace(HitLocation, HitNormal, Top - CP, MarkLocation, false); if ( Other == None ) { IonBeamEffect = Spawn(IonEffectClass,,, Top - CP); if (IonBeamEffect != None) IonBeamEffect.AimAt(MarkLocation, Vect(0,0,1)); } } function ShakeView() { local Controller C; local PlayerController PC; local float Dist, Scale; for ( C=Level.ControllerList; C!=None; C=C.NextController ) { PC = PlayerController(C); if ( PC != None && PC.ViewTarget != None && PC.ViewTarget.Base != None ) { Dist = VSize(DamageLocation - PC.ViewTarget.Location); if ( Dist < DamageRadius * 2.0) { if (Dist < DamageRadius) Scale = 1.0; else Scale = (DamageRadius*2.0 - Dist) / (DamageRadius); C.ShakeView(ShakeRotMag*Scale, ShakeRotRate, ShakeRotTime, ShakeOffsetMag*Scale, ShakeOffsetRate, ShakeOffsetTime); } } } } function PlayGlobalSound(sound S) { local PlayerController P; ForEach DynamicActors(class'PlayerController', P) P.ClientPlaySound(S); } function EndState() { if ( (Instigator != None) && (Painter(Instigator.Weapon) != None) ) Instigator.Weapon.CheckOutOfAmmo(); if ( Fear != None ) Fear.Destroy(); } Begin: if ( Fear == None ) Fear = Spawn(class'AvoidMarker',,,MarkLocation); Fear.SetCollisionSize(DamageRadius,200); if ( (Instigator != None) && (Instigator.PlayerReplicationInfo != None) && (Instigator.PlayerReplicationInfo.Team != None) ) Fear.TeamNum = Instigator.PlayerReplicationInfo.Team.TeamIndex; Fear.StartleBots(); Sleep(0.5); SpawnEffect(); PlayGlobalSound(FireSound); Sleep(0.5); ShakeView(); HurtRadius(Damage, DamageRadius*0.125, DamageType, MomentumTransfer, DamageLocation); Sleep(0.5); PlayGlobalSound(sound'WeaponSounds.redeemer_explosionsound'); HurtRadius(Damage, DamageRadius*0.300, DamageType, MomentumTransfer, DamageLocation); Sleep(0.2); HurtRadius(Damage, DamageRadius*0.475, DamageType, MomentumTransfer, DamageLocation); Sleep(0.2); HurtRadius(Damage, DamageRadius*0.650, DamageType, MomentumTransfer, DamageLocation); Sleep(0.2); HurtRadius(Damage, DamageRadius*0.825, DamageType, MomentumTransfer, DamageLocation); Sleep(0.2); HurtRadius(Damage, DamageRadius*1.000, DamageType, MomentumTransfer, DamageLocation); GotoState('Ready'); } function bool IsFiring() { return false; } Y%M0class InstantFire extends WeaponFire; var class DamageType; var int DamageMin, DamageMax; var float TraceRange; var float Momentum; function float MaxRange() { if (Instigator.Region.Zone.bDistanceFog) TraceRange = FClamp(Instigator.Region.Zone.DistanceFogEnd, 8000, default.TraceRange); else TraceRange = default.TraceRange; return TraceRange; } function DoFireEffect() { local Vector StartTrace; local Rotator R, Aim; Instigator.MakeNoise(1.0); // the to-hit trace always starts right in front of the eye StartTrace = Instigator.Location + Instigator.EyePosition(); Aim = AdjustAim(StartTrace, AimError); R = rotator(vector(Aim) + VRand()*FRand()*Spread); DoTrace(StartTrace, R); } function DoTrace(Vector Start, Rotator Dir) { local Vector X, End, HitLocation, HitNormal, RefNormal; local Actor Other; local int Damage; local bool bDoReflect; local int ReflectNum; MaxRange(); ReflectNum = 0; while (true) { bDoReflect = false; X = Vector(Dir); End = Start + TraceRange * X; Other = Weapon.Trace(HitLocation, HitNormal, End, Start, true); if ( Other != None && (Other != Instigator || ReflectNum > 0) ) { if (bReflective && Other.IsA('xPawn') && xPawn(Other).CheckReflect(HitLocation, RefNormal, DamageMin*0.25)) { bDoReflect = true; HitNormal = Vect(0,0,0); } else if ( !Other.bWorldGeometry ) { Damage = DamageMin; if ( (DamageMin != DamageMax) && (FRand() > 0.5) ) Damage += Rand(1 + DamageMax - DamageMin); Damage = Damage * DamageAtten; // Update hit effect except for pawns (blood) other than vehicles. if ( Other.IsA('Vehicle') || (!Other.IsA('Pawn') && !Other.IsA('HitScanBlockingVolume')) ) WeaponAttachment(Weapon.ThirdPersonActor).UpdateHit(Other, HitLocation, HitNormal); Other.TakeDamage(Damage, Instigator, HitLocation, Momentum*X, DamageType); HitNormal = Vect(0,0,0); } else if ( WeaponAttachment(Weapon.ThirdPersonActor) != None ) WeaponAttachment(Weapon.ThirdPersonActor).UpdateHit(Other,HitLocation,HitNormal); } else { HitLocation = End; HitNormal = Vect(0,0,0); WeaponAttachment(Weapon.ThirdPersonActor).UpdateHit(Other,HitLocation,HitNormal); } SpawnBeamEffect(Start, Dir, HitLocation, HitNormal, ReflectNum); if (bDoReflect && ++ReflectNum < 4) { //Log("reflecting off"@Other@Start@HitLocation); Start = HitLocation; Dir = Rotator(RefNormal); //Rotator( X - 2.0*RefNormal*(X dot RefNormal) ); } else { break; } } } function SpawnBeamEffect(Vector Start, Rotator Dir, Vector HitLocation, Vector HitNormal, int ReflectNum) { } Y%K// ==================================================================== // Class: XWeapons.HitScanBlockingVolume // Parent: Engine.BlockingVolume // // Used to limit where hit-scan weapons // ==================================================================== class HitScanBlockingVolume extends BlockingVolume; j#V 2k#.!e.I SD Y%Y%]class HitEffect extends Effects; var(HitEffect) class HitEffectDefault; var(HitEffect) class HitEffectRock; var(HitEffect) class HitEffectDirt; var(HitEffect) class HitEffectMetal; var(HitEffect) class HitEffectWood; var(HitEffect) class HitEffectPlant; var(HitEffect) class HitEffectFlesh; var(HitEffect) class HitEffectIce; var(HitEffect) class HitEffectSnow; var(HitEffect) class HitEffectWater; var(HitEffect) class HitEffectGlass; static function class GetHitEffect( Actor Victim, Vector HitLocation, Vector HitNormal ) { if (Victim == None) return Default.HitEffectDefault; switch (Victim.SurfaceType) { case EST_Rock: return Default.HitEffectRock; case EST_Dirt: return Default.HitEffectDirt; case EST_Metal: return Default.HitEffectMetal; case EST_Wood: return Default.HitEffectWood; case EST_Plant: return Default.HitEffectPlant; case EST_Flesh: return Default.HitEffectFlesh; case EST_Ice: return Default.HitEffectIce; case EST_Snow: return Default.HitEffectSnow; case EST_Water: return Default.HitEffectWater; case EST_Glass: return Default.HitEffectGlass; default: return Default.HitEffectDefault; } } Y%*class GrenadeAmmo extends Ammunition; Y%M@//============================================================================= // Grenade. //============================================================================= class Grenade extends Projectile; var float ExplodeTimer; var bool bCanHitOwner, bHitWater; var xEmitter Trail; var() float DampenFactor, DampenFactorParallel; var class HitEffectClass; var float LastSparkTime; var bool bTimerSet; replication { reliable if (Role==ROLE_Authority) ExplodeTimer; } simulated function Destroyed() { if ( Trail != None ) Trail.mRegen = false; // stop the emitter from regenerating Super.Destroyed(); } simulated function PostBeginPlay() { local PlayerController PC; Super.PostBeginPlay(); if ( Level.NetMode != NM_DedicatedServer) { PC = Level.GetLocalPlayerController(); if ( (PC.ViewTarget != None) && VSize(PC.ViewTarget.Location - Location) < 5500 ) Trail = Spawn(class'GrenadeSmokeTrail', self,, Location, Rotation); } if ( Role == ROLE_Authority ) { Velocity = Speed * Vector(Rotation); RandSpin(25000); bCanHitOwner = false; if (Instigator.HeadVolume.bWaterVolume) { bHitWater = true; Velocity = 0.6*Velocity; } } } simulated function PostNetBeginPlay() { if ( Physics == PHYS_None ) { SetTimer(ExplodeTimer, false); bTimerSet = true; } } simulated function Timer() { Explode(Location, vect(0,0,1)); } simulated function Landed( vector HitNormal ) { HitWall( HitNormal, None ); } simulated function ProcessTouch( actor Other, vector HitLocation ) { if ( !Other.bWorldGeometry && (Other != Instigator || bCanHitOwner) ) { Explode(HitLocation, Normal(HitLocation-Other.Location)); } } simulated function HitWall( vector HitNormal, actor Wall ) { local Vector VNorm; local PlayerController PC; if ( (Pawn(Wall) != None) || (GameObjective(Wall) != None) ) { Explode(Location, HitNormal); return; } if (!bTimerSet) { SetTimer(ExplodeTimer, false); bTimerSet = true; } // Reflect off Wall w/damping VNorm = (Velocity dot HitNormal) * HitNormal; Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel; RandSpin(100000); DesiredRotation.Roll = 0; RotationRate.Roll = 0; Speed = VSize(Velocity); if ( Speed < 20 ) { bBounce = False; PrePivot.Z = -1.5; SetPhysics(PHYS_None); DesiredRotation = Rotation; DesiredRotation.Roll = 0; DesiredRotation.Pitch = 0; SetRotation(DesiredRotation); if ( Trail != None ) Trail.mRegen = false; // stop the emitter from regenerating } else { if ( (Level.NetMode != NM_DedicatedServer) && (Speed > 250) ) PlaySound(ImpactSound, SLOT_Misc ); else { bFixedRotationDir = false; bRotateToDesired = true; DesiredRotation.Pitch = 0; RotationRate.Pitch = 50000; } if ( !Level.bDropDetail && (Level.DetailMode != DM_Low) && (Level.TimeSeconds - LastSparkTime > 0.5) && EffectIsRelevant(Location,false) ) { PC = Level.GetLocalPlayerController(); if ( (PC.ViewTarget != None) && VSize(PC.ViewTarget.Location - Location) < 6000 ) Spawn(HitEffectClass,,, Location, Rotator(HitNormal)); LastSparkTime = Level.TimeSeconds; } } } simulated function BlowUp(vector HitLocation) { DelayedHurtRadius(Damage,DamageRadius, MyDamageType, MomentumTransfer, HitLocation ); if ( Role == ROLE_Authority ) MakeNoise(1.0); } simulated function Explode(vector HitLocation, vector HitNormal) { BlowUp(HitLocation); PlaySound(sound'WeaponSounds.BExplosion3',,2.5*TransientSoundVolume); if ( EffectIsRelevant(Location,false) ) { Spawn(class'NewExplosionB',,, HitLocation, rotator(vect(0,0,1))); Spawn(ExplosionDecal,self,,HitLocation, rotator(-HitNormal)); } Destroy(); } Y%o+//============================================================================= // flakshell //============================================================================= class flakshell extends Projectile; #exec TEXTURE IMPORT NAME=NewFlakSkin FILE=textures\jflakslugel1.bmp GROUP="Skins" DXT=5 var xemitter trail; var vector initialDir; var actor Glow; simulated function PostBeginPlay() { local Rotator R; local PlayerController PC; if ( !PhysicsVolume.bWaterVolume && (Level.NetMode != NM_DedicatedServer) ) { PC = Level.GetLocalPlayerController(); if ( (PC.ViewTarget != None) && VSize(PC.ViewTarget.Location - Location) < 6000 ) Trail = Spawn(class'FlakShellTrail',self); Glow = Spawn(class'FlakGlow', self); } Super.PostBeginPlay(); Velocity = Vector(Rotation) * Speed; R = Rotation; R.Roll = 32768; SetRotation(R); Velocity.z += TossZ; initialDir = Velocity; } simulated function destroyed() { if ( Trail != None ) Trail.mRegen=False; if ( glow != None ) Glow.Destroy(); Super.Destroyed(); } simulated function ProcessTouch(Actor Other, Vector HitLocation) { if ( Other != Instigator ) { SpawnEffects(HitLocation, -1 * Normal(Velocity) ); Explode(HitLocation,Normal(HitLocation-Other.Location)); } } simulated function SpawnEffects( vector HitLocation, vector HitNormal ) { local PlayerController PC; PlaySound (Sound'WeaponSounds.BExplosion1',,3*TransientSoundVolume); if ( EffectIsRelevant(Location,false) ) { PC = Level.GetLocalPlayerController(); if ( (PC.ViewTarget != None) && VSize(PC.ViewTarget.Location - Location) < 3000 ) spawn(class'FlakExplosion',,,HitLocation + HitNormal*16 ); spawn(class'FlashExplosion',,,HitLocation + HitNormal*16 ); spawn(class'RocketSmokeRing',,,HitLocation + HitNormal*16, rotator(HitNormal) ); if ( (ExplosionDecal != None) && (Level.NetMode != NM_DedicatedServer) ) Spawn(ExplosionDecal,self,,HitLocation, rotator(-HitNormal)); } } simulated function Landed( vector HitNormal ) { SpawnEffects( Location, HitNormal ); Explode(Location,HitNormal); } simulated function HitWall (vector HitNormal, actor Wall) { Landed(HitNormal); } simulated function Explode(vector HitLocation, vector HitNormal) { local vector start; local rotator rot; local int i; local FlakChunk NewChunk; start = Location + 10 * HitNormal; if ( Role == ROLE_Authority ) { HurtRadius(damage, 220, MyDamageType, MomentumTransfer, HitLocation); for (i=0; i<6; i++) { rot = Rotation; rot.yaw += FRand()*32000-16000; rot.pitch += FRand()*32000-16000; rot.roll += FRand()*32000-16000; NewChunk = Spawn( class 'FlakChunk',, '', Start, rot); } } Destroy(); } Y%sclass FlakFire extends ProjectileFire; function InitEffects() { Super.InitEffects(); if ( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'tip'); } Y%e S TyrS *e S  ,$} 7$A B$F M$G X$H c$I n$L y$R $ S $ V e  G Y%{1//============================================================================= // FlakChunk. //============================================================================= class FlakChunk extends Projectile; var xEmitter Trail; var byte Bounces; var float DamageAtten; var sound ImpactSounds[6]; replication { reliable if (bNetInitial && Role == ROLE_Authority) Bounces; } simulated function Destroyed() { if (Trail !=None) Trail.mRegen=False; Super.Destroyed(); } simulated function PostBeginPlay() { local float r; if ( Level.NetMode != NM_DedicatedServer ) { if ( !PhysicsVolume.bWaterVolume ) { Trail = Spawn(class'FlakTrail',self); Trail.Lifespan = Lifespan; } } Velocity = Vector(Rotation) * (Speed); if (PhysicsVolume.bWaterVolume) Velocity *= 0.65; r = FRand(); if (r > 0.75) Bounces = 2; else if (r > 0.25) Bounces = 1; else Bounces = 0; SetRotation(RotRand()); Super.PostBeginPlay(); } simulated function ProcessTouch (Actor Other, vector HitLocation) { if ( (FlakChunk(Other) == None) && ((Physics == PHYS_Falling) || (Other != Instigator)) ) { speed = VSize(Velocity); if ( speed > 200 ) { if ( Role == ROLE_Authority ) { if ( Instigator == None || Instigator.Controller == None ) Other.SetDelayedDamageInstigatorController( InstigatorController ); Other.TakeDamage( Max(5, Damage - DamageAtten*FMax(0,(default.LifeSpan - LifeSpan - 1))), Instigator, HitLocation, (MomentumTransfer * Velocity/speed), MyDamageType ); } } Destroy(); } } simulated function Landed( Vector HitNormal ) { SetPhysics(PHYS_None); LifeSpan = 1.0; } simulated function HitWall( vector HitNormal, actor Wall ) { if ( !Wall.bStatic && !Wall.bWorldGeometry && ((Mover(Wall) == None) || Mover(Wall).bDamageTriggered) ) { if ( Level.NetMode != NM_Client ) { if ( Instigator == None || Instigator.Controller == None ) Wall.SetDelayedDamageInstigatorController( InstigatorController ); Wall.TakeDamage( Damage, instigator, Location, MomentumTransfer * Normal(Velocity), MyDamageType); } Destroy(); return; } SetPhysics(PHYS_Falling); if (Bounces > 0) { if ( !Level.bDropDetail && (FRand() < 0.4) ) Playsound(ImpactSounds[Rand(6)]); Velocity = 0.65 * (Velocity - 2.0*HitNormal*(Velocity dot HitNormal)); Bounces = Bounces - 1; return; } bBounce = false; if (Trail != None) { Trail.mRegen=False; Trail.SetPhysics(PHYS_None); //Trail.mRegenRange[0] = 0.0;//trail.mRegenRange[0] * 0.6; //Trail.mRegenRange[1] = 0.0;//trail.mRegenRange[1] * 0.6; } } simulated function PhysicsVolumeChange( PhysicsVolume Volume ) { if (Volume.bWaterVolume) { if ( Trail != None ) Trail.mRegen=False; Velocity *= 0.65; } } Y%t#Y%Y%u#Y%Y%Y%Y%//============================================================================= // FlakCannonPickup. //============================================================================= class FlakCannonPickup extends UTWeaponPickup; #exec OBJ LOAD FILE=WeaponStaticMesh.usx static function StaticPrecache(LevelInfo L) { L.AddPrecacheMaterial(Texture'XEffects.FlakTrailTex'); if ( L.DetailMode != DM_Low ) L.AddPrecacheMaterial(Texture'XEffects.fexpt'); L.AddPrecacheMaterial(Texture'XEffects.ExplosionFlashTex'); L.AddPrecacheMaterial(Texture'XEffects.GoldGlow'); L.AddPrecacheMaterial(Texture'WeaponSkins.FlakTex0'); L.AddPrecacheMaterial(Texture'WeaponSkins.FlakTex1'); L.AddPrecacheMaterial(Texture'WeaponSkins.FlakChunkTex'); L.AddPrecacheMaterial(Texture'XWeapons.NewFlakSkin'); L.AddPrecacheMaterial(Texture'XGameShaders.flak_flash'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.flakchunk'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.flakshell'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.FlakCannonPickup'); } simulated function UpdatePrecacheMaterials() { Level.AddPrecacheMaterial(Texture'XEffects.FlakTrailTex'); if ( Level.DetailMode != DM_Low ) Level.AddPrecacheMaterial(Texture'XEffects.fexpt'); Level.AddPrecacheMaterial(Texture'XEffects.ExplosionFlashTex'); Level.AddPrecacheMaterial(Texture'XEffects.GoldGlow'); Level.AddPrecacheMaterial(Texture'WeaponSkins.FlakTex0'); Level.AddPrecacheMaterial(Texture'WeaponSkins.FlakTex1'); Level.AddPrecacheMaterial(Texture'WeaponSkins.FlakChunkTex'); Level.AddPrecacheMaterial(Texture'XWeapons.NewFlakSkin'); Level.AddPrecacheMaterial(Texture'XGameShaders.flak_flash'); super.UpdatePrecacheMaterials(); } simulated function UpdatePrecacheStaticMeshes() { Level.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.flakchunk'); Level.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.flakshell'); Super.UpdatePrecacheStaticMeshes(); } Y%K"//============================================================================= // Flak Cannon //============================================================================= class FlakCannon extends Weapon config(user); #EXEC OBJ LOAD FILE=InterfaceContent.utx // AI Interface function float GetAIRating() { local Bot B; local float EnemyDist; local vector EnemyDir; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( (B.Target != None) && (Pawn(B.Target) == None) && (VSize(B.Target.Location - Instigator.Location) < 1250) ) return 0.9; if ( B.Enemy == None ) { if ( (B.Target != None) && VSize(B.Target.Location - B.Pawn.Location) > 3500 ) return 0.2; return AIRating; } EnemyDir = B.Enemy.Location - Instigator.Location; EnemyDist = VSize(EnemyDir); if ( EnemyDist > 750 ) { if ( EnemyDist > 2000 ) { if ( EnemyDist > 3500 ) return 0.2; return (AIRating - 0.3); } if ( EnemyDir.Z < -0.5 * EnemyDist ) return (AIRating - 0.3); } else if ( (B.Enemy.Weapon != None) && B.Enemy.Weapon.bMeleeWeapon ) return (AIRating + 0.35); else if ( EnemyDist < 400 ) return (AIRating + 0.2); return FMax(AIRating + 0.2 - (EnemyDist - 400) * 0.0008, 0.2); } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { local vector EnemyDir; local float EnemyDist; local bot B; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 0; EnemyDir = B.Enemy.Location - Instigator.Location; EnemyDist = VSize(EnemyDir); if ( EnemyDist > 750 ) { if ( EnemyDir.Z < -0.5 * EnemyDist ) return 1; return 0; } else if ( (B.Enemy.Weapon != None) && B.Enemy.Weapon.bMeleeWeapon ) return 0; else if ( (EnemyDist < 400) || (EnemyDir.Z > 30) ) return 0; else if ( FRand() < 0.65 ) return 1; return 0; } function float SuggestAttackStyle() { if ( (AIController(Instigator.Controller) != None) && (AIController(Instigator.Controller).Skill < 3) ) return 0.4; return 0.8; } function float SuggestDefenseStyle() { return -0.4; } // End AI Interface Y%r class FlakAttachment extends xWeaponAttachment; var class mMuzFlashClass; var xEmitter mMuzFlash3rd; simulated function Destroyed() { if (mMuzFlash3rd != None) mMuzFlash3rd.Destroy(); Super.Destroyed(); } simulated event ThirdPersonEffects() { local rotator r; if ( Level.NetMode != NM_DedicatedServer && FlashCount > 0 ) { WeaponLight(); if (mMuzFlash3rd == None) { mMuzFlash3rd = Spawn(mMuzFlashClass); AttachToBone(mMuzFlash3rd, 'tip'); } if (mMuzFlash3rd != None) { r.Roll = Rand(65536); SetBoneRotation('Bone_Flash', r, 0, 1.f); mMuzFlash3rd.mStartParticles++; } } Super.ThirdPersonEffects(); } Y%/class FlakAmmoPickup extends UTAmmoPickup; Y%Sclass FlakAmmo extends Ammunition; #EXEC OBJ LOAD FILE=InterfaceContent.utx Y%X FwX*Xa GY%{#jD(9:9:$2rX*Xa w*uX"a #A@AXa+X,H(Xa AXa+X,X X 9?j,zC%&aL>( GY%class FlakAltFire extends ProjectileFire; function InitEffects() { Super.InitEffects(); if ( FlashEmitter == None ) FlashEmitter = Weapon.GetFireMode(0).FlashEmitter; } Y%|#2%%% GY%~#lI7:bHB9?l,zC7-n}D,2 GY%?class DamTypeTeleFrag extends WeaponDamageType abstract; Y%>class DamTypeSuperShockBeam extends DamTypeShockBeam; Y%#j A.Bxx}??}xD,2x} GY%Dclass DamTypeSniperShot extends WeaponDamageType abstract; static function GetHitEffects(out class HitEffects[4], int VictemHealth ) { HitEffects[0] = class'HitSmoke'; } Y%U class DamTypeSniperHeadShot extends WeaponDamageType abstract; var class KillerMessage; var sound HeadHunter; // OBSOLETE static function IncrementKills(Controller Killer) { local xPlayerReplicationInfo xPRI; if ( PlayerController(Killer) == None ) return; PlayerController(Killer).ReceiveLocalizedMessage( Default.KillerMessage, 0, Killer.PlayerReplicationInfo, None, None ); xPRI = xPlayerReplicationInfo(Killer.PlayerReplicationInfo); if ( xPRI != None ) { xPRI.headcount++; if ( (xPRI.headcount == 15) && (UnrealPlayer(Killer) != None) ) UnrealPlayer(Killer).ClientDelayedAnnouncementNamed('HeadHunter',15); } } static function GetHitEffects(out class HitEffects[4], int VictemHealth ) { HitEffects[0] = class'HitSmoke'; HitEffects[1] = class'HitFlameBig'; } Y%O class DamTypeShockCombo extends WeaponDamageType abstract; var sound ComboWhore; // OBSOLETE static function GetHitEffects(out class HitEffects[4], int VictemHealth ) { HitEffects[0] = class'HitSmoke'; } static function IncrementKills(Controller Killer) { local xPlayerReplicationInfo xPRI; xPRI = xPlayerReplicationInfo(Killer.PlayerReplicationInfo); if ( xPRI != None ) { xPRI.combocount++; if ( (xPRI.combocount == 15) && (UnrealPlayer(Killer) != None) ) UnrealPlayer(Killer).ClientDelayedAnnouncementNamed('ComboWhore',15); } } Y%Cclass DamTypeShockBeam extends WeaponDamageType abstract; static function GetHitEffects(out class HitEffects[4], int VictemHealth ) { HitEffects[0] = class'HitSmoke'; } Y%Cclass DamTypeShockBall extends WeaponDamageType abstract; static function GetHitEffects(out class HitEffects[4], int VictemHealth ) { HitEffects[0] = class'HitSmoke'; } Y%Cclass DamTypeShieldImpact extends WeaponDamageType abstract; Y%5class DamTypeRocketHoming extends DamTypeRocket; Y%Uclass DamTypeRocket extends WeaponDamageType abstract; static function GetHitEffects(out class HitEffects[4], int VictimHealth ) { HitEffects[0] = class'HitSmoke'; if( VictimHealth <= 0 ) HitEffects[1] = class'HitFlameBig'; else if ( FRand() < 0.8 ) HitEffects[1] = class'HitFlame'; } Y%?class DamTypeRedeemer extends WeaponDamageType abstract; Y%Dclass DamTypeMinigunBullet extends WeaponDamageType abstract; Y%:class DamTypeMinigunAlt extends DamTypeMinigunBullet; Y%Cclass DamTypeLinkShaft extends WeaponDamageType abstract; static function GetHitEffects(out class HitEffects[4], int VictemHealth ) { HitEffects[0] = class'HitSmoke'; } Y%Dclass DamTypeLinkPlasma extends WeaponDamageType abstract; static function GetHitEffects(out class HitEffects[4], int VictemHealth ) { HitEffects[0] = class'HitSmoke'; } Y%?class DamTypeIonBlast extends WeaponDamageType abstract; Y%5class DamTypeFlakShell extends DamTypeFlakChunk; Y%Fclass DamTypeFlakChunk extends WeaponDamageType abstract; var sound FlakMonkey; //OBSOLETE static function IncrementKills(Controller Killer) { local xPlayerReplicationInfo xPRI; xPRI = xPlayerReplicationInfo(Killer.PlayerReplicationInfo); if ( xPRI != None ) { xPRI.flakcount++; if ( (xPRI.flakcount == 15) && (UnrealPlayer(Killer) != None) ) UnrealPlayer(Killer).ClientDelayedAnnouncementNamed('FlackMonkey',15); } } Y%>class DamTypeBioGlob extends WeaponDamageType abstract; Y%Eclass DamTypeAssaultGrenade extends WeaponDamageType abstract; Y%Dclass DamTypeAssaultBullet extends WeaponDamageType abstract; Y%qclass BlueSuperShockBeam extends ShockBeamEffect; simulated function SpawnEffects() { local ShockBeamEffect E; Super.SpawnEffects(); E = Spawn(class'ExtraBlueBeam'); if ( E != None ) E.AimAt(mSpawnVecA, HitNormal); } Y%*class BlueBeacon extends TransBeacon; Y%r]=- /a9 ]98w]]a10 GY%Uclass BioRiflePickup extends UTWeaponPickup; static function StaticPrecache(LevelInfo L) { L.AddPrecacheMaterial(Texture'XEffects.xbiosplat2'); L.AddPrecacheMaterial(Texture'XEffects.xbiosplat'); L.AddPrecacheMaterial(Texture'XGameShaders.bio_flash'); L.AddPrecacheMaterial(Texture'WeaponSkins.BioGoo.BRInnerGoo'); L.AddPrecacheMaterial(Texture'WeaponSkins.BioGoo.BRInnerBubbles'); L.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.BioRiflePickup'); } simulated function UpdatePrecacheMaterials() { Level.AddPrecacheMaterial(Texture'XEffects.xbiosplat2'); Level.AddPrecacheMaterial(Texture'XEffects.xbiosplat'); Level.AddPrecacheMaterial(Texture'XGameShaders.bio_flash'); Level.AddPrecacheMaterial(Texture'WeaponSkins.BioGoo.BRInnerGoo'); Level.AddPrecacheMaterial(Texture'WeaponSkins.BioGoo.BRInnerBubbles'); super.UpdatePrecacheMaterials(); } Y%P!class BioRifle extends Weapon config(user); #EXEC OBJ LOAD FILE=InterfaceContent.utx function DropFrom(vector StartLocation) { if ( bCanThrow && (AmmoAmount(0) == 0) ) AddAmmo(1,0); Super.DropFrom(StartLocation); } // AI Interface function float GetAIRating() { local Bot B; local float EnemyDist; local vector EnemyDir; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( B.Enemy == None ) { if ( (B.Target != None) && VSize(B.Target.Location - B.Pawn.Location) > 3500 ) return 0.2; return AIRating; } // if retreating, favor this weapon EnemyDir = B.Enemy.Location - Instigator.Location; EnemyDist = VSize(EnemyDir); if ( EnemyDist > 1500 ) return 0.1; if ( B.IsRetreating() ) return (AIRating + 0.4); if ( (B.Enemy.Weapon != None) && B.Enemy.Weapon.bMeleeWeapon ) return (AIRating + 0.35); if ( -1 * EnemyDir.Z > EnemyDist ) return AIRating + 0.1; if ( EnemyDist > 1000 ) return 0.35; return AIRating; } /* BestMode() choose between regular or alt-fire */ function byte BestMode() { if ( FRand() < 0.8 ) return 0; return 1; } function float SuggestAttackStyle() { local Bot B; local float EnemyDist; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 0.4; EnemyDist = VSize(B.Enemy.Location - Instigator.Location); if ( EnemyDist > 1500 ) return 1.0; if ( EnemyDist > 1000 ) return 0.4; return -0.4; } function float SuggestDefenseStyle() { local Bot B; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 0; if ( VSize(B.Enemy.Location - Instigator.Location) < 1600 ) return -0.6; return 0; } // End AI Interface simulated function AnimEnd(int Channel) { local name anim; local float frame, rate; GetAnimParams(0, anim, frame, rate); if (anim == 'AltFire') LoopAnim('Hold', 1.0, 0.1); else Super.AnimEnd(Channel); } simulated function bool HasAmmo() { return ( (AmmoAmount(0) >= 1) || FireMode[1].bIsFiring ); } Y%\$Y%Y%]$Y%Y%^$Y%Y%Y%Y%V`$vHbGY%V[e5 `(X*A6X*6S aZ \ X*A(VwS *(|-][FAq!u' GY%Pclass BioGlob extends Projectile; var xEmitter Trail; var() int BaseDamage; var() float GloblingSpeed; var() float RestTime; var() float TouchDetonationDelay; // gives player a split second to jump to gain extra momentum from blast var() float DripTime; var() int MaxGoopLevel; var int GoopLevel; var float GoopVolume; var Vector SurfaceNormal; var int Rand3; var bool bCheckedSurface; var() bool bMergeGlobs; var bool bDrip; var bool bOnMover; var() Sound ExplodeSound; var AvoidMarker Fear; replication { reliable if (bNetInitial && Role == ROLE_Authority) Rand3; } simulated function PostBeginPlay() { Super.PostBeginPlay(); SetOwner(None); LoopAnim('flying', 1.0); if (Role == ROLE_Authority) { Velocity = Vector(Rotation) * Speed; Velocity.Z += TossZ; } if (Role == ROLE_Authority) Rand3 = Rand(3); if ( (Level.NetMode != NM_DedicatedServer) && ((Level.DetailMode == DM_Low) || Level.bDropDetail) ) { bDynamicLight = false; LightType = LT_None; } } function AdjustSpeed() { if ( GoopLevel < 1 ) Velocity = Vector(Rotation) * Speed; else Velocity = Vector(Rotation) * Speed * (0.4 + GoopLevel)/(1.4*GoopLevel); Velocity.Z += TossZ; } simulated function PostNetBeginPlay() { if (Role < ROLE_Authority && Physics == PHYS_None) { Landed(Vector(Rotation)); } } simulated function Destroyed() { if ( !bNoFX && EffectIsRelevant(Location,false) ) { Spawn(class'xEffects.GoopSmoke'); Spawn(class'xEffects.GoopSparks'); } if ( Fear != None ) Fear.Destroy(); if (Trail != None) Trail.Destroy(); Super.Destroyed(); } simulated function MergeWithGlob(int AdditionalGoopLevel) { } auto state Flying { simulated function Landed( Vector HitNormal ) { local Rotator NewRot; local int CoreGoopLevel; if ( Level.NetMode != NM_DedicatedServer ) { PlaySound(ImpactSound, SLOT_Misc); // explosion effects } SurfaceNormal = HitNormal; // spawn globlings CoreGoopLevel = Rand3 + MaxGoopLevel - 3; if (GoopLevel > CoreGoopLevel) { if (Role == ROLE_Authority) SplashGlobs(GoopLevel - CoreGoopLevel); SetGoopLevel(CoreGoopLevel); } spawn(class'BioDecal',,,, rotator(-HitNormal)); bCollideWorld = false; SetCollisionSize(GoopVolume*10.0, GoopVolume*10.0); bProjTarget = true; NewRot = Rotator(HitNormal); NewRot.Roll += 32768; SetRotation(NewRot); SetPhysics(PHYS_None); bCheckedsurface = false; Fear = Spawn(class'AvoidMarker'); GotoState('OnGround'); } simulated function HitWall( Vector HitNormal, Actor Wall ) { Landed(HitNormal); if ( !Wall.bStatic && !Wall.bWorldGeometry ) { bOnMover = true; SetBase(Wall); if (Base == None) BlowUp(Location); } } simulated function ProcessTouch(Actor Other, Vector HitLocation) { local BioGlob Glob; Glob = BioGlob(Other); if ( Glob != None ) { if (Glob.Owner == None || (Glob.Owner != Owner && Glob.Owner != self)) { if (bMergeGlobs) { Glob.MergeWithGlob(GoopLevel); // balancing on the brink of infinite recursion bNoFX = true; Destroy(); } else { BlowUp( HitLocation ); } } } else if (Other != Instigator && (Other.IsA('Pawn') || Other.IsA('DestroyableObjective') || Other.bProjTarget)) BlowUp( HitLocation ); else if ( Other != Instigator && Other.bBlockActors ) HitWall( Normal(HitLocation-Location), Other ); } } state OnGround { simulated function BeginState() { PlayAnim('hit'); SetTimer(RestTime, false); } simulated function Timer() { if (bDrip) { bDrip = false; SetCollisionSize(default.CollisionHeight, default.CollisionRadius); Velocity = PhysicsVolume.Gravity * 0.2; SetPhysics(PHYS_Falling); bCollideWorld = true; bCheckedsurface = false; bProjTarget = false; LoopAnim('flying', 1.0); GotoState('Flying'); } else { BlowUp(Location); } } simulated function ProcessTouch(Actor Other, Vector HitLocation) { if ( Other.IsA('Pawn') && (Other != Base) ) { bDrip = false; SetTimer(TouchDetonationDelay, false); } } function TakeDamage( int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Momentum, class DamageType ) { if (DamageType.default.bDetonatesGoop) { bDrip = false; SetTimer(0.1, false); } } simulated function AnimEnd(int Channel) { local float DotProduct; if (!bCheckedSurface) { DotProduct = SurfaceNormal dot Vect(0,0,-1); if (DotProduct > 0.7) { PlayAnim('Drip', 0.66); bDrip = true; SetTimer(DripTime, false); if (bOnMover) BlowUp(Location); } else if (DotProduct > -0.5) { PlayAnim('Slide', 1.0); if (bOnMover) BlowUp(Location); } bCheckedSurface = true; } } simulated function MergeWithGlob(int AdditionalGoopLevel) { local int NewGoopLevel, ExtraSplash; NewGoopLevel = AdditionalGoopLevel + GoopLevel; if (NewGoopLevel > MaxGoopLevel) { Rand3 = (Rand3 + 1) % 3; ExtraSplash = Rand3; if (Role == ROLE_Authority) SplashGlobs(NewGoopLevel - MaxGoopLevel + ExtraSplash); NewGoopLevel = MaxGoopLevel - ExtraSplash; } SetGoopLevel(NewGoopLevel); SetCollisionSize(GoopVolume*10.0, GoopVolume*10.0); PlaySound(ImpactSound, SLOT_Misc); PlayAnim('hit'); bCheckedSurface = false; SetTimer(RestTime, false); } } function BlowUp(Vector HitLocation) { if (Role == ROLE_Authority) { Damage = BaseDamage + Damage * GoopLevel; DamageRadius = DamageRadius * GoopVolume; MomentumTransfer = MomentumTransfer * GoopVolume; if (Physics == PHYS_Flying) MomentumTransfer *= 0.5; DelayedHurtRadius(Damage, DamageRadius, MyDamageType, MomentumTransfer, HitLocation); } PlaySound(ExplodeSound, SLOT_Misc); Destroy(); //GotoState('shriveling'); } singular function SplashGlobs(int NumGloblings) { local int g; local BioGlob NewGlob; local Vector VNorm; for (g=0; g 0 ) { Super.ModeHoldFire(); GotoState('Hold'); } } function float MaxRange() { return 1500; } simulated function bool AllowFire() { return (Weapon.AmmoAmount(ThisModeNum) > 0 || GoopLoad > 0); } simulated function PlayStartHold() { Weapon.PlayAnim('AltFire', 1.0 / (GoopUpRate*MaxGoopLoad), 0.1); } simulated function PlayFiring() { Super.PlayFiring(); Weapon.OutOfAmmo(); } state Hold { simulated function BeginState() { GoopLoad = 0; SetTimer(GoopUpRate, true); Weapon.PlayOwnedSound(sound'WeaponSounds.Biorifle_charge',SLOT_Interact,TransientSoundVolume); Weapon.ClientPlayForceFeedback( "BioRiflePowerUp" ); // jdf Timer(); } simulated function Timer() { if ( Weapon.AmmoAmount(ThisModeNum) > 0 ) GoopLoad++; Weapon.ConsumeAmmo(ThisModeNum, 1); if (GoopLoad == MaxGoopLoad || Weapon.AmmoAmount(ThisModeNum) == 0) { SetTimer(0.0, false); Instigator.AmbientSound = sound'NewWeaponSounds.BioGoopLoop'; Instigator.SoundRadius = 50; Instigator.SoundVolume = 50; } } simulated function EndState() { if ( (Instigator != None) && (Instigator.AmbientSound == sound'NewWeaponSounds.BioGoopLoop') ) Instigator.AmbientSound = None; Instigator.SoundRadius = Instigator.Default.SoundRadius; Instigator.SoundVolume = Instigator.Default.SoundVolume; StopForceFeedback( "BioRiflePowerUp" ); // jdf } } function projectile SpawnProjectile(Vector Start, Rotator Dir) { local BioGlob Glob; GotoState(''); if (GoopLoad == 0) return None; Glob = Weapon.Spawn(class'BioGlob',,, Start, Dir); if ( Glob != None ) { Glob.Damage *= DamageAtten; Glob.SetGoopLevel(GoopLoad); Glob.AdjustSpeed(); } GoopLoad = 0; if ( Weapon.AmmoAmount(ThisModeNum) <= 0 ) Weapon.OutOfAmmo(); return Glob; } function StartBerserk() { if ( (Level.GRI != None) && (Level.GRI.WeaponBerserk > 1.0) ) return; GoopUpRate = default.GoopUpRate*0.75; } function StopBerserk() { if ( (Level.GRI != None) && (Level.GRI.WeaponBerserk > 1.0) ) return; GoopUpRate = default.GoopUpRate; } function StartSuperBerserk() { GoopUpRate = default.GoopUpRate/Level.GRI.WeaponBerserk; } Y%S Y%Y%[ class BioAttachment extends xWeaponAttachment; var xEmitter MuzFlash3rd; simulated function Destroyed() { if (MuzFlash3rd != None) MuzFlash3rd.Destroy(); Super.Destroyed(); } simulated event ThirdPersonEffects() { local Rotator R; if ( Level.NetMode != NM_DedicatedServer && FlashCount > 0 ) { if (MuzFlash3rd == None) { MuzFlash3rd = Spawn(class'XEffects.BioMuzFlash1st'); MuzFlash3rd.bHidden = false; AttachToBone(MuzFlash3rd, 'tip'); } if (MuzFlash3rd != None) { R.Roll = Rand(65536); SetBoneRotation('Bone_Flash', R, 0, 1.0); MuzFlash3rd.mStartParticles++; } } Super.ThirdPersonEffects(); } Y%Eclass BioAmmoPickup extends UTAmmoPickup; #exec OBJ LOAD FILE=PickupSounds.uax simulated function PostBeginPlay() { local actor HitActor; local vector HitLocation, HitNormal; Super.PostBeginPlay(); // check to see if imbedded (stupid LD) HitActor = Trace(HitLocation, HitNormal, Location - CollisionHeight * vect(0,0,1), Location + CollisionHeight * vect(0,0,1), false); if ( (HitActor != None) && HitActor.bWorldGeometry ) SetLocation(HitLocation + vect(0,0,1) * CollisionHeight); } Y%Rclass BioAmmo extends Ammunition; #EXEC OBJ LOAD FILE=InterfaceContent.utx Y%hclass BallTarget extends WeaponFire; var() float AimCone; var() float MaxDist; simulated function bool AllowFire() { return true; } function DoFireEffect() { local UnrealPawn p; local Pawn bestP; local float bestWt; local vector toPawn; local vector eyeDir; local float cosdot; local float curwt; local float curdist; local float curdot; if ( (Instigator.Role < ROLE_Authority) || (Instigator.PlayerReplicationInfo == None) || (Instigator.PlayerReplicationInfo.Team == None) ) return; bestP = None; cosdot = cos(AimCone*PI/180); eyeDir = Vector(Instigator.Controller.Rotation); bestWt = 0.0; foreach Instigator.VisibleActors(class'UnrealPawn', p, MaxDist ) { if ( (p == Instigator) || (p.PlayerReplicationInfo == None) || (P.PlayerReplicationInfo.Team != Instigator.PlayerReplicationInfo.Team) ) continue; toPawn = p.Location - Instigator.Location; curdot = Normal(toPawn) dot eyeDir; curdist = VSize(toPawn); if( curdot < cosdot ) continue; if( curdist > MaxDist ) continue; curwt = 1.0 - (curDist / MaxDist); curwt *= curdot; if( curwt > bestWt ) { bestWt = curwt; bestP = p; } } BallLauncher(Weapon).SetPassTarget(bestP); } Y%cclass BallShoot extends ProjectileFire; simulated function bool AllowFire() { return true; } function ModeDoFire() { local xBombFlag Bomb; local Translauncher T; Bomb = xBombFlag( Instigator.PlayerReplicationInfo.HasFlag ); if ( Bomb.bBallDrainsTransloc ) { T = Translauncher(Instigator.FindInventoryType(class'Translauncher')); if ( T != None ) T.DrainCharges(); } Super.ModeDoFire(); // make sure to switch to a new weapon if (PlayerController(Instigator.Controller) != None && Instigator.IsLocallyControlled() && (Instigator.PendingWeapon == Weapon || Instigator.PendingWeapon == None)) { PlayerController(Instigator.Controller).ClientSwitchToBestWeapon(); } } function DoFireEffect() { local xBombFlag Bomb; if (Weapon.Role != ROLE_Authority) return; if( Instigator.PlayerReplicationInfo.HasFlag == None ) return; Bomb = xBombFlag( Instigator.PlayerReplicationInfo.HasFlag ); if ( Bomb == None ) return; BallLauncher(Weapon).launchedBall = true; Super.DoFireEffect(); } function projectile SpawnProjectile(Vector Start, Rotator Dir) { local xBombFlag bomb; local vector ThrowDir; Bomb = xBombFlag ( Weapon.Instigator.Controller.PlayerReplicationInfo.HasFlag ); Bomb.PassTarget = BallLauncher(Weapon).PassTarget; ThrowDir = Bomb.ThrowSpeed * vector(Dir); bomb.Throw(Start, ThrowDir); BallLauncher(Weapon).PassTarget = None; return None; } Y%b{class BallLauncher extends Weapon config(user) HideDropDown CacheExempt; #EXEC OBJ LOAD FILE=InterfaceContent.utx var() transient bool launchedBall; var() transient Pawn PassTarget; var() Sound PassAmbient; var() Sound PassTargetLocked; var() Sound PassTargetLost; var() String PassTargetLockedForce; var() String PassTargetLostForce; var() float HealRate; var transient float HealAccum; var transient float SwitchTestTime; var Actor AITarget; // used by AI #exec OBJ LOAD File=IndoorAmbience.uax replication { reliable if ( Role == ROLE_Authority ) PassTarget; } simulated function OutOfAmmo() { } function SynchronizeWeapon(Weapon ClientWeapon) { if ( Instigator.PlayerReplicationInfo.HasFlag == None ) return; if ( Instigator.Controller != None ) Instigator.Controller.ClientSetWeapon(class); } simulated function DrawWeaponInfo(Canvas Canvas) { NewDrawWeaponInfo(Canvas, 0); } simulated function NewDrawWeaponInfo(Canvas Canvas, float YPos) { local xPlayer PC; PC = xPlayer(Instigator.Controller); if ( PC == None ) return; if( PassTarget != None ) PC.myHUD.SetTargeting( true, PassTarget.Location, 1.0 ); PC.myHUD.DrawTargeting(Canvas); PC.myHUD.SetTargeting(false); } simulated function BringUp(optional Weapon PrevWeapon) { Super.BringUp(); if (Instigator.IsLocallyControlled() && !PrevWeapon.IsA('BallLauncher')) Instigator.PendingWeapon = PrevWeapon; // prevent shooting ball until button is released FireMode[0].bIsFiring = true; FireMode[0].bNowWaiting = true; } simulated function Weapon NextWeapon(Weapon CurrentChoice, Weapon CurrentWeapon) { if ( CurrentWeapon == self ) return Instigator.PendingWeapon; else return Super.NextWeapon(CurrentChoice,CurrentWeapon); } simulated function Weapon PrevWeapon(Weapon CurrentChoice, Weapon CurrentWeapon) { if ( CurrentWeapon == self ) return Instigator.PendingWeapon; else return Super.PrevWeapon(CurrentChoice,CurrentWeapon); } simulated function bool PutDown() { if ( launchedBall || Instigator.PlayerReplicationInfo.HasFlag == None ) { launchedBall = false; return Super.PutDown(); } if ( Instigator.PendingWeapon == self ) Instigator.PendingWeapon = None; return( false ); // Never let them put the weapon away. } function SetPassTarget( Pawn passTarg ) { if ( (PassTarget != None) && (PassTarget != PassTarg) && (PlayerController(PassTarget.Controller) != None) ) PlayerController(PassTarget.Controller).ClientPlaySound(PassTargetLost); PassTarget = passTarg; if ( PassTarget == None ) Level.Game.GameReplicationInfo.FlagTarget = None; else Level.Game.GameReplicationInfo.FlagTarget = PassTarget.PlayerReplicationInfo; if ( PlayerController(Instigator.Controller) != None ) { if ( passTarg != None ) PlayerController(Instigator.Controller).ClientPlaySound(PassTargetLocked); else PlayerController(Instigator.Controller).ClientPlaySound(PassTargetLost); } if ( (PassTarget != None) && (PlayerController(PassTarget.Controller) != None) ) PlayerController(PassTarget.Controller).ClientPlaySound(PassTargetLocked); } function ModifyPawn( float dt ) { if ( Instigator.Weapon == self && Instigator.PlayerReplicationInfo.HasFlag != None) { if ( Instigator.Health < Instigator.HealthMax ) { HealAccum += HealRate * dt; if( HealAccum > 1 ) { Instigator.Health = Min(Instigator.HealthMax, Instigator.Health + HealAccum); HealAccum -= int(HealAccum); } } } if ( Instigator.Weapon != self && Instigator.PlayerReplicationInfo.HasFlag != None) { xBombFlag(Instigator.PlayerReplicationInfo.HasFlag).SetHolder( Instigator.Controller ); } } simulated function Tick(float dt) { if ( (Level.NetMode == NM_Client) || Instigator == None || Instigator.PlayerReplicationInfo == None) return; if ( Instigator.PlayerReplicationInfo.HasFlag == None ) { if ( Level.TimeSeconds - SwitchTestTime > 0.8 ) { if ( (Instigator.Weapon == self) && ((Instigator.PendingWeapon == None) || (Instigator.PendingWeapon == self)) ) Instigator.Controller.ClientSwitchToBestWeapon(); SwitchTestTime = Level.TimeSeconds; } if ( Instigator.AmbientSound == PassAmbient ) AmbientSound = None; return; } // safeguard - to be absoulutly certain the ball launcher is up when player has the ball and not up otherwise if (Level.TimeSeconds - SwitchTestTime > 0.5) { if ( (Instigator.Weapon != self) && (Instigator.PendingWeapon != self) ) { if ( PassTarget != None ) SetPassTarget(None); Instigator.Controller.ClientSetWeapon(class'BallLauncher'); } else if ( (PassTarget != None) && ((Passtarget.Controller == None) || (VSize(PassTarget.Location - Instigator.Location) > 6000)) ) SetPassTarget(None); SwitchTestTime = Level.TimeSeconds; } ModifyPawn(dt); } // todo: disallow switching away from this while this weapon is coming is up!! simulated function bool StartFire( int modeNum ) { local bool bResult; bResult = Super.StartFire(modeNum); if ( bResult ) { if ( modeNum == 0 ) { launchedBall = true; ClientPlayForceFeedback(PassTargetLockedForce); } else ClientPlayForceFeedback(PassTargetLostForce); } return bResult; } simulated function bool HasAmmo() { if ( xBombFlag(Instigator.PlayerReplicationInfo.HasFlag) != None ) return true; return( false ); // Never let them change to this weapon for fun. } simulated function Weapon RecommendWeapon( out float rating ) { local Weapon Recommended; local float oldRating; if ( xBombFlag(Instigator.PlayerReplicationInfo.HasFlag) != None ) { rating = 10000000; return self; } if ( inventory != None ) { Recommended = inventory.RecommendWeapon(oldRating); if ( Recommended != None ) { rating = oldRating; return Recommended; } } // Never return the ball launcher if no bomb! return None; } function bool CanAttack(Actor Other) { return true; } function SetAITarget(Actor T) { AITarget = T; } function bool BotFire(bool bFinished, optional name FiringMode) { local xBombFlag Bomb; local vector ShootLoc; local Bot B; Bomb = xBombFlag( Instigator.PlayerReplicationInfo.HasFlag ); B = Bot(Instigator.Controller); if ( !B.bPlannedShot || (Bomb == None) || (AITarget == None) ) { B.bPlannedShot = false; return false; } // find correct initial velocity ShootLoc = AITarget.Location; Bomb.PassTarget = None; if ( Pawn(AITarget) != None ) { ShootLoc = ShootLoc + 0.5 * (VSize(ShootLoc - Bomb.Location)/Bomb.ThrowSpeed) * Pawn(AITarget).Velocity; Bomb.PassTarget = Pawn(AITarget); } else if ( (GameObjective(AITarget) == None) && (AITarget.Location.Z <= Bomb.Location.Z) ) ShootLoc = ShootLoc - AITarget.CollisionHeight * vect(0,0,1); return ShootHoop(B,ShootLoc); } function bool ShootHoop(Controller B, Vector ShootLoc) { local xBombFlag Bomb; Bomb = xBombFlag( Instigator.PlayerReplicationInfo.HasFlag ); // shoot hoop FireMode[0].PlayFiring(); FireMode[0].FlashMuzzleFlash(); FireMode[0].StartMuzzleSmoke(); IncrementFlashCount(0); launchedBall = true; Bomb.Throw(Instigator.Location, B.AdjustToss(Bomb.ThrowSpeed, Bomb.Location, ShootLoc,true) ); //fixme experiment with bNormalize==false if ( Bot(B) != None ) Bot(B).bPlannedShot = false; AITarget = None; return true; } Y%Hu$uC r3*3a  F3 aAHCw*w*w*3 9=3ka?@h ra?|]9?qA>el{a?h ]9?qA>el{aL>]9?qA33>el{aL>]9?qAff&?el{aL>]9?qA33S?el{aL>]9?qA?el{q!v @Y%G Y%HdR GY%{%B[A/G #{FG HC GY%m$B@eQ C*aK*^*F#@FF(s)F6s)6K*6BaJ s)wB*BHF#?w*t)#? t)#?t)?66FC*aK*^*s)t)F(rC**BaJ s)t)wB*BHF#?C*aK*^*s)t)F(rC**BaJ s)t)wB*BHF#? GY%Dclass BallAttachment extends xWeaponAttachment; function InitFor(Inventory I) { Super.InitFor(I); } simulated event ThirdPersonEffects() { Super.ThirdPersonEffects(); } Y%n$N|=N:wN*V.N#wV*wV*wV*n{V #nA@nAs?sA@nAN2|gsikss{@NN GY%'class BallAmmo extends Ammunition; Y%o//============================================================================= // AssaultRiflePickup. //============================================================================= class AssaultRiflePickup extends UTWeaponPickup; Y%Vz//============================================================================= // Assault Rifle //============================================================================= class AssaultRifle extends Weapon config(user); var float DualPickupTime; var AssaultAttachment OffhandActor; var bool bDualMode; var bool bWasDualMode; var bool bFireLeft; #EXEC OBJ LOAD FILE=InterfaceContent.utx #EXEC OBJ LOAD FILE=UT2004Weapons.utx replication { reliable if ( Role == ROLE_Authority ) bDualMode; } simulated function Loaded() { bDualMode = true; } simulated function PostNetBeginPlay() { Super.PostNetBeginPlay(); if ( (Role < ROLE_Authority) && (Instigator != None) && (Instigator.Controller != None) && (Instigator.Weapon != self) && (Instigator.PendingWeapon != self) ) Instigator.Controller.ClientSwitchToBestWeapon(); } simulated function bool WeaponCentered() { return !bDualMode && Super.WeaponCentered(); } simulated event RenderOverlays( Canvas Canvas ) { local bool bRealHidden; local int RealHand; if (Instigator == None) return; if ( Instigator.Controller != None ) Hand = Instigator.Controller.Handedness; if ((Hand < -1.0) || (Hand > 1.0)) return; RealHand = Hand; if ( bDualMode && (Hand == 0) ) { Instigator.Controller.Handedness = -1; Hand = -1; } if ( bDualMode && (FireMode[1].FlashEmitter != None) ) { bRealHidden = FireMode[1].FlashEmitter.bHidden; if ( bFireLeft ) FireMode[1].FlashEmitter.bHidden = true; Super.RenderOverlays(Canvas); FireMode[1].FlashEmitter.bHidden = bRealHidden; } else Super.RenderOverlays(Canvas); if ( bDualMode ) RenderDualOverlay(Canvas); if ( Instigator.Controller != None ) Instigator.Controller.Handedness = RealHand; } simulated function RenderDualOverlay(Canvas Canvas) { local vector NewScale3D; local rotator WeaponRotation; local bool bRealHidden; Hand *= -1; newScale3D = Default.DrawScale3D; newScale3D.Y *= Hand; SetDrawScale3D(newScale3D); PlayerViewPivot.Roll = Default.PlayerViewPivot.Roll * Hand; PlayerViewPivot.Yaw = Default.PlayerViewPivot.Yaw * Hand; RenderedHand = Hand; if ( class'PlayerController'.Default.bSmallWeapons ) PlayerViewOffset = SmallViewOffset; else PlayerViewOffset = Default.PlayerViewOffset; PlayerViewOffset.Y *= Hand; SetLocation( Instigator.Location + Instigator.CalcDrawOffset(self) ); WeaponRotation = Instigator.GetViewRotation(); if ( bDualMode != bWasDualMode ) { bWasDualMode = true; DualPickupTime = Level.Timeseconds; } if ( DualPickupTime > Level.TimeSeconds - 0.5 ) WeaponRotation.Pitch = WeaponRotation.Pitch - 16384 - 32768 * (DualPickupTime - Level.TimeSeconds); SetRotation( WeaponRotation ); bDrawingFirstPerson = true; if ( bDualMode && (FireMode[1].FlashEmitter != None) ) { bRealHidden = FireMode[1].FlashEmitter.bHidden; if ( !bFireLeft ) FireMode[1].FlashEmitter.bHidden = true; Canvas.DrawActor(self, false, false, DisplayFOV); FireMode[1].FlashEmitter.bHidden = bRealHidden; } else Canvas.DrawActor(self, false, false, DisplayFOV); bDrawingFirstPerson = false; Hand *= -1; } simulated function DetachFromPawn(Pawn P) { bFireLeft = false; AssaultGrenade(FireMode[1]).ReturnToIdle(); Super.DetachFromPawn(P); if ( OffhandActor != None ) { OffhandActor.Destroy(); OffhandActor = None; } } function AttachToPawn(Pawn P) { local name BoneName; if ( ThirdPersonActor == None ) { ThirdPersonActor = Spawn(AttachmentClass,Owner); InventoryAttachment(ThirdPersonActor).InitFor(self); } BoneName = P.GetWeaponBoneFor(self); if ( BoneName == '' ) { ThirdPersonActor.SetLocation(P.Location); ThirdPersonActor.SetBase(P); } else P.AttachToBone(ThirdPersonActor,BoneName); if ( bDualMode ) { BoneName = P.GetOffHandBoneFor(self); if ( BoneName == '' ) return; if ( OffhandActor == None ) { OffhandActor = AssaultAttachment(Spawn(AttachmentClass,Owner)); OffhandActor.InitFor(self); } P.AttachToBone(OffhandActor,BoneName); if ( OffhandActor.AttachmentBone == '' ) OffhandActor.Destroy(); else { ThirdPersonActor.SetDrawScale(0.3); OffhandActor.SetDrawScale(0.3); OffhandActor.bDualGun = true; OffhandActor.TwinGun = AssaultAttachment(ThirdPersonActor); if ( Mesh == OldMesh ) { OffhandActor.SetRelativeRotation(rot(0,32768,0)); OffhandActor.SetRelativeLocation(vect(20,-10,-5)); } else { OffhandActor.SetRelativeRotation(rot(0,0,32768)); OffhandActor.SetRelativeLocation(vect(40,-3,-7)); } AssaultAttachment(ThirdPersonActor).TwinGun = OffhandActor; } } } simulated function DrawWeaponInfo(Canvas Canvas) { NewDrawWeaponInfo(Canvas, 0.705*Canvas.ClipY); } simulated function NewDrawWeaponInfo(Canvas Canvas, float YPos) { local int i,Count; local float ScaleFactor; ScaleFactor = 99 * Canvas.ClipX/3200; Canvas.Style = ERenderStyle.STY_Alpha; Canvas.DrawColor = class'HUD'.Default.WhiteColor; Count = Min(8,AmmoAmount(1)); for( i=0; i 8 ) { Count = Min(16,AmmoAmount(1)); for( i=8; i= FireMode[1].AmmoPerFire) ) return 1; } if ( AmmoAmount(0) >= FireMode[0].AmmoPerFire ) return 0; return 1; } simulated function float ChargeBar() { return FMin(1,FireMode[1].HoldTime/AssaultGrenade(FireMode[1]).mHoldClampMax); } function bool HandlePickupQuery( pickup Item ) { if ( class == Item.InventoryType ) { if ( bDualMode ) return super.HandlePickupQuery(Item); bDualMode = true; if ( Instigator.Weapon == self ) { PlayOwnedSound(SelectSound, SLOT_Interact,,,,, false); AttachToPawn(Instigator); } if (Level.GRI.WeaponBerserk > 1.0) CheckSuperBerserk(); else FireMode[0].FireRate = FireMode[0].Default.FireRate * 0.55; FireMode[0].Spread = FireMode[0].Default.Spread * 1.5; if (xPawn(Instigator) != None && xPawn(Instigator).bBerserk) StartBerserk(); return false; } if ( item.inventorytype == AmmoClass[1] ) { if ( (AmmoCharge[1] >= MaxAmmo(1)) && (AmmoCharge[0] >= MaxAmmo(0)) ) return true; item.AnnouncePickup(Pawn(Owner)); AddAmmo(50, 0); AddAmmo(Ammo(item).AmmoAmount, 1); item.SetRespawn(); return true; } if ( Inventory == None ) return false; return Inventory.HandlePickupQuery(Item); } simulated function int MaxAmmo(int mode) { if ( bDualMode ) return 2 * FireMode[mode].AmmoClass.Default.MaxAmmo; else return FireMode[mode].AmmoClass.Default.MaxAmmo; } function float GetAIRating() { local Bot B; if ( !bDualMode ) return AIRating; B = Bot(Instigator.Controller); if ( B == None ) return AIRating; if ( B.Enemy == None ) { if ( (B.Target != None) && VSize(B.Target.Location - B.Pawn.Location) > 8000 ) return 0.78; return AIRating; } return (AIRating + 0.0003 * FClamp(1500 - VSize(B.Enemy.Location - Instigator.Location),0,1000)); } Y%x`class AssaultGrenade extends ProjectileFire; #exec OBJ LOAD FILE=..\Sounds\NewWeaponSounds.uax const mNumGrenades = 8; var float mCurrentRoll; var float mBlend; var float mRollInc; var float mNextRoll; var float mDrumRotationsPerSec; var float mRollPerSec; var AssaultRifle mGun; var int mCurrentSlot; var int mNextEmptySlot; var() float mScale; var() float mScaleMultiplier; var() float mSpeedMin; var() float mSpeedMax; var() float mHoldSpeedMin; var() float mHoldSpeedMax; var() float mHoldSpeedGainPerSec; var() float mHoldClampMax; var float ClickTime; var() float mWaitTime; function PostBeginPlay() { Super.PostBeginPlay(); mRollInc = -1.f * 65536.f / mNumGrenades; mRollPerSec = 65536.f * mDrumRotationsPerSec; mGun = AssaultRifle(Weapon); mHoldClampMax = (mHoldSpeedMax - mHoldSpeedMin) / mHoldSpeedGainPerSec; FireRate = mWaitTime + 1.f / (mDrumRotationsPerSec * mNumGrenades); } function DrawMuzzleFlash(Canvas Canvas) {} simulated function bool AllowFire() { if (Super.AllowFire()) return true; else { if ( (PlayerController(Instigator.Controller) != None) && (Level.TimeSeconds > ClickTime) ) { Instigator.PlaySound(Sound'NewWeaponSounds.newclickgrenade'); ClickTime = Level.TimeSeconds + 0.25; } return false; } } function InitEffects() { Super.InitEffects(); if ( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'tip2'); } function DoFireEffect() { local Vector StartProj, StartTrace, X,Y,Z; local Rotator Aim; local Vector HitLocation, HitNormal; local Actor Other; Instigator.MakeNoise(1.0); Weapon.GetViewAxes(X,Y,Z); StartTrace = Instigator.Location + Instigator.EyePosition();// + X*Instigator.CollisionRadius; StartProj = StartTrace + X*ProjSpawnOffset.X; if ( AssaultRifle(Weapon).bDualMode ) { AssaultRifle(Weapon).bFireLeft = !AssaultRifle(Weapon).bFireLeft; if ( AssaultRifle(Weapon).bFireLeft ) Y *= -1; } if ( !Weapon.WeaponCentered() ) StartProj = StartProj + Weapon.Hand * Y*ProjSpawnOffset.Y + Z*ProjSpawnOffset.Z; // 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); SpawnProjectile(StartProj, Aim); } function projectile SpawnProjectile(Vector Start, Rotator Dir) { local Grenade g; local vector X, Y, Z; local float pawnSpeed; g = Weapon.Spawn(class'Grenade', instigator,, Start, Dir); if (g != None) { Weapon.GetViewAxes(X,Y,Z); pawnSpeed = X dot Instigator.Velocity; if ( Bot(Instigator.Controller) != None ) g.Speed = mHoldSpeedMax; else g.Speed = mHoldSpeedMin + HoldTime*mHoldSpeedGainPerSec; g.Speed = FClamp(g.Speed, mHoldSpeedMin, mHoldSpeedMax); g.Speed = pawnSpeed + g.Speed; g.Velocity = g.Speed * Vector(Dir); g.Damage *= DamageAtten; } return g; } simulated function ReturnToIdle() { UpdateRoll(FireRate); GotoState('Idle'); } // Client-side only: update the first person drum rotation simulated function bool UpdateRoll(float dt) { local rotator r; local bool bDone; local float diff; local float inc; diff = mCurrentRoll - mNextRoll; inc = dt*mRollPerSec; if (inc >= diff) { inc = diff; bDone = true; } mCurrentRoll -= inc; mCurrentRoll = mCurrentRoll % 65536.f; r.Roll = int(mCurrentRoll); mGun.SetBoneRotation('Bone_Drum', r, 0, mBlend); return bDone; } simulated function int WrapPostIncr(out int count) { local int oldcount; oldcount = count; if (++count >= mNumGrenades) count = 0; return oldcount; } function PlayPreFire() {} function PlayStartHold() {} function PlayFiring() {} function PlayFireEnd() {} auto state Idle { function StopFiring() { local rotator r; if (Instigator.Weapon != Weapon) return; r.Roll = Rand(65536); Weapon.SetBoneRotation('Bone_Flash02', r, 0, 1.f); mNextRoll = mCurrentRoll + mRollInc; mGun.PlayAnim(FireAnim, FireAnimRate, 0.0); if ( (Level.NetMode != NM_Client) && (Instigator.DrivenVehicle == None) ) Weapon.PlaySound(FireSound,SLOT_Interact,TransientSoundVolume,,512.0,,false); ClientPlayForceFeedback(FireForce); // jdf GotoState('Wait'); Super.StopFiring(); } } state Wait { function BeginState() { SetTimer(mWaitTime, false); } function Timer() { GotoState('LoadNext'); //goto idle if out of ammo? } } state LoadNext { function BeginState() { if (Level.NetMode != NM_Client) Weapon.PlaySound(ReloadSound,SLOT_None,,,512.0,,false); ClientPlayForceFeedback(ReloadForce); } function ModeTick(float dt) { if ( Weapon.Mesh != Weapon.OldMesh ) GotoState('Idle'); else if (UpdateRoll(dt)) GotoState('Idle'); } } function StartBerserk() { mHoldSpeedGainPerSec = default.mHoldSpeedGainPerSec * 1.5; mHoldClampMax = (mHoldSpeedMax - mHoldSpeedMin) / mHoldSpeedGainPerSec; } function StopBerserk() { mHoldSpeedGainPerSec = default.mHoldSpeedGainPerSec; mHoldClampMax = (mHoldSpeedMax - mHoldSpeedMin) / mHoldSpeedGainPerSec; } function StartSuperBerserk() { mHoldSpeedGainPerSec = default.mHoldSpeedGainPerSec * Level.GRI.WeaponBerserk; mHoldClampMax = (mHoldSpeedMax - mHoldSpeedMin) / mHoldSpeedGainPerSec; FireRate = mWaitTime + 1.f / (mDrumRotationsPerSec * mNumGrenades) / Level.GRI.WeaponBerserk; } Y%,HX>w*w.R*PUw3*3a GY%k$w$`( GY%Y%Y%Qclass AssaultFire extends InstantFire; var float LastFireTime; var float ClickTime; function InitEffects() { Super.InitEffects(); if ( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'tip'); } function FlashMuzzleFlash() { local rotator r; r.Roll = Rand(65536); Weapon.SetBoneRotation('Bone_Flash', r, 0, 1.f); Super.FlashMuzzleFlash(); } event ModeDoFire() { if ( Level.TimeSeconds - LastFireTime > 0.5 ) Spread = Default.Spread; else Spread = FMin(Spread+0.02,0.12); LastFireTime = Level.TimeSeconds; Super.ModeDoFire(); } simulated function bool AllowFire() { if (Super.AllowFire()) return true; else { if ( (PlayerController(Instigator.Controller) != None) && (Level.TimeSeconds > ClickTime) ) { Instigator.PlaySound(Sound'WeaponSounds.P1Reload5'); ClickTime = Level.TimeSeconds + 0.25; } return false; } } function StartBerserk() { DamageMin = default.DamageMin * 1.33; DamageMax = default.DamageMax * 1.33; } function StopBerserk() { DamageMin = default.DamageMin; DamageMax = default.DamageMax; } function StartSuperBerserk() { FireRate = default.FireRate * 1.5/Level.GRI.WeaponBerserk; FireAnimRate = default.FireAnimRate * 0.667 * Level.GRI.WeaponBerserk; DamageMin = default.DamageMin * 1.5; DamageMax = default.DamageMax * 1.5; if (AssaultRifle(Weapon) != None && AssaultRifle(Weapon).bDualMode) FireRate *= 0.55; } Y%_8class AssaultAttachment extends xWeaponAttachment; var byte OldSpawnHitCount; var class mMuzFlashClass; var xEmitter mMuzFlash3rd; var xEmitter mMuzFlash3rdAlt; var bool bDualGun; var AssaultAttachment TwinGun; var float AimAlpha; replication { reliable if ( Role == ROLE_Authority ) bDualGun, TwinGun; } simulated function Hide(bool NewbHidden) { bHidden = NewbHidden; if ( TwinGun != None ) TwinGun.bHidden = bHidden; } simulated function Destroyed() { if ( bDualGun ) { if ( Instigator != None ) { Instigator.SetBoneDirection(AttachmentBone, Rotation,, 0, 0); Instigator.SetBoneDirection('lfarm', Rotation,, 0, 0); } } if (mMuzFlash3rd != None) mMuzFlash3rd.Destroy(); if (mMuzFlash3rdAlt != None) mMuzFlash3rdAlt.Destroy(); Super.Destroyed(); } simulated function SetOverlayMaterial( Material mat, float time, bool bOverride ) { Super.SetOverlayMaterial(mat, time, bOverride); if ( !bDualGun && (TwinGun != None) ) TwinGun.SetOverlayMaterial(mat, time, bOverride); } simulated function Tick(float deltatime) { local rotator newRot; if ( !bDualGun || (Level.NetMode == NM_DedicatedServer) ) { Disable('Tick'); return; } AimAlpha = AimAlpha * ( 1 - 2*DeltaTime); // point in firing direction if ( Instigator != None ) { newRot = Instigator.Rotation; if ( AimAlpha < 0.5 ) newRot.Yaw += 4500 * (1 - 2*AimAlpha); Instigator.SetBoneDirection('lfarm', newRot,, 1.0, 1); newRot.Roll += 32768; Instigator.SetBoneDirection(AttachmentBone, newRot,, 1.0, 1); } } /* UpdateHit - used to update properties so hit effect can be spawn client side */ function UpdateHit(Actor HitActor, vector HitLocation, vector HitNormal) { SpawnHitCount++; mHitLocation = HitLocation; mHitActor = HitActor; mHitNormal = HitNormal; } simulated function MakeMuzzleFlash() { local rotator r; AimAlpha = 1; if ( TwinGun != None ) TwinGun.AimAlpha = 1; if (mMuzFlash3rd == None) { mMuzFlash3rd = Spawn(mMuzFlashClass); AttachToBone(mMuzFlash3rd, 'tip'); } mMuzFlash3rd.mStartParticles++; r.Roll = Rand(65536); SetBoneRotation('Bone_Flash', r, 0, 1.f); } simulated event ThirdPersonEffects() { local rotator r; local PlayerController PC; if ( Level.NetMode != NM_DedicatedServer ) { AimAlpha = 1; if ( TwinGun != None ) TwinGun.AimAlpha = 1; if (FiringMode == 0) { WeaponLight(); if ( OldSpawnHitCount != SpawnHitCount ) { OldSpawnHitCount = SpawnHitCount; GetHitInfo(); PC = Level.GetLocalPlayerController(); if ( ((Instigator != None) && (Instigator.Controller == PC)) || (VSize(PC.ViewTarget.Location - mHitLocation) < 4000) ) { Spawn(class'HitEffect'.static.GetHitEffect(mHitActor, mHitLocation, mHitNormal),,, mHitLocation, Rotator(mHitNormal)); CheckForSplash(); } } MakeMuzzleFlash(); if ( !bDualGun && (TwinGun != None) ) TwinGun.MakeMuzzleFlash(); } else if (FiringMode == 1 && FlashCount > 0) { WeaponLight(); if (mMuzFlash3rdAlt == None) { mMuzFlash3rdAlt = Spawn(mMuzFlashClass); AttachToBone(mMuzFlash3rdAlt, 'tip2'); } mMuzFlash3rdAlt.mStartParticles++; r.Roll = Rand(65536); SetBoneRotation('Bone_Flash02', r, 0, 1.f); } } Super.ThirdPersonEffects(); } Y%Q yD :Q Q 9?y,zC%&aL>( GY%2class AssaultAmmoPickup extends UTAmmoPickup; Y%z$%% GY%|$`Ih"pHB9?`,zC GY%RC<  &  GY%Y%Y%D%Y%Y%V@%g Q-$@%G-$<@%%-R'vGp-$ GY%$Y%Y%J%Y%Y%X%Y%Y%Y%Y%O%Y%Y%S%Y%Y%Y%Y%N%Y%Y%L%Y%Y%cM%gnM%%K%&K%%_K%-%K%(M% GY% @T%A4, ' GY%K%Y%Y%Y%Y%n!I%}"k~T& +rI%J%(U&!aY&W& I%(hrU&*'a T&( GY%Y%Y% WP%9_xL%O%N%  M6L%6N% GY%T&Y%Y% aV%~#Sr* Pw* `  GY%Y%Y%Z%J. - L%%k&%Z% GY%g%Y%Y%Y%Y%Y%Y%_%Y%Y%^%Y%Y%d%Y%Y%Y%Y%c%Y%Y%e%Y%Y%f%Y%Y%j%Y%Y%Y%Y%Y%Y%Y% Y%k%Y% Y%U#`%Ovda _%`%a _%`%a  _%9P1a _%19?,`% GY%O-Y%Y%y%Y%Y%t%h%R"h%j% GY%l%Y%Y%PS GY%o%Y%Y%vu%Jl' GY%n%Y%Y%gi%J%i% GY%r%s%w ' GY%m%|-b%OjWa ^%b%a ^%b%a  ^%9P1a ^%b% GY%Y%Y%_P \%i Bb?\%  qw.*xg%f%e%\%\%g%6 o c|\%\%f%6 o ce%6 o cd%<\%c%9P99d%D\%c% GY%l$|%`V' GY%Y%Y%~%Y%Y%%Y%Y%Y%Y%|w $[c!Z GY%@&Z,#. $ ( GY%z%}%i}b?}%  q%<}%~%9P99%D}%~% GY%\8>;L%% $ ̌?( G] I&e&dE&)v] Z]~AH&Y%pJ&c2H&p<7l!Y%Y%iclass ZoomSuperShockBeamFire extends SuperShockBeamFire config; var config bool bAllowMultiHit; function bool AllowMultiHit() { return bAllowMultiHit; } Y%Fclass ZoomSuperShockBeamDamage extends DamTypeSuperShockBeam; Y%]'@Y%Y%Y%Y%Q&Y%Y%Z&Y%Y%S&Y%Y%a Y%Y%Y&Y%Y%Y%Y%Y%Y%U&Y%Y%Y%Y%W&Y%Y%O&Y%Y%AX& :tX&79:9:$b? GY%U%P&r1!a P&['9:Q&9:$O&Q& Q& a O&'P&Q& a Q& 'O&P&#??a O&'O&P&#??a O&'O&P&#?a O&'O&P&#a O&'( GY%Y%Y%@Y%Y%@b&|( GY%Y%Y%m(d&|3X- 9?& GY%Y%Y%V`&}S<r.*(.- GY%Y%Y%_&^&f&| -^& GY%Y%Y%m&Y%Y%i&Y%Y%j&Y%Y%~&Y%Y%Y%Y%n&Y%Y%k&Y%q&r&D@o&nBh̊3}@@@mLSJ"n"J $?J ?H:@@@F: B B AM$AMAC]s SEhb$@@YY^Y%Y%\-t&\=Ly/u"|xh&i&j&W -~& b~&9?%-6~&9?, 6~&9?,}'@@-6~&9?,   M6~&h&ծ6~&}'i&6~&j&v #?99  B GY%w class NewLightningBolt extends xEmitter; simulated function PostBeginPlay() { Super.PostBeginPlay(); MakeNoise(0.5); PlaySound(Sound'WeaponSounds.LightningGun.LightningGunImpact', SLOT_Misc,,,,,false); } simulated function PostNetBeginPlay() { local xWeaponAttachment Attachment; local vector X,Y,Z; if ( (xPawn(Instigator) != None) && !Instigator.IsFirstPerson() ) { Attachment = xPawn(Instigator).WeaponAttachment; if ( (Attachment != None) && (Level.TimeSeconds - Attachment.LastRenderTime < 0.1) ) { GetAxes(Attachment.Rotation,X,Y,Z); SetLocation(Attachment.Location -40*X -10*Z); } } } Y%s&g&`Mw.*ug&.wg&*&g&=g& m&n&k&a g& 9?,(m&9?, k& GY%W b?a $ ( GY%h&Y%Y%@   %%"&&%((&++(--+--,7?.JsZppp ) KcXظ. s_pU{,  VZzgܾ "`^a*@ %Acbe.`k׬L'tƩJ.*U| jjer(/`eV_Ìs%XW#| BXp: UbJ UbZ5/"  5=$%PpT W 5wp\7p^] zPt```AcUUR+^ABUWa BUUaB UעJUcRUMUΈkU [fk^WJJ*aRտAOk`p{,AccW|![~UUsRAac /!| +/a )- )-) X`(\C~ⵧ o୆`aV~^asV!|U / ƈՀeU *U}* -"7*兀a/ccGRU!c1_Z1UR1*Uk9 *U|R*U c (.UƯs *8 UUUUUUUU_|`@p~?_`1蠪WsU [UARUsRUZ*3Uﴔ//U_Uz*__Bc`l_R9xB$!~^)e)+9$! c155ZU^rrMk----Y--- ) UUUUUUUUUUUUUUUU~xxp~Yxxxx{x|X^{ [xxxZBx^R9_UR9 +-sR -s=54r5u---]-- UUUU]xp`~xx@v1xxhx{ZxxxhMk9\___e)xxAAU1URE){(BMk----z---- UUUUUUUUUUUUUUUU]xX\`xxxrx|~Q{\^VsRhhxIJe)xx\1!UB +-- cIJ-1Z/{----~UUUU@@]8hxxxxxxxQZj|IJ9xxhx1xAD)AյU5D)A%9%--- cB----ns----z----y ++)UUUUUUUU~x~uxu1xxxxs|x||sRxxxx(B xxxx9//--RB/mkR -ns-/--4---- UUUU@]xxxx{zpz`{Rxrx~iJ9\|xxB~~xa_A?1U9 ---+ cB----s----Y----]9Ɗ/UUUU=Xz9$) IJ1 --ZIJZ5---׽Q )--]8 -=炫U]zbxxzxxxsxxx{Z||z~ZBxxB%!xe)!_E)!*9E))IJ1-++ZIJ-) {,c--= --85+/Y~]z׽hz~4xz^4r~^Ӕ{~~_{ cz~MkZ~UZ9^IJe)pp~_$!?e) +IJe)--=5 cR{ c----vQ----ַ -- xzxxx|rsxxxxMkZZIJx`x(J9^Zxx1E)|1D)U.Ae)+iJB5-- cR-s c=rs-- /-8Ʒ -yƪgƖpxxuxx{~mkx~^MkZXzZZIJz^IJe)z1!z~!說$!/?(BD)5ZB -%{ c//--uR----yη----y`xx^xxxzrsxz^^MkZZB_IJ1_9D)_1$!"Be) +R9+ c(B MkIJUR ,c U9ƲU/U4mkW1ZUsHJ_ c(BUR9_BD)_e) hz_!$!//1 Z1//{R++U4 c {ypUW4,cWRW cIJWIJBXPpP9e1x1E)^^e)$! 9E)B1-/--IJB %-RIJUUZIJ{Z---{ +Ҝp_psx^sZ~_ cIJ__RBHJB_[V_B1xzz1D)xx`E)^~~x!!E)%=-Be)--RB/MkR //,c U/MkU/ c_UMkR~_ZIJRIJ_WUUMkIJ_,c(JU_^R9UIJ1UZ9 Z(BկMkRUMkR{ZU*Tmkյ U- 4U8{W~xP c_^^MkRWMkRU cIJWZBWR9W~HJE)U9!U9!UHJe)U ZAսsIJ P cUU mkUUkUuMkUsZ_jMkZU(sZUmk$!UU c$!UUR!UURUUR!UU cD)UU,cE)UUmke1UU1*UU1UU9UU9UUq1UUe)UUMke)UUMke)UU,ce)UUZE)UURE)UUHJE)UUBe)UUBe)UUR1*UUZ1UUs1UUp1UU1UU1UUmk1UU,c1UU,c1UUmke)UUIJ1U"IJ1UBe)UBE)U9E)U9e1U 9191 B1U_91-B9*+/B9_B1W9e1WB1U*Be)ՀB1UB1U9e1W9e)U(9f1(B1UB1UB1WB1UB1UB1U B1uB1B1B9_ IJ1U(B9jjBe)91]9E)1E)9e)Z9E)"9191B1B9?/B9B9B1XB9B1 B9__~9e) ZZ1$!zz1$!9e1%B9B9B9zB9 B1ZB9B1hZZh91 B9B1* B9R9A$!kjHJE)}몀HJe) IJ1U׾(R9](iRE)ZBUB1VIJ9 RB]B1|(Be) (Je)XX\R9ZBUʃIJ9}<HJ1W(R!_RD)} c9,cBUZ9 ZBU׶Z9**LkBW^x c9 c9_ c9Uտ* c(BU~hRBUZBUUsRR9~ c(BkʀR1 RB cIJ}ZB**}Z1WB1R9-%-RBBe)\ܞ(B9(Je)XX^_Be)!ZA}IJ1$.&'RB:>,c(JZZXV cBzsR%u--sBpXLk9ZB,c(J?7sIJxV]sZyMkZjMkIJ%/sZxhZZBMkZ} s(BWRe)(>,c9_IJE)UB!"UB}9ue)U9*/BU(B u9(Be)!Wt~D)1!BE)/U(B (UHJU(B!WUR! UZ!p~_U9UBB!*UhJE)URe)}R$) +HJ$!(Z1__HJe)Mk9 -RE)WV1..1x! aAm}D)Au E)AUW aU<D)Aկ1U}€D)A*1ժ1U] 11UUE)WUzpaU1Uս+9__e1>$)A~$!AD)AE)UU.e1_1 }}BUU1׼1IJUU R!+ZBz蠀iJe)׾iJE)~Buߪ1-/ 1zz`D)A 5Be)m9׾B1]0#Be)U+ B$!@@B1}B$!*`Bh`p15A$!~1׾ Be)B1 BpBWw: }yBb1+ -%B$!_^ܰB$!cb`9 <R!W+Z{b9- cR_ cZZ cIJ~ꪨRB~IJBU\B$!B! BD)װjBe)4(B1(B9VV(HJB(B1@HJBU(J$!@0HJ (B0B!`0(B9՞(B9*&HJBUh(B(B1(B$`((J(J1-,7R1Z> ZB~@,c 7. cR cR"#Mk cUUMkZMk c cZ蠠ZRXXP`RIJW^^IJ9h IJE)j(B `IJ1&(J9"IJB_"IJ9`IJ17) (B IJ!(IJ@ IJ pIJe1iJ1IJB^#(B@`T(B%%(B(J<$HJE)P )J ce) ,cA MkZ cB`0 cIJ Mk cꪪMk c몪Mk cMk cW__~ cRzZIJꪠRIJuRIJURBiJIJIJB IJ1(B!(" IJ1`(Bb8iJE)R9몪IJD)$@IJ9(Bx(BxWB5(B (B6_Re)+)ZB  cB Mk cMk cꪪMk cMk cMk cMk cMk cMk cMkZꪪ cZ_ cZU cZU cZUjZ9jiJ$)8 IJ9IJ9,IJE)ްIJ1IJ1b(BIJ1 R9h"IJ11 (Brr(BaBW ((B iJe): ZIJ+ cZ-+ Mk cMk cMk cMk cMk cMk cMk cMk cMk cMk cMk cMk cMk cꪪMkZ cRV^~RIJRIJWRIJUURBzIJ9IJ9IJ1IJ^IJ!IJB<IJD)`IJ1ݠIJ1jR1+ ZHJ+ MkZMk cMk cMk cMk cMk cMk c*Mk cMk csMkUUs csMkUU_ns,cs,cUׯ {MkUU { c{ZU{RU{RUsRUsRUsRUsRUmkbzxXaVYe) /mk!- sRUsRUsRU{RUZտ-cU{MkU{MkU{MkU{MkUMk0nsU {mkUsMkUWzӜMk U{U{UR{Ur{z^nkUU,cUZUZUZURUrRU1IJUQ!X(BaUW(BbUU Q!% RiRURiRURiJUrRUiJURUrIJUrZUrZUrZUrZUrRU1iJU{BUb@@s.( |yI U|社@שּׂ] UUU*Uz_秭Cߧ]b߃Z쵆k@dRzZU#|&&% |`q +nvx㵠@΁k*z!`BU![Uegk U'sW{xJ_k:UJ ߦs /O-z\ ^j^­{W%cUfs +-U ^b{|xx^iRxxD)AWIJ*/1(B/(+-U----UUUUUUUUY``xxx^^mk1xxIJ$!*1R+-{///-~ zXxpp5 cxxxIJ!xxxhA1=5=#r(J----u---]`׽hxz^sxxxxnsD)xxxx17555MkIJ-5nk----~`pxvZxxxjiJE)xxxx!r(9 -/ IJ----YӜ -Ơz_8rz^s~WMk9xhxz9!55R9+ 8 c---Y ~4xxxZxxxZ1xx1$!W(iJe1-/sR----׵ --9xxs~^sR^^iJE)x~^E)/Ze) --5,c---- `xxx1 cxxxxZ1z~~1E) VWIJ1 MkIJ UUZ+ƐUU׵Lk~_WiJ~WUZ9~__B!x^_^!>R$!-IJ+LkUֽZ_U|iR_UU c$!UHJ!UR$!*Umke1U1 U}(BU1UMkE)UZe)UHJE)~U9$!UR1 +Us1 Uq1Umk1Us1 UiJ1^B1_W91 U9f1!A1%B9B9WnB9UB1~9E)91+ B9B9UkB9bkB9(J9W+,ce)_Z1՟8 R9 Z9{iJ9՟=iJ1prIJ1jcbzR9 iJ9 )ZD)mk1 cB],cB}ˋMk(B}†ms(BUkBU/mk!W^Z UW9aU1aU1AտBU9ue) /9_^9uIJU1տ9UiJ URUw,c!/կZ9ZR$!^ꨀB}(B B! (B1K IJ9kjB\B!^(B1+ (B ^ B$!ug.iJ!}+ZE)_( ce1uk cBMk c_zzz cIJ^~R9nRe)xIJ1 IJ1bIJxIJE) iJ9IJ`zB HJ!% c9_*MkIJ)MkR/ Mk cMk cꪪMk cU_MkZU cIJzhR9R9IJ9iIJE)" bIJ1 IJ!IJ! ,cA+ Mk cMk cMk c*Mk cMkUrMkUW1MkUrMkUUrbUWRZU1ZU_{^V\RZUrZUrbrmkURmkUrsUU1 c_@@r@ Ec~k?:50ƀ*&baP!סk "GU&]E!WW#ߨ1+``*KJ~~9 / {``xx(B\\x{ -///4 -5x^Ӝ9xxxz c-s --kxxxxRe)\\\^mk1--y,c 9Z~W,c$)xz_R %5YΪR Y cxx^Ub1__WZ9 UU9 UU9WUURe)_iJ15{A UUsBUUU,c$!WIJUIJuR$!.>WUR cULk$! U,c$!" c1~蠀iJIJ1(B$)z$HJe)+JrBD)W,ce)u c9QZ{R{IJUU{!z`{$) {9ս*Z{MkUU @ƥ1.ή#׊1cC,c7>},c}1$)W,cck}iJ$)(^Q!UR$) ULke){9W~Mk1}@s9UW{9ҿ@3B lAmk9UWnk9 (B#U(BZY/ӵ(B[VEY%Y%W(@}a(Y%z&Y%wY%s' Y%Y%A'Y%Y%& Y%wY%}'Y%Y%Y%Y%y'dY%Y%Y%k'Y%Y%Y%Y%Z(Y%Y%Y%W)A,N@F'_J!Yi-j-k-l-m-n-o-p-\ $E~ SX!SvSY%Y%K'Y%Y%Y%Y%C'Y%Y%E'Y%Y%Y%Y%Q+Y%Y%Y%Y%Y%Y%h(Y%Y%Y%Y%Y%Y%p'Y%Y%Y%Y%{(Y%Y%S'@Y%Y%Y%Y%Y'@Y%R)Y%Y%Y%N'Y%Y%Y%Y%Y%Y%Y%Y%L'Y%Y%z'Y%Y%}& Y%Y%Y%Y%b'Y%Y%Y%Y%o(Y%Y%|'Y%Y%h'Y%Y%q'Y%Y%t(Y%Y%y&Y%Y%C(Y%Y%W'Y%Y%o'Y%Y%H'Y%Y%Y%Y%Q'Y%Y%Y%Y%v'Y%Y%dY%Y%Y%D(Y%Y%E(Y%Y%Y%Y%f'Y%Y%YW O( GY%'N(vB(C?%%&&6 9CB(N( G Y%['Y%Y%Y%Y%{'Y%Y%M(Y%Y%Y%Y%g'Y%Y%a'Y%Y%@(\(v ew*$&    @(\( G Y%Y%Y%O)@Y%])V2K(uhC\"L"K"dz%Z$#"P""R!"~ "}Y%] BulletsY%Y%O+Y%Y%I(Y%Y%B(Y%Y%Y%Y%Q(_Y%_Y%@'dY%T'Y%Y%n(Y%Y%@Y%Y%Y%Y%l)@Y%Y%U(@Y%Y%[Y%Y%V'Y%Y%wY%Y%Y%Y%_(Vl GY%d-_'WfrF_'_'_'_' G!Y%Y%R(Y%pz~u!CL(a)a)N-N''{w.*.`@ GY%Y%Y% L,e(Y  W( GY%@Y%Y%d(R'Z"- m R'm-y+w.R'* .R't!L'%L'7x&w6@'L'x&*G(.R'h6@'L'x&rG(*a'6@'L'x&G(r %a'>L'tmR'--a'}?U?R'=rR'*R'?@a'a' GY% Cc(C  m GY%G(Y%Y%Y%Y%Ji(Is ̾ GY%d'Y%Y%f(j'Of*- m j'Q'%Q'7x&x'.j'h6@'Q'x&rx'*v'6@'Q'x&x'r %v'>Q'&.j'R2j'?h'9?L>h'v'h' GY%@(k(\'VZPu"|d'!56d'9?,6d' GY%O'Y%Y%x'Y%Y% `T(`2"O'.&rO'* ]w[*O'~'[ ?O' E T(O'~( GY%\'Y%Y%L-q(\&-z&\'.;r\'*r\'*w\'*<\' \' 9?@G?RI9D\'  zD GY%l(Z'CRZ'%IZ'7x&6@'Z'x& vZ' GY%Y%Y%s(|(~&G Y%w(D' GY%x(Y%Y%Y%Y%v(X'vcr.X'*.X'-2r.X'*r.X'*(b$X' (' GY% cl'arl'--z& l'-z&'fr$ (q?z!%% ?%%?w.*.-Q(rl'&U&L&%L%'l'u.k,2%k.l'&l'F'r*( al' GY%Y%Y%y(G'i^vG'w..G'**w...G'*wl)*l)-l) N!A9:9:$ s .G' @ .G'E'%E'7x&6@'E'x&K'..G'h6@'E'x&GwK'*K'a!\.G'K'.Q.G'wK'*K'[.G'6y'E'x&%K'k6y'E'x&%E'u.G' GY% gD'`W'BD'9? D'$D' p',L&V'%V'p'D'5D'?9?V'9?&W'Z(D'&a W'W'.CC8B4BV'jL&,p',L&V',V'p'D'@D'?9?V',9?&W'Z(W'D'&a W'W'.CC8B4BV' GY%fI'q 23r*a.XC'I']C'!Y%a I' a*I'I'C'/-z&C'I'BC'!Y% ry&*y&.way&XI'y&C'By&!Y%y&a/ >y& >y&-c''y&}&.wry& "y& #A y& "y& # B@.w}&y& GY%@)~'tU^9?f' 6f'f'69D9?669D9?6 -6a   Mb' }!-z&-s'-s''m'm'?6b'9D9?6b'@9?m'a+b'-'1-z&w&*-z'&--H'&-'~' a((&--z'E~' a((-(9? GY%H)i'v.A r* >w*` ? E(9D-z& 9?%C-z&w&*-|'&--H'&-'i'&--|'Ni'b-z&ti'w*9?E( G Y%oy6[j"`&99V99>9?`33?9?`6 GY%Y%Y%~^<?*?09D9?0?O9D9?O?w.m*.m-z& ? GY%K^$809D9?0?O9D9?O?F F *??9?P F TGF  GY%`F)q' GY%Y%Y%rcB'iGRb?xq'o'C(k'  qB'k'q'6c.m-z&.m-H'.m-H'.m-H'o'9?.|B'B'o'6cC(6cI(aD(M(B'k'(kwI(*B'D({'<B'(B'{' GY%hB)|&-z& GY% m'S9 -z&' GY%U`w*w*w*|%& &&  GY%|w'hX&?*w}&*}&&?SrK*Kao K!5K6w'!Ww'%? GY%Q,S(C4/-c'9:9:$v!C &&9?&9?,S(w*T' &?6T'9D9?9?&9?,&!|T' ?&6T'T' ?& GY%@Y%Y%S)J(L^ 5&zJ(ArenaWeaponClassNameU(J( G(Y%H^2xvv`GEvK ?b 9?, GY%@Y%Y%^!A(JNA( c&['S'%S'7['K{Y'aBY';aBY'pp6S'[';6S'['S'#A(4bArenaWeaponClassNameX($$SelectY' G Y%l^}/ 'VV GY%@|class WeaponLocker extends Pickup; #exec OBJ LOAD FILE=..\staticmeshes\industrial_static struct WeaponEntry { var() class WeaponClass; var() int ExtraAmmo; }; var() bool bSentinelProtected; var() array Weapons; var localized string LockerString; var FX_WeaponLocker Effect; struct PawnToucher { var Pawn P; var float NextTouchTime; }; var array Customers; function bool AddCustomer(Pawn P) { local int i; local PawnToucher PT; if ( Customers.Length > 0 ) for ( i=0; i 0 ) for ( i=0; i P; local int i; local float Interval; if ( (Level.NetMode == NM_DedicatedServer) || (Level.DetailMode == DM_Low) ) return; L = spawn(class'LockerWeapon'); Interval = 65536.0/Weapons.Length; for ( i=0; i<8; i++ ) { if ( i >= Weapons.Length ) L.Emitters[i].Disabled = true; else { P = class(Weapons[i].WeaponClass.Default.PickupClass); if ( (P == None) || (P.Default.StaticMesh == None) ) L.Emitters[i].Disabled = true; else { MeshEmitter(L.Emitters[i]).StaticMesh = P.Default.StaticMesh; L.Emitters[i].StartLocationOffset = P.default.LockerOffset * vector(WeaponDir); WeaponDir.Yaw += Interval; MeshEmitter(L.Emitters[i]).StartSpinRange.X.Min = P.Default.Standup.X; MeshEmitter(L.Emitters[i]).StartSpinRange.X.Max = P.Default.Standup.X; MeshEmitter(L.Emitters[i]).StartSpinRange.Y.Min = P.Default.Standup.Y; MeshEmitter(L.Emitters[i]).StartSpinRange.Y.Max = P.Default.Standup.Y; MeshEmitter(L.Emitters[i]).StartSpinRange.Z.Min = P.Default.Standup.Z; MeshEmitter(L.Emitters[i]).StartSpinRange.Z.Max = P.Default.Standup.Z; MeshEmitter(L.Emitters[i]).StartSizeRange.X.Min = 0.9 * P.default.DrawScale; MeshEmitter(L.Emitters[i]).StartSizeRange.X.Max = 0.9 * P.default.DrawScale; MeshEmitter(L.Emitters[i]).StartSizeRange.Y.Min = 0.9 * P.default.DrawScale; MeshEmitter(L.Emitters[i]).StartSizeRange.Y.Max = 0.9 * P.default.DrawScale; MeshEmitter(L.Emitters[i]).StartSizeRange.Z.Min = 0.9 * P.default.DrawScale; MeshEmitter(L.Emitters[i]).StartSizeRange.Z.Max = 0.9 * P.default.DrawScale; } } } } simulated function String GetHumanReadableName() { return LockerString; } // tell the bot how much it wants this weapon pickup // called when the bot is trying to decide which inventory pickup to go after next function float BotDesireability(Pawn Bot) { local Weapon AlreadyHas; local float desire; local int i; if ( bHidden || HasCustomer(Bot) ) return 0; if ( bSentinelProtected && (Bot(Bot.Controller) != None) && !Bot(Bot.Controller).NeedWeapon() ) return 0; // see if bot already has a weapon of this type for ( i=0; i 0.5) || (PathWeight > 400)) ) return 0.2/PathWeight; return desire/PathWeight; } simulated function UpdatePrecacheMaterials() { local int i; for ( i=0; i 0 ) Copy.AddAmmo(Weapons[i].ExtraAmmo, 0); } } } AnnouncePickup( Pawn(Other) ); } } } State Disabled { simulated function BeginState() { local LockerWeapon W; Super.BeginState(); ForEach DynamicActors(class'LockerWeapon', W) W.Destroy(); if ( Effect != None ) Effect.Destroy(); } } U)R,}2|V)|R߾#F'_z)>6nhh uz)>6nz)>6nhqYԊ3}ZsqYԈqYԄhhhʁ)qYԖ#hqYԈqYԄh _hqYԄhh|hqYԈqYԄh,ehqYԄhhqYԊ3}3}F'_W=qYԖPvF'_W=F'_O>|PvF'_W=PvF'_O>|PvF'_O>|PvF'_O>|PvF'_O>|PvF'_O>|PvF'_O>|PvF'_O>|PvF'_O>|PvF'_O>|PvF'_O>|PvF'_O>|PvF'_O>|Pvu)u)3}u)u)z)>6nqYԊ3}3}3}3}3}M]Weapon Locker]#"You loaded up at a weapon locker.  nx $?$?[ :???o:BX$BA$HBb:/k:/eY%Y%Sclass LockerWeapon extends Emitter placeable; simulated function Reset(); Y%Iu/ GY%R ^A GY%f ^N GY%g!^aaaU U FF GY%X"^'r@PV9:9:$b #?a b lr*a b!ur*|r*a  a  \9?,<99 ^'.w^'*$^'9?&a ^' Xa  J A9:9:$b GY%Vclass AssaultAmmo extends Ammunition; #EXEC OBJ LOAD FILE=InterfaceContent.utx Y%\)_)pc gDw*w.*a+ }Ua+9PJJ GY%Y%Y%s-Y%Y%NNY%u*Y%Y%b)Y%Y%s*Y%F'Y%R(@Y%K,Y%Y%Y%Y%Y%Y%Y%T Y%Y%`*Y%Y%h*Y%Y%e)Y%z)Y%Y%Y%)Y%Y%Y%Y%sY%Y%y)Y%Y%UY%Y%t)Y%Y%Y%Y%qY%Y%BY%Y%Y%Y%Y%Y%Y%e-D,j!@z)>6nJ!Yg-h-\ $E~ SY%Y%z*Y%Y%Y%Y%WY%Y%Y%Y%j+Y%Y%Y%Y%_*Y%Y%x)Y%Y%K*Y%Y%N*Y%Y%Y%Y%b-Y%Y%Y%Y%Y%Y%Y%Y%a*Y%Y%^*Y%Y%M+Y%Y%e+Y%Y%Y%Y%Y%Y%U,Y%Y%Y%Y%Y%Y% Y% T*Y%4b!k!C"f!Y%FY%Y%Y%Y%Y%Y%Y%Y%H+Y%Y%Y%Y%B,Y%Y%Y%Y%Y%Y%s)Y%Y%S+Y%Y%Y%w*Y%r)Y%Y%Y%Y%Y%Y%h)Y%Y%g*Y%Y%Y%Y%q*Y%Y%n)Y%Y%X-Y%Y%Y%Y%{)Y%Y%k*Y%Y%p*Y%Y%U*Y%Y%Y%Y%Y%Y%Y%Y%vY%Y%c)Y%Y%Y%Y%Y%Y%t*Y%Y%y+D*J"Y%|*Y%Y%Y%T*Y%Y%Y%sY%Y%}*Y%Y%Y%Y%Y%Y%u+Y%Y%S*Y%Y%R-Y%Y%Y%F'Y%V-Y%Y%Y%T*Y%Y%Y%` Y%Y%m+Y%Y%Y%Y%Y%V)Y%Y%Y%Y%Y%f+Y%Y%Y%Y%Y%Y%L*Y%Y%@,Y%Y%P+Y%Y%Y%Y%\+Y%Y%Y%Y%i uY%`Y%Y%G,Y%Y%Y+Y%Y%w,Y%Y%V+Y%Y%r,Y%Y%Z+Y%Y%[+Y%Y%|,Y%Y%U+uY%_+uY%},Y%Y%Y%Y%`+uY%N+Y%Y%c+uY%Y%Y%gY%Y%Y%{f)| /f),wf)*w.f)*wf)*f)S 9:J+.f)@f)`3rf)*f)bf)f)Rf)f)r f)f) GY%a+Y%Y%J+Y%Y%Y%Y%Y%K-}!2n+$bjPv]You got the Translocator.]SniperRiflePickup  $L>Y%Y%F+Y%Y%dB GY%Y%Y%P-Y%Y%Lv GY%v+Y%Y%A+Y%Y%T-Y%Y%W-Y%Y%Y-Y%Y%x&}Y%Y%T*Y%Y%Y%^-Y%Y%Y%Y%zY%R&Y%Y%L(Y%Y% VM GY%j)Y%Y%Y%Y%H,C,x! -( GY%F,W+m 97e)%m)%m)7e)x6N*m)e)br6D*m)e)W+(Ae)m)&m)r6D*m)e)W+'m)( GY%w*[*s  7e)%j)%j)7e)6N*j)e)r6D*j)e)[*6N*j)e)9?,'Ae)j)&j)r6D*j)e)[*(j)6D*`*[*6N*`*9?,7e)e)`*' GY%m)Y%Y%M,L -( GY%E,H*`N- H*%]H*7x&6@'H*x&H*#v 9:9:$l)a z)  GY%Y%Y%Y%w*Y%](d)v v69:9:$9:9:$ d)a F'u*G9?7x&b)%b),b)7x&b)d)-'c)6@'b)x&rc)*rc) *b)d)-'.b)d)c) b)d) c)Q(99s*6s*9Du*66.b)d)6c) P(66.b)d)6c) P(66.b)d)6c) P(66.b)d)6c) P(66.b)d)6c) P(66.b)d)6c) P(66.b)d)fff?c)66.b)d)fff?c)66.b)d)fff?c)66.b)d)fff?c)66.b)d)fff?c)66.b)d)fff?c)b)` GY%J,N! -'aA( GY%n }+~!1--}+.w}&*}&-- GY% Z,e!m!/C @w&*&%& C& GY%Y%Y%}x*k+Px*|*-}*M-c' w}&*}&kx*|*-}* GY%u(S,g 4GY% B+B.p> /a9 F'B+#B+a10;wl)*l)a GY%T*D+N d9:D+9:S* 7-@+ 9?&S*D+a9:9:$^  GY%B*Y%Y% ~$P*ZE B*.P*wB**wB**x).B*wx)*x)sB*S x) x) *P* x) 9?#H"rP* h*9?, P* GY%Y,B6D-'?- - A9:9:$x  GY%Y%Y%X,C v!C GY%^,P,K"i/ GY%[W,D"!G!Y%P(x M-'JH(&M b  a  G Y%Y%Y%`,],S!g. GY%Y%Y% b,_,G"d.( GY%Y%Y% h,a,y!_o.( GY%Y%Y%L0--33? GY%T,^ )Cw*w*. ^ S*w4*S* s$%4  x$ %4  GY%`q 4(w*J+9=S a?' GY%Y%Y% l c,u!Z;.( GY%i+~ GY%g,Y%Y%z h+B"s h+-  G"Y%Y%Y%|E*`.G!9:9:$ E*M ]w*rE* -9:9:$-($rE**rE***E* 9? -($ GY%Q!l,n NQ  GY%m%]+n &]+b [+;E GY%mR+~9@ R+& R+ GY%T+~Q T+& T+ GY%Y%Y% {,Pp GY%^)X+n mu X+b Y+zD GY%Y%Y%u,Y%Y%Y%Y%Iv!,7\ * &\ * &  GY%v,Y%Y%y,Y%Y%H(z,J5' GY%Y%Y%A*Y%Y% H^+T!r*w&!&&&-&&&& ^+ GY%p$d+h +)/a9 N+%N+ d+10 GY%Tb+YCHb+p &&&&&-&&&& GY%B-@!' -{( GY%Q%L+e DA-{-L+-f+-{-L+;-{MA@! GY%R!Y%A{ w.*w.* w.*.&& &  G Y%~Q!  GY%uG-fX L& GY%Y%Y%jI-y @F GY%Y%Y%vI+q \+/a0 V)I+!I+q!g 10 GY%=class TransPickup extends UTWeaponPickup notplaceable; Y%z(C+LaO.-z&,C+LC+ GY%Y%Y%sr+B!0r+ L GY%M-Y%Y%Y%Y%N-t+C!5;<t+v+ GY%Y%Y%A* Gd#-*%-A+'*u+-A+ GY%Y%Y%Q-w+D!:'x+?9?w+ 9?& GY%Y%Y%x+Y%Y%o)Y%Y%Y%Y% y*^ (w&*.& ^ y*9r y* b$% &  $% &  $% &  $% &   GY%tz+^ w, r* z+ 2$%  P$%  n$%  $%   GY%Z-{+v-zlw&*&- w*V %.\ N $l.\ N ${+ G Y%Bf wB*Ba GY%l*Y%Y%f-|+z {)w{)*{)-\ z*,l*.&{) hrl**(k*.l*rk**({)k*r{)|+'z*( GY%S a-y  _ GY%Y%Y%Y%Y%If !909:9:$0wI*Ia GY% I,^ wl)*l)a  GY%~ //============================================================================= // FX_WeaponLocker //============================================================================= // Created by Laurent Delayen // 2003, Epic Games, Inc. All Rights Reserved //============================================================================= class FX_WeaponLocker extends Emitter; #exec OBJ LOAD FILE=..\Textures\AS_FX_TX.UTX #exec OBJ LOAD FILE=..\Textures\AW-2004Particles.UTX function TurnOff(Float T) { bHidden = true; SetTimer(30, false); } function Timer() { bHidden = false; } simulated function NotifyLocalPlayerDead(PlayerController PC) { bHidden = false; } Y% EF*w! ~c/w.F**.F* 9?%'^w.F**.F*9?%'( G| Y V Z So Y1a $*Y%a $?*@Y%a $?*Y%t $+?X "W :AI!ZL DQJK I $ #X "W :AI!ZL DQJK I $ ף;J $J $>Y%Y%T ZL DQJK I $>J $>Y%PJK I $?J $?Y%OJK I $?J $?Y%Y%U $PCGY% Y V Z S] SX "W :A[ ZL DQJK I $J $Y%PJK I $J $Y%OJK I $>J $>Y%Y%T ZL DQJK I $>J $>Y%PJK I $?J $?Y%OJK I $?J $?Y%Y%U $PCGY% Y V Z S] SX "W :A[ ZL DQJK I $J $Y%PJK I $J $Y%OJK I $>J $>Y%Y%T ZL DQJK I $>J $>Y%PJK I $?J $?Y%OJK I $?J $?Y%Y%U $PCGY% Y V Z S] SX "W :A[ ZL DQJK I $J $Y%PJK I $J $Y%OJK I $>J $>Y%Y%T ZL DQJK I $>J $>Y%PJK I $?J $?Y%OJK I $?J $?Y%Y%U $PCGY% Y V Z S] SX "W :A[ ZL DQJK I $J $Y%PJK I $J $Y%OJK I $>J $>Y%Y%T ZL DQJK I $>J $>Y%PJK I $?J $?Y%OJK I $?J $?Y%Y%U $PCGY% Y V Z S] SX "W :A[ ZL DQJK I $J $Y%PJK I $J $Y%OJK I $>J $>Y%Y%T ZL DQJK I $>J $>Y%PJK I $?J $?Y%OJK I $?J $?Y%Y%U $PCGY% Y V Z S] SX "W :A[ ZL DQJK I $J $Y%PJK I $J $Y%OJK I $>J $>Y%Y%T ZL DQJK I $>J $>Y%PJK I $?J $?Y%OJK I $?J $?Y%Y%U $PCGY% Y V Z S] SX "W :A[ ZL DQJK I $J $Y%PJK I $J $Y%OJK I $>J $>Y%Y%T ZL DQJK I $>J $>Y%PJK I $?J $?Y%OJK I $?J $?Y%Y%U $PCGY%Y%r-Y%Y%t-Y%Y%Y%Y%Y%Y%q- q-ar-t-#?#?(wq-*q--a r-#? GY%Y%Y%a&Hv-|&|$-v - 9?& GY%^ Y%Y%jCA1 &  &  GY%Y%ZY%Y%ZY%_z-G ;_z-a }-8wz-*z-H1 GwC.E.Q%@}-/7vJwiRMhY%PD.B.P%@~-HPc!^hY%Y%@.Y%Y%Y%Y%_{-Gz;_{-a ~-8w{-*{-H1 GY%A.GL GY%Sclass ExtraRedBeam extends SuperShockBeamEffect; function SpawnEffects() {} Y%Rclass ExtraBlueBeam extends BlueSuperShockBeam; function SpawnEffects() {} Y%|-GM GY%S-a $9?&D-@. Gppodozo_ozo}o^poaoRFRo@ oBoFonoGBAFno2ooFRp FToio]F^p@oH/oIoyoiFRpVB|oAp` FiF]F^GOGhKnB@oDotokK_GFI|I{FTpEFzo^#FSFo{ouBZpmoKpFIh}}zoaCYpuoAoto}oe#oIH_G}oq#pFolpE oiFdIiFgoGpFHcouomoHoao~pOFTFFGoKw}XCJ!pYoAGlGQpk IgF\GP}tpiuhoo}`pApJpyK pt}Coho~Fc}8Gzoc}rFtGMF^KBKCGeFv}vIwL GIjGSoBGAKao@oPF]}ofpZGfKTomF^IPoTDmGuGXK^uxHI BGBQGF}B}Y}HLIfIguvGIo_omGaFSBn}`FYKZ}goLF_}\Kco@H`}dGI }u}CuwGf}N}}f}u}HiDoF[}CK6pLGJ  C pMGVpBp@}qKWHl}V}vIJorooR}IHgKzpYp~pWFUVpIF-}aHX}fFZp@ }F}ipBpC}Ho`}[}Q}RonoM}UoUotjhFip@$pBpbBSooBQpe K'}JHkFoG}_pDHII;FXGs }Zoj}^}h}bpioC}G}rFr#}o}DF]Bk}Q}~GIG~oL$}G^ or$G["Gp$KooPpN GDB[ BT pP HspdBL#Gu BvOBvPBvQGgiojFapepQ"B~$}X}<oEo]HDFYo\#o[Dr[pHG"ox#GTop}yH]BPu{ ooDp#F}FzEdGF}wHKGPodD}omoZt~HRIP} HxoO#oQ#Keo}D  c}}q BEHknKOuspcGcF{pK#B{BWus"}+oc}c}Bua um FV}hHfuz ud G3G:}zl}UpV~BKd}i}poqFRpS oEGU}cGIHup|pIGh#u2GB}WFk}Ypg|pc"oV oWuoHu/KoqopBBu2N}u/JpI#pJogDG=}JU~Y-CHmGE#HZH[HI oY}{GqGhoYoz~D"p\mF~g }\pa}|okF ooEWp]kukv}wmjfmjkGPuo Y| ur}j}r}\D|uk$FEFk^gm@ }LU\$GH \ u  q Bkj w  r o`}sGTFYGtHD#F_GJGWoCBG!mmpcptop@}`Fg"ocG`KeHGHH t# P$on$Hg HS G  @ DQHm HU#F]" B  v Ga  F ILGE @ uf}^$YxGqopEQ}ue$GJ GauU$uN#oY}`H} doyDkoH%o{Faor}imx mA mF mE HS$oqFv}LIA }J}$uI$}n u~#}kuj$Yz$ua}| uI%ufuhu_ueG_u\T# vu\W#ulosGpuioE$uM$BH}R@}RZp`"uA#ut"uD}RHRMoy"}T!uSF XIDIEIF}u}rpcpX}d}FBupQ}Ju{upOu2Puxu/x"uqGtusug pR#Yt$}Auj uh uc uLui uZ"Yb u[V#u[C#}Z}`I}IPYu Yv }[}YAHX#YEYDFWGVGBuJ$uP"uc$u[#}uy }u@uq Bbuw u,Au,Lu-Nu-Fu,\"u,MuCUEur ufU,J}aY-Hut uBo{}U}XF ovuquplaXpYBlkQk_}VKoR$mbokmdHnk>wmjjIxmvlkNKhGN$oaHh"o_}RkMpT o|mH[HKpI}t}ruUuTu{"uhG%uhT$}auz"u_ u^ u] oZ oW }sooobo]o\ou}^}LoXoJoToUoVoSBooQB[ EioOoNoMoKoWoIoGoAo}o|oZ}e!o^o^o\oZoY}R }u!oz#oX }~o[ o\ oA$o_#KPoLoo}y!orozGcoI}G"}|BoMEVoN}moSoUmEHG#mGmG|oVmH`p~m}pzly}}[}|+kKSmjn}VkCmjmoZHykvLkvRp@k}Mm^mDJobm]ockOH`#odmjeoemjlofk>x}lkPmjipj lemjhmkmpohmKmmDtoimcmjoojoloH$onmnmgmr}FkDmfmam_m`mamDimhkAkBmsopmomcoq}Q}Xmqmjg}SmjkGorosotouG\ owpl oy}Yo`}AozHdY-GUUI}w!H~ }DF}JFSFTHMGUH`|C}|Yp H\H]GIYx Y Y~ }CY} GQ^uO$}Y}Ppo"}Wu~v#p|M}Vpr"}OHy}Z}D}IC}zmS#mp#mu#mx$m]$ml$}IBG@fFb}RIL}d"olob}d}FB,u}q}LB,|}j }Q!}x BjBCBy}B"}{ GU}n }] }q}f }`}b}a}d}`}x!BmbnGwH]DGe"Aa"}a}imC mD m{ m| A-nA-bm} }\ }d mB mz my }+m m~ Hs#D |D[A {o|HGH{$ok"Hi"HHA]!o~"A?FUFY }GoEK}{ Gkw#HO"YB YZUl"Uk#UF#UQ$Ua#UY"Uf$U}"H@  b}k}w}PGU D  {  | }q } }n  E Gk }d z  y }yGt  x FR t  ~  ~#E }v! v" m"BW o_oRHl}|}] GY#B@}~!F+`}U }_ H$f"HvFY$Hz}y}K"GLuW$uy#uK$um$Ub$U}#U|#Y{#pVmWF }b prpsmG{m@#mkmlmj}S!m`$op[eG[[Q[[[a[f[_[Y[d[O[W[c[e[^"[T [][P[L[M[d[`[Z[b[S[X[R[P [V[c[_"p @[9Ic+H+RkR{DRK~ n[NR.IMA&[~ \~nQl~1Rjvz9IKJ WT@kJ{\_K~VjS@TOw_YoTarORAY%oQO }ar^pmi}P yMP eFLkW9zIJy_ZKWyBI[Y[!hjbzAz I^CoSrc:ArpCZlRDed iu\eFeWIhP Dxc|^oLDh \EanT~CM (b^a@G_P SoW@},aNl o^h CMEPqS`jp4i @}QbC"crfTuTEtTKScrrD ]"AeU^\omWT}VMNo^EwM r]` cme_PGbQrDBBRQ%batp%@ _NT]ZDnY%lr!bA+BQWV`DfoA~RNo]Y%rQmT}DLT^vnA@b OA^ tnT}TL s[ajEAyrI3uYNThIsxokY%:v{WKIZdiexWYGM {V!tQ,Aaoq[ A`R@cJg] rKmOKe`AoY%Y%rS]N_R^dRlf{q~ JuZY%rjByqvHqxXDEhYwDDG+DVDeEt+ECBRsTb|srT {B|`}ebNY%Y%h]Y%rYkjzrEJ+rZHjrYyKYHXWRfRteCwRi W`owTFPUTeQu ~E pT Y%Klf 7cu 7bE wU Sd 0 St <{D KS Sc Ws jD cT Xwb S q }@ @R %ba W`q Y%[  SO G^ }n bT} Y%YL dT[ DGk Az jK DF[ vj Y%Fy GH eW Ne [ku +FE dmT lc uTq K@ Y%wTP V_ Yr pC KWR lc Y%+Gs DAB Z R e` Tp w PO ~ ] Y%R l w`{ S K Y%OZ ei Ty eSH hW Tf Pu @AD IjT eLc DCr I^A CP 0 I_ Y%Uo rl  [Fk U bz [j\ Sk q\y +CI NX qeh px BF mU le Xxu [EC !qS Sb Hoq %cA %dP %ea Op Zl@ QTP Y%g` *Yp zH ZG YX hxg ow IpF u pU TE ]DU wY Qj 3Iz 7^J aZ Api X^x &mH BW fg Iv \F XoU Hae STs jC FS Da `oq T@ ZO R{] bRl bQ{ H^K D[ rm In| oK l[ iTj s Ny kTG qyW rg Wv sRE GT lf |Tv uE o yT >YM K\ uYl m{ VK rF\ rxk rB{ MK y] Y% iGl Ts eTB jQ Ka zo ET  YN o] Y%Y%EBm @~ 'TM %e[ Ej Gy !sH sX Kh 4ex lG 4BV q ae KF h V `e ou Y%TE RT Rb Qq jA ^Q Oa Io \ FN }\ Kk e{ TJ d Y Y%xh @w caG lh Bx jlH WV {e Ts QB W}P g` Rp l{ HN 0 \] zl Y%H{ W~J 0 FZ Elh Y%sw Y%TF <{T Y%_c Zjq Y%DtA ,lQ s` !po Du~ QM p Q\ DCm Y%z| WXK FBZ Iqh _v Y%HoE e fU WD{ cJ b[ Nok ^y Y%}H eV gf MBv TAE TBU ~e j _u T @e Wjt DC oS \vc ot AD RT Gc v `u EU P e Wp t WC TR doa Sq A@ QR ta JKoo M^ I {m jwh jlx BH LX hhg r^v EF pV rd Y%%is %gC ER . {c rGt Y%`B Y%E fR Gx qH gW Qg @v KF sV y }e Mb is pD T yR pK ~~ Y [ h qCw @~H ~oV jf TPt pjD bR G` lp u@ jP dj` n|n R| lK R~[  k Bz | fI Do z~ 'sM P^ mn Q| yL xR[ ek yz zI @Y o h Z| Ew | UK ^Z Vi Cpx R F KU ed W Ss BpF WT Od t }u }r }@ rO J_ ep b {M Z {[ KXV ze ^t hC I `R ^r Y%wC vS Y%ub or jB Y%[ R Q [` \{ _J eZ Y%gj Gz R bJ MYl L{ S^K *p[ Hli )px XF NW `e su QD HFT Qc wTs ` dC \g Wmv oYF eU oe Bxu sQE ^T Ad [Ju [^C [QS kRc [hq [P@ [OP Ne` HQo dQ HjN \^ em [o} [iL j\ d l e{ gvJ [jY [xi HKy Y%[I K Y IPh IOx BvH ETW Df Bv HxF xV D] e S EB BgG @RW vf +^t pC jR n` Soq 9lA zP N` ~o +Km K\{ +JK K[Z NRi KZx +II DeX +Hh Cw *eE wU Y%q Jd Yn M} Y%Y%xM d\ 7el 7g| lL 2U [ Cl <|o d~ <FN t] <Dl XK{ !aK !bZ 8Bh Sw fF lT I c Xxr NB OQ Qb ir Y%PA rP DK_ DJm `| RL w[ DIl k{ BI \X Y%|f Au DHG jV Od xQt XC pR Ba +Rq P@ QP Y` ln K } jN Cp ^ rN l{] l|l N b{ lF] lDl ]T{ MBO RD^ RFm Pq| R|L R}[ ik B| QL 4A\ ek a${ G$_ qDC HS kjb c p x ~jO qJ^ @}n k} q~N q] ol H| IK JZ Ki rox bH jW @Kg lv rK ^F ugd N wt qek Lz L I JX  gjg sQ qa Ap %A lO C_ go e %B O 7`^ 7^n p gO F_ wo Y%ro~ QN w^ rjl [ n| @zj rO{ rPK e[ Bk Fz GJ vZ Hh jv hgF WTV WUe iBt xC BR Ba Up j RO l_ ]ln e} TN B] xl R{ Y K Z Z gi By eH ^X xh Bx @G BU Rd !^t jE WoT Y%Y%Mld `t Y%Y%!kB nQ y` Bn l} NM Q\ |k j{ Y%!`K !r[ Bj Oy Y%pH Y%OW Y%Pg n yw W Cp js tA Eg kP q { Y%jM Ef k\ SG ~IU f^ i l h { QJ H X J i e w C zF o@ Y%c P za up b  t QP _a lp u I@ jI pY D ih CbQ X s W C !{ MR V _ U n Q } Zy L Y%UE !| OU {d d ^t w vR mH lX c sh g[ \ Ij E k s v^ rll j| zL !} r\ ZUN >gc >es JzeC Sh Qv PF OV F tf _Z li Ox Jy w C eR ua  \~q jo i eP {m` [\o gK z s[ ~N $p^ bSjm uPW  Njf [M oP Q H qP { @A F mA qjn ql~ lpN \`] t&} Sc gr ]B lmR ll` lnn ls| ltJ lxX lyf l{t l}B RAQ R` lo lA~ R}M R{\ Ryj Rxx RtF RsT gb } dr |V ESg Rnv jD ~ rS PE OU v re YW jf pu C BD jF }T D|c D}r jA jP g^ en ~~ BN R] &gl h| B cK n Z} <mL <lZ <nh <sv <tD <xR <y` <{n <}| ^zK &e[ <k <Az \zI XlY ZGpi KpY uZ i S$C!z og-RV5Re,StKsD?pTQK vb>(GXY%A M _Kl*g{!y GKK,RK0b S Wr+|I+}XDggK*wMgFMeVSlfSjvXjFsVoeSHvjEQoTudWpuY%Y%HODxTye{v|GHPXYh}wHlH[lXI@hlwgxF~TF er Tvg[JJ Y Y vigS_I~nIQ}ljMog[ Ak@ ]|BPY uhjwEyGoeVugf_ bv!x KXwscuespCvS e DaTek Ct\w+VEfl tT+dH -Wm rg+_Y:oh+]w+VFNWMfztPE{TeY%n pscstY%Y uC}lx9UGa WY%j fp wt g kB|CKG ZjiqwjFjUjdlreAL r aQK|OreAIQKb*_RIM XRiPxK _GLf= TuD u aCv [dw cjbmqL@ pOx T^ sr@ X rA sjAUPen`+[oeoJjYji ,xoGoWeugy ]v*S0b,r 0BQeC`sqz VA * W{ ldpPeG`eHq} BjQl`CofA pRe BoQY`F oA~Z} ~P@ lNG LzeFlUB d e&sjYii'gzlI vX B Ph exlGavV#vL4_Z@ kl{|&JMpQBiRA cZs|lClR RX biz@JKO\@Eltl{tBK@J ZD MiPviF@LWPf!t SvY%OIiY%L j%H yiH%A Y%vh%lwPF@OUPFeDk G x{ d4sEgDvjE%UhfluhyDWKT%g$bH iFhohl~SN\_Tmhj|ilLo\Y%e^k_l} MWWLS[JN Qln}YoKY%!H [TXkl{PqJjZUAjD{HjKQZxjIkyyHjVWWeGjts CDsR!waO MrY%: v!~ CM@pPAS^Cd%l=oQ=ja%jEp Cr(uCB4]%h2Q%e]C=`E]% TbdYvQ^gzONSIb3XKlKaVZ ^rbpU{RpRbUjtUUDUlTTXc^+A{TP|TdZLYjf^dOuTGxD^||^B0xTb7h%e2_Ta,Qdj}_BMY%Y%kdH\Y%Y%Y%TDfdkahJkbjr%G2\kN%n\%`IJ%qSqnDCL SiZ_s+vRy_aYKHwdp+B)[JnD@=r@[o@`?J@6I@b-tl@dazd|,[q2G@auytnB|ZL@Du\p/QA@{Qja:7q:Ph+Vx:ZbN_p:`yO:DdHd_lb-K:d_xqWp%g oLt{ J.In 4wMkLzCPIvWYC4pCed:IHCvxKd7CC4ztndC|CpvLoD+{C|flbp%qqVb*flPa*_lIBYv\htD @)Rj{{KA[q*lkV `f *FBIpo+#yl\Ukj{{KA[Bhl|qTUAECTFvgZtAAO @)^BGCV *eU@O CLO vX[,CAs,vht^C@\^Ch\^vUDCdYP}vrM`G A*F !A)pb.YtGdgU\2|8n ?fteDAs-tv\ a [g}^Mdjiq L$ZCg~teglsj @_Y% aC_C 0bF:RP@LILp[J'jtQz_Bnw'}+U;d+k_+0J+Oz+N6I+dwtv\_D Xb c{Et@+D`OgdolS++fb lHYUW jl {|tL+LyZB&Sty <U}H+K9Et~+H2MC~n}<\{KtF<N(Ut}<_+Kykvtaizo!ti<I+w#lb$Cop<e2_&tQ<Z_(ty<YcH<Zjk<[nU<vjC<}Fm<QVs<:I<'C"gj"ez"jJ"lZ"_j<ix<jG!`>V!oMT?ta!ujo!ftY;tM!QF[!R0alZQAtklYNzlZnHl[nvH(lv~dl}zblQZ\l:v'l'pliWQsfR]YQvoMGljT`?cE^bWt@nWOj$fc$J8#nh$QQN(uYt]J[+ktVU2d[[t&V\t|[B-J[H+wF [aAbV2caB)UaHD~aVOBltQG aG)_D2HgBizG gG)cgH_LgVNkd g3yJ2lmB)^mHDGmVEKstPF ma)^E\(G`Wo<eFtk ]M{utH$tWte nKtt~tN\H\td] DJr_+|tgI+u_u`rUUtj lkyp>d FFb mtht\\YkOSnDtrNqB XXs^Ktiow R'GYUnv|C L$tcNJst}\L] DOKtZIXi]C2ATysYHlM+t[M_QFlNtrOZfr^@L5^82S M2Etw(KGvZRtlRM{jHN WMctk)\mztg)N(vt^)_+ltW)I+ejP )sN^)ZKl)U'wt^ RU'ltS R[+atLR_+Z>tEtU z_cRI+BtmRN(|tdHst{R\\JtfRecutXRB:ft`NnO}o LC [F jK yROHtWRYUfRZn{R[niRvKW~bft`tT`?b>({aR}z\RQVVtlY%Y%VV{tQ-_V/LjP{W0Kt{tJgwYjiPSyN @Gr%Gtlt{j$Ic$m8#Qh$tU2XGFJEZPc2jB+\(Gw2oBSaVStlGQCFR(SUNkhtStb\Jrt|zKwWZ(aecFIi&tyDIQ_YRXxqDP3jTy+c/tNk`D\W`=` sw]2G T2qEb8tg>2(GvY0};tm7t{J83H>(T{Nn OQt}MtL\{ \StW Y_fWtEh$TY%gvxc1n8d_uXCriV [Oq^t@_+N`tyI_GbtfNPvdtF\lUftAB?OrXNitf_Fukt{IbJV^lptJ`>Y>(TWN7kstbotq\^A`=_>(f\wtB eDQutP|t`|zo|B~ewDM eQ,Qt}oK eR'[Y%Y%8LB<3NgAPQt`f8otgY%Y%>(tuti eXyytrtBeBAPY%f'QtxiBFeCSHe`v[efhQtyeiGtp etFtE erFTeYsZ eZ1M e^$~tb\HptxN`HWYh Z=A`@~t~XL|k&[hAsF-Oh|F7JLgAL}hhefKsVk0~F.ihWfF-ehRF-`LFWMhdF-rh_F-m@L}ZiKWX(bX+JX[u:PXjJ:tDI=nDXzkRBetgi8u8`mGKME_XDXVwKXMDKeXaptQ:`HIZXQc:tXQn@s:rtlC+{!P2f!XvX !VPNzJ^!NwhP_OotQuNR_CtbW}r!GBA!O^C!joa!^P!un\XA~\8eX\we:SXeMWirWQC:TX(NX+v7XBaY%WV2c<PU 7V?e7HdtlBx|)tVz]jW|qf B^W Au {F jV Uf lv +$E #iYb&LGErH;wWi$rWw)VWQ$WR$cWzJGjQP`Opt@^ $OIsV|%A`#fKBQIY%4iDZ"n^48Gl4GYs$CeL4U@qKG2q4Q$c4R$G4ISk,j~,AM,G_4qaoK\ *P4hz0db0Aq KR %CK] O-hK{ $w5t[5AiK] 'x9A_9{p9j@K+ePKi8uK_ )mABVAlef9u`\nqdJKa*n<SXDlkKb*zBtdGqtKp%DiK iKf mtLnaLyoKU %K`cdKtGKkr{QtmKd7{StrKb '@K>gw,e`3QVtDJRZt\Kd :l\tfdCt^twdDEHhIxixqz.iaQWaPgaOwatGQmVR_Cj?b84axFUl[4cb[SWl~8DjfVnntD[4X S\|k![4vg[4ll][4kI[4OtY%x[4IC[aL[4vm[4xc|[4u[G AP[4@QuOQ[4E`i8e[{]tX[4g7[4i f[4TO[44c[4Q#W<[4Lh[4PJt [4XD![4<\!9[4aX![4N7y! [4VGG![4v]"+[4[MS"[4Yn#Z[4e&G#[4>l#J j#[4As#[4[4{-F> tA>[4g P>[4Qw>[4^H>[4tf>[4oZ>e[4n{I> u}w?H+ d#t?+ BHW?+ @Z_?[4Py@+ |KI@[42T@[4{F@[4bzA@[4DacA+ H`gA `&GA6 tmA![4]{A7[4k8XBDQCB:[4=TB.QBI?B,C4~BB lrBB Z@BY%eg[OBY%B tjBY%Y%Y%Y%U vyBU ~ IBQ FYBW QgBQ pwBW OFBW PUBW teBgruB RA'gBQ tNBR t]B}ykBY DdB asBU tTB e~]cB[ K@BJEOBz ^TBY%x ]dBm ]sBm \BBY%x \RBz BbBz xrBz OABz PQBz QaBp pqBv K@Bp IOBZQ]BZSnBZOi@Bt IiBw TxBRR.GBZJuBP#GBw UjBRJ'yBt p`BJ,oBw'[Bm%7O`BBw tbB_i@pB+ `&pB{ tVB ^dB BtB xDBw {aF= RoF< hFNGMF< oTFrdF> YrFY%< ~BF& hRFY%P`F0 IoFY%, hF& @ MFS h]FN wkFY%= hzF= KIF9 oWFS FgF3 hvFS aDF2 TUF`dF\ suF EDFxTF& QcF? vrF7nBF- SSFY%? qcF lsF, YBF@ RQF, oaFG ^qF: `AFyQFY%G P`F= epFG QFY%C OFY%![^F, QmFM B|F, `KF g[F? xiFG xwF@ xGF {VF? RdF 5tF v^iFS pGF ZXFG OfFG jvF@ _FF `TF& `eF@(vIuFG o~FP hMFV`\F\|FG lKF R[F EkF_zF^JFV dXFN nqF0 R@F_PFF ^FV MlFT{FkJF= N[F+PjF R|FV V$KFY%V WToFY% JCFzxSF' tKF V Y)\F$ tEFV ZpSF C)CF& tlF* t{F I+IF- ttFV OCDF \bGF0 NiF, txF e`QGF2 tXF\^gFV C]EF: tbFV ~2pF5 D&bF6 BHF6 tWF5 vCeF athF9 t\F5 iDjF `rnFqO`FtVoFvMEF%ylRFH t~F!^mLF^IyFq%BFE RgFriuvF|5kF S*`FY%Y%`aJF7hLkF7C^wFP tUFLOcF^yrF akFJ}{F^=xGV [4L|uG}}AG [4_~Hu1]HW^$NH4^$rH^HVHrv^H [4bTHpjvH^ t`H1roH|!~H hMH Y\H rmHV g#~H SOHNs^HEnH\}H hLHKg![HV q$lH h}HK_!KHAS\H+\kHQb#zHu"KH. v$[H. w"kH+d#zHD\KHFZH b#hHQsxHj!sHH_ E{HIKHqGZHSsjHK\!zHIKHKm#ZH TiH. oyH YIH- IYHf ohHTxH hGHTUHh$dH. jtHE"DH!|"SH C$bH_$pH @ ~HhNHh\H\BjH \J# |Ho#IHIYHTIhH v$wHqM#FHYUH YdHqj"tHIBH. lQHKl#aH n"pHD$@HZIPHyI_Hu$nHI]#~HINHIZ#]HKd!nHATH@"NH_ _\H_ olH\|H^!KHTg$[HIjHIj#yHb"IH }ZHOjH o$yHP#GHV J"VH [$pHZ AH_ `QHn#_H y$nH w$}Hc KHS p[H\i$jHS TyH e"HHL pXH N"gHTwHqlGHjWHqDgHJ rvHFHa$UHB q"cHZ$rH? Y@HX$OHV$_HpnH0 p}HKL"KH1 pZH!q!hHKO!wH YFH4 YVH4 s$fHKU!vH/ s$EHKm!UH/ YdH> ptH!F$CH!p!RHKW!aH@ tpH!s!H? mNH!P!_HB i#nHM!|H+ oKHJZHKY!dHn!sH` DHlTH}!fcHqjIHB#YHs|HN ILHv#\HQ ^HS IOHQ P^HU ImHU l}HV d$LH[ [H\ RkH_ rzH G$JH4c!XHr!gH!wH V#GH tjH IyHz x!+HHV m XsHV s \KH tgHz )vHV `P_H loHe g#}HV v r MHz N!2H7~!GqH Ke!NxH B$FH7k\THV g 3pH  BScH\N kvH taH ,Z{pH BUkH n@H C)NHKK"%wHD"3\Hx YOH H#hHKS!%vH t[H KG"'iH" tPH Ky!'^H( tEH/DSH\^ NWIq IeItnI Ku!'|Ii+#cITFIKB"8UI. oMI+`e\IKn *AIZn ;kI<~7fIl~7]I/ tTI P$bIn ;FI; tAI; TOI4 t^IKv!DlI; IpI; pIJ'NI> tuIKV!CI T!FRI+ h ?XIYzWI@!+QIe U|IB#QI{ N_I)Q!$mI2f6QIF tGIy+UIH t@Iq CNI [4HQIL]YIt tvIB!8DIt T|IN tKIC!.YIS tGI BUIQ tWID!AfIL tgIU ouIAtEIU tTI^ {bI^ R]IvoIWf;nI_ tiIz nxIWy)fI` tOIf t]I4fNkI V :yIz [4J sI w!q}Iz R"bnIz S"bPI f#BrI c#BtI p"BvI T"BxI U"BzI V"B|I W"B~I X"B@Iu DBIu jRI1$bIu lrITAIw tUIa&l|@cIF%cIC@rI| R%rI R%BI_7GKRIwQ%e]IPP%eBI lgI BwI_GKFIA.~ G#QI} [4_tI~ [4^SI|-} G#qI:a