Advertisement
Guest User

Untitled

a guest
Jul 16th, 2018
1,693
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 153.88 KB | None | 0 0
  1. /**
  2. * Copyright 1998-2012 Epic Games, Inc. All Rights Reserved.
  3. */
  4. class UTPawn extends UDKPawn
  5. config(Game)
  6. notplaceable;
  7.  
  8. var bool bFixedView;
  9. var bool bSpawnDone; // true when spawn protection has been deactivated
  10. var bool bSpawnIn;
  11. var bool bShieldAbsorb; // set true when shield absorbs damage
  12. var bool bDodging; // true while in air after dodging
  13. var bool bStopOnDoubleLanding;
  14. var bool bIsInvulnerable;
  15. var bool bJustDroppedOrb; // if orb dropped because knocked off hoverboard
  16.  
  17. /** Holds the class type of the current weapon attachment. Replicated to all clients. */
  18. var repnotify class<UTWeaponAttachment> CurrentWeaponAttachmentClass;
  19.  
  20. /** count of failed unfeign attempts - kill pawn if too many */
  21. var int UnfeignFailedCount;
  22.  
  23. /** true when feign death activation forced (e.g. knocked off hoverboard) */
  24. var bool bForcedFeignDeath;
  25.  
  26. /** The pawn's light environment */
  27. var DynamicLightEnvironmentComponent LightEnvironment;
  28.  
  29. /** anim node used for feign death recovery animations */
  30. var AnimNodeBlend FeignDeathBlend;
  31.  
  32. /** Slot node used for playing full body anims. */
  33. var AnimNodeSlot FullBodyAnimSlot;
  34.  
  35. /** Slot node used for playing animations only on the top half. */
  36. var AnimNodeSlot TopHalfAnimSlot;
  37.  
  38. var(DeathAnim) float DeathHipLinSpring;
  39. var(DeathAnim) float DeathHipLinDamp;
  40. var(DeathAnim) float DeathHipAngSpring;
  41. var(DeathAnim) float DeathHipAngDamp;
  42.  
  43. /** World time that we started the death animation */
  44. var float StartDeathAnimTime;
  45. /** Type of damage that started the death anim */
  46. var class<UTDamageType> DeathAnimDamageType;
  47. /** Time that we took damage of type DeathAnimDamageType. */
  48. var float TimeLastTookDeathAnimDamage;
  49.  
  50. var globalconfig bool bWeaponBob;
  51. var bool bJustLanded; /** used by eyeheight adjustment. True if pawn recently landed from a fall */
  52. var bool bLandRecovery; /** used by eyeheight adjustment. True if pawn recovering (eyeheight increasing) after lowering from a landing */
  53.  
  54. var bool bHasHoverboard;
  55.  
  56. /*********************************************************************************************
  57. Camera related properties
  58. ********************************************************************************************* */
  59. var vector FixedViewLoc;
  60. var rotator FixedViewRot;
  61. var float CameraScale, CurrentCameraScale; /** multiplier to default camera distance */
  62. var float CameraScaleMin, CameraScaleMax;
  63.  
  64. /** Stop death camera using OldCameraPosition if true */
  65. var bool bStopDeathCamera;
  66.  
  67. /** OldCameraPosition saved when dead for use if fall below killz */
  68. var vector OldCameraPosition;
  69.  
  70. /** used to smoothly adjust camera z offset in third person */
  71. var float CameraZOffset;
  72.  
  73. /** If true, use end of match "Hero" camera */
  74. var bool bWinnerCam;
  75.  
  76. /** Used for end of match "Hero" camera */
  77. var(HeroCamera) float HeroCameraScale;
  78.  
  79. /** Used for end of match "Hero" camera */
  80. var(HeroCamera) int HeroCameraPitch;
  81.  
  82. var float DodgeSpeed;
  83. var float DodgeSpeedZ;
  84. var eDoubleClickDir CurrentDir;
  85. var() float DoubleJumpEyeHeight;
  86. var float DoubleJumpThreshold;
  87. var float DefaultAirControl;
  88.  
  89. /** view bob properties */
  90. var globalconfig float Bob;
  91. var float LandBob;
  92. var float JumpBob;
  93. var float AppliedBob;
  94. var float bobtime;
  95. var vector WalkBob;
  96.  
  97. /** when a body in feign death's velocity is less than this, it is considered to be at rest (allowing the player to get up) */
  98. var float FeignDeathBodyAtRestSpeed;
  99.  
  100. /** when we entered feign death; used to increase FeignDeathBodyAtRestSpeed over time so we get up in a reasonable amount of time */
  101. var float FeignDeathStartTime;
  102.  
  103. /** When feign death recovery started. Used to pull feign death camera into body during recovery */
  104. var float FeignDeathRecoveryStartTime;
  105.  
  106. var int SuperHealthMax; /** Maximum allowable boosted health */
  107.  
  108. var class<UTPawnSoundGroup> SoundGroupClass;
  109.  
  110. /** This pawn's current family/class info **/
  111. var class<UTFamilyInfo> CurrCharClassInfo;
  112.  
  113. /** bones to set fixed when doing the physics take hit effects */
  114. var array<name> TakeHitPhysicsFixedBones;
  115.  
  116. /** Array of bodies that should not have joint drive applied. */
  117. var array<name> NoDriveBodies;
  118.  
  119. /** Controller vibration for taking falling damage. */
  120. var ForceFeedbackWaveform FallingDamageWaveForm;
  121.  
  122.  
  123. /*********************************************************************************************
  124. Gibs
  125. ********************************************************************************************* */
  126.  
  127. /** Track damage accumulated during a tick - used for gibbing determination */
  128. var float AccumulateDamage;
  129.  
  130. /** Tick time for which damage is being accumulated */
  131. var float AccumulationTime;
  132.  
  133. /** whether or not we have been gibbed already */
  134. var bool bGibbed;
  135.  
  136. /** whether or not we have been decapitated already */
  137. var bool bHeadGibbed;
  138.  
  139. /*********************************************************************************************
  140. Hoverboard
  141. ********************************************************************************************* */
  142. var float LastHoverboardTime;
  143. var float MinHoverboardInterval;
  144.  
  145. /** Node used for blending between driving and non-driving state. */
  146. var UTAnimBlendByDriving DrivingNode;
  147.  
  148. /** Node used for blending between different types of vehicle. */
  149. var UTAnimBlendByVehicle VehicleNode;
  150.  
  151. /** Node used for various hoverboarding actions. */
  152. var UTAnimBlendByHoverboarding HoverboardingNode;
  153.  
  154. /*********************************************************************************************
  155. Armor
  156. ********************************************************************************************* */
  157. var float ShieldBeltArmor;
  158. var float VestArmor;
  159. var float ThighpadArmor;
  160.  
  161. /*********************************************************************************************
  162. Weapon / Firing
  163. ********************************************************************************************* */
  164.  
  165. var bool bArmsAttached;
  166.  
  167. /** This holds the local copy of the current attachment. This "attachment" actor will exist independantly on all clients */
  168. var UTWeaponAttachment CurrentWeaponAttachment;
  169. /** client side flag indicating whether attachment should be visible - primarily used when spawning the initial weapon attachment
  170. * as events that change its visibility might have happened before we received a CurrentWeaponAttachmentClass
  171. * to spawn and call the visibility functions on
  172. */
  173. var bool bWeaponAttachmentVisible;
  174.  
  175. /** WeaponSocket contains the name of the socket used for attaching weapons to this pawn. */
  176. var name WeaponSocket, WeaponSocket2;
  177.  
  178. /** Socket to find the feet */
  179. var name PawnEffectSockets[2];
  180.  
  181. /** These values are used for determining headshots */
  182. var float HeadOffset;
  183. var float HeadRadius;
  184. var float HeadHeight;
  185. var name HeadBone;
  186. /** We need to save a reference to the headshot neck attachment for the case of: Headshot then gibbed so we can hide this **/
  187. var protected StaticMeshComponent HeadshotNeckAttachment;
  188.  
  189. var class<Actor> TransInEffects[2];
  190. var LinearColor TranslocateColor[2];
  191. /** camera anim played when spawned/teleported */
  192. var CameraAnim TransCameraAnim[3];
  193.  
  194. var SoundCue ArmorHitSound;
  195. /** sound played when initially spawning in */
  196. var SoundCue SpawnSound;
  197. /** sound played when we teleport */
  198. var SoundCue TeleportSound;
  199.  
  200. /** Set when pawn died on listen server, but was hidden rather than ragdolling (for replication purposes) */
  201. var bool bHideOnListenServer;
  202.  
  203. /*********************************************************************************************
  204. Overlay system
  205.  
  206. UTPawns support 2 separate overlay systems. The first is a simple colorizer that can be used to
  207. apply a color to the pawn's skin. This is accessed via the
  208. ********************************************************************************************* */
  209.  
  210. /** This is the color that will be applied when a pawn is first spawned in and is covered by protection */
  211. var LinearColor SpawnProtectionColor;
  212.  
  213. /*********************************************************************************************
  214. * Team beacons
  215. ********************************************************************************************* */
  216. var(TeamBeacon) float TeamBeaconPlayerInfoMaxDist;
  217. var(TeamBeacon) Texture SpeakingBeaconTexture;
  218.  
  219. /** true is last trace test check for drawing postrender beacon succeeded */
  220. var bool bPostRenderTraceSucceeded;
  221.  
  222. /*********************************************************************************************
  223. * HUD Icon
  224. ********************************************************************************************* */
  225. var float MapSize;
  226. var TextureCoordinates IconCoords; /** Coordiates of the icon associated with this object */
  227. /*********************************************************************************************
  228. * Pain
  229. ********************************************************************************************* */
  230. const MINTIMEBETWEENPAINSOUNDS=0.35;
  231. var float LastPainSound;
  232. var float RagdollLifespan;
  233. var UTProjectile AttachedProj;
  234.  
  235. /** Max distance from listener to play footstep sounds */
  236. var float MaxFootstepDistSq;
  237.  
  238. /** Max distance from listener to play jump/land sounds */
  239. var float MaxJumpSoundDistSq;
  240.  
  241. /*********************************************************************************************
  242. * Skin swapping support
  243. ********************************************************************************************* */
  244. /** type of vehicle spawned when activating the hoverboard */
  245. var class<UTVehicle> HoverboardClass;
  246.  
  247. var DrivenWeaponPawnInfo LastDrivenWeaponPawn;
  248. /** reference WeaponPawn spawned on non-owning clients for code that checks for DrivenVehicle */
  249. var UTClientSideWeaponPawn ClientSideWeaponPawn;
  250.  
  251. /** set on client when valid team info is received; future changes are then ignored unless this gets reset first
  252. * this is used to prevent the problem where someone changes teams and their old dying pawn changes color
  253. * because the team change was received before the pawn's dying
  254. */
  255. var bool bReceivedValidTeam;
  256.  
  257. /*********************************************************************************************
  258. * Hud Widgets
  259. ********************************************************************************************* */
  260.  
  261. /** The default overlay to use when not in a team game */
  262. var MaterialInterface ShieldBeltMaterialInstance;
  263. /** A collection of overlays to use in team games */
  264. var MaterialInterface ShieldBeltTeamMaterialInstances[4];
  265.  
  266. /** If true, head size will change based on ratio of kills to deaths */
  267. var bool bKillsAffectHead;
  268.  
  269. /** Mirrors the # of charges available to jump boots */
  270. var int JumpBootCharge;
  271.  
  272. /** Mesh scaling default */
  273. var float DefaultMeshScale;
  274.  
  275. var name TauntNames[6];
  276.  
  277. /** currently desired scale of the hero (switches between crouched and default) */
  278. var float DesiredMeshScale;
  279.  
  280. /** Third person camera offset */
  281. var vector CamOffset;
  282.  
  283. /** information on what gibs to spawn and where */
  284. struct GibInfo
  285. {
  286. /** the bone to spawn the gib at */
  287. var name BoneName;
  288. /** the gib class to spawn */
  289. var class<UTGib> GibClass;
  290. var bool bHighDetailOnly;
  291. };
  292.  
  293. /** bio death effect - updates BioEffectName parameter in the mesh's materials from 0 to 10 over BioBurnAwayTime
  294. * activated BioBurnAway particle system on death, deactivates it when BioBurnAwayTime expires
  295. * could easily be overridden by a custom death effect to use other effects/materials, @see UTDmgType_BioGoo
  296. */
  297. var bool bKilledByBio;
  298. var ParticleSystemComponent BioBurnAway;
  299. var float BioBurnAwayTime;
  300. var name BioEffectName;
  301.  
  302. /** Time at which this pawn entered the dying state */
  303. var float DeathTime;
  304.  
  305. enum EWeapAnimType
  306. {
  307. EWAT_Default,
  308. EWAT_Pistol,
  309. EWAT_DualPistols,
  310. EWAT_ShoulderRocket,
  311. EWAT_Stinger
  312. };
  313.  
  314. replication
  315. {
  316. if ( bNetOwner && bNetDirty )
  317. bHasHoverboard, ShieldBeltArmor, VestArmor, ThighpadArmor;
  318. if ( bNetDirty )
  319. CurrentWeaponAttachmentClass;
  320. }
  321.  
  322. simulated function AdjustPPEffects(UTPlayerController PC, bool bRemove);
  323.  
  324. /*************************************************************/
  325.  
  326.  
  327. /* return a value (typically 0 to 1) adjusting pawn's perceived strength if under some special influence (like berserk)
  328. */
  329. function float AdjustedStrength()
  330. {
  331. return 0;
  332. }
  333.  
  334. /** Accessor to make sure we always get a valid UTPRI */
  335. simulated function UTPlayerReplicationInfo GetUTPlayerReplicationInfo()
  336. {
  337. local UTPlayerReplicationInfo UTPRI;
  338.  
  339. UTPRI = UTPlayerReplicationInfo(PlayerReplicationInfo);
  340. if (UTPRI == None)
  341. {
  342. if (DrivenVehicle != None)
  343. {
  344. UTPRI = UTPlayerReplicationInfo(DrivenVehicle.PlayerReplicationInfo);
  345. }
  346. }
  347.  
  348. return UTPRI;
  349. }
  350.  
  351. simulated event FellOutOfWorld(class<DamageType> dmgType)
  352. {
  353. super.FellOutOfWorld(DmgType);
  354. bStopDeathCamera = true;
  355. }
  356.  
  357. event HeadVolumeChange(PhysicsVolume newHeadVolume)
  358. {
  359. if ( (WorldInfo.NetMode == NM_Client) || (Controller == None) )
  360. return;
  361. if (HeadVolume != None && HeadVolume.bWaterVolume)
  362. {
  363. if ( !newHeadVolume.bWaterVolume )
  364. {
  365. if ( Controller.bIsPlayer && (BreathTime > 0) && (BreathTime < 8) )
  366. Gasp();
  367. BreathTime = -1.0;
  368. }
  369. }
  370. else if ( newHeadVolume != None && newHeadVolume.bWaterVolume )
  371. {
  372. BreathTime = UnderWaterTime;
  373. }
  374. }
  375.  
  376. /** PoweredUp()
  377. returns true if pawn has game play advantages, as defined by specific game implementation
  378. */
  379. function bool PoweredUp()
  380. {
  381. return ( (DamageScaling > 1) || (FireRateMultiplier < 1) || bIsInvulnerable );
  382. }
  383.  
  384. /** InCombat()
  385. returns true if pawn is currently in combat, as defined by specific game implementation.
  386. */
  387. function bool InCombat()
  388. {
  389. return (WorldInfo.TimeSeconds - LastPainSound < 1) && !PhysicsVolume.bPainCausing;
  390. }
  391.  
  392. simulated function RenderMapIcon(UTMapInfo MP, Canvas Canvas, UTPlayerController PlayerOwner, LinearColor FinalColor)
  393. {
  394. MP.DrawRotatedTile(Canvas, class'UTHUD'.default.IconHudTexture, HUDLocation, Rotation.Yaw, MapSize, IconCoords, FinalColor);
  395. }
  396.  
  397. /**
  398. * UTPawns not allowed to set bIsWalking true
  399. */
  400. event SetWalking( bool bNewIsWalking )
  401. {
  402. }
  403.  
  404. simulated function ClearBodyMatColor()
  405. {
  406. RemainingBodyMatDuration = 0;
  407. ClientBodyMatDuration = 0;
  408. BodyMatFadeDuration = 0;
  409. }
  410.  
  411. simulated function SetBodyMatColor(LinearColor NewBodyMatColor, float NewOverlayDuration)
  412. {
  413. RemainingBodyMatDuration = NewOverlayDuration;
  414. ClientBodyMatDuration = RemainingBodyMatDuration;
  415. BodyMatFadeDuration = 0.5 * RemainingBodyMatDuration;
  416. BodyMatColor = NewBodyMatColor;
  417. CompressedBodyMatColor.Pitch = 256.0 * BodyMatColor.R;
  418. CompressedBodyMatColor.Yaw = 256.0 * BodyMatColor.G;
  419. CompressedBodyMatColor.Roll = 256.0 * BodyMatColor.B;
  420.  
  421. CurrentBodyMatColor = BodyMatColor;
  422. CurrentBodyMatColor.R += 1; // make sure CurrentBodyMatColor differs from BodyMatColor to force update
  423. VerifyBodyMaterialInstance();
  424. }
  425.  
  426. simulated function SetInvisible(bool bNowInvisible)
  427. {
  428. bIsInvisible = bNowInvisible;
  429.  
  430. if (WorldInfo.NetMode != NM_DedicatedServer)
  431. {
  432. if (bIsInvisible)
  433. {
  434. Mesh.CastShadow = false;
  435. Mesh.bCastDynamicShadow = false;
  436. ReattachMesh();
  437. }
  438. else
  439. {
  440. UpdateShadowSettings(!class'Engine'.static.IsSplitScreen() && class'UTPlayerController'.default.PawnShadowMode == SHADOW_All);
  441. }
  442. }
  443. }
  444.  
  445. /**
  446. * SetSkin is used to apply a single material to the entire model, including any applicable attachments.
  447. * NOTE: Attachments (ie: the weapons) need to handle resetting their default skin if NewMaterinal = NONE
  448. *
  449. * @Param NewMaterial The material to apply
  450. */
  451.  
  452. simulated function SetSkin(Material NewMaterial)
  453. {
  454. local int i;
  455.  
  456. // Replicate the Material to remote clients
  457. ReplicatedBodyMaterial = NewMaterial;
  458.  
  459. if (VerifyBodyMaterialInstance()) // Make sure we have setup the BodyMaterialInstances array
  460. {
  461. // Propagate it to the 3rd person weapon attachment
  462. if (CurrentWeaponAttachment != None)
  463. {
  464. CurrentWeaponAttachment.SetSkin(NewMaterial);
  465. }
  466.  
  467. // Propagate it to the 1st person weapon
  468. if (UTWeapon(Weapon) != None)
  469. {
  470. UTWeapon(Weapon).SetSkin(NewMaterial);
  471. }
  472.  
  473. // Set the skin
  474. if (NewMaterial == None)
  475. {
  476. for (i = 0; i < Mesh.SkeletalMesh.Materials.length; i++)
  477. {
  478. Mesh.SetMaterial(i, BodyMaterialInstances[i]);
  479. }
  480. }
  481. else
  482. {
  483. for (i = 0; i < Mesh.SkeletalMesh.Materials.length; i++)
  484. {
  485. Mesh.SetMaterial(i, NewMaterial);
  486. }
  487. }
  488.  
  489. SetArmsSkin(NewMaterial);
  490. }
  491. }
  492.  
  493. simulated protected function SetArmsSkin(MaterialInterface NewMaterial)
  494. {
  495. local int i,Cnt;
  496.  
  497. // if no material specified, grab default from PRI (if that's None too, use mesh default)
  498. if (NewMaterial == None)
  499. {
  500. NewMaterial = CurrCharClassInfo.static.GetFirstPersonArmsMaterial(GetTeamNum());
  501. }
  502.  
  503. if ( NewMaterial == None ) // Clear the materials
  504. {
  505. if(default.ArmsMesh[0] != none && ArmsMesh[0] != none)
  506. {
  507. if( default.ArmsMesh[0].Materials.Length > 0)
  508. {
  509. Cnt = Default.ArmsMesh[0].Materials.Length;
  510. for(i=0;i<Cnt;i++)
  511. {
  512. ArmsMesh[0].SetMaterial(i,Default.ArmsMesh[0].GetMaterial(i) );
  513. }
  514. }
  515. else if(ArmsMesh[0].Materials.Length > 0)
  516. {
  517. Cnt = ArmsMesh[0].Materials.Length;
  518. for(i=0;i<Cnt;i++)
  519. {
  520. ArmsMesh[0].SetMaterial(i,none);
  521. }
  522. }
  523. }
  524.  
  525. if(default.ArmsMesh[1] != none && ArmsMesh[1] != none)
  526. {
  527. if( default.ArmsMesh[1].Materials.Length > 0)
  528. {
  529. Cnt = Default.ArmsMesh[1].Materials.Length;
  530. for(i=0;i<Cnt;i++)
  531. {
  532. ArmsMesh[1].SetMaterial(i,Default.ArmsMesh[1].GetMaterial(i) );
  533. }
  534. }
  535. else if(ArmsMesh[1].Materials.Length > 0)
  536. {
  537. Cnt = ArmsMesh[1].Materials.Length;
  538. for(i=0;i<Cnt;i++)
  539. {
  540. ArmsMesh[1].SetMaterial(i,none);
  541. }
  542. }
  543. }
  544. }
  545. else
  546. {
  547. if ((default.ArmsMesh[0] != none && ArmsMesh[0] != none) && (default.ArmsMesh[0].Materials.Length > 0 || ArmsMesh[0].GetNumElements() > 0))
  548. {
  549. Cnt = default.ArmsMesh[0].Materials.Length > 0 ? default.ArmsMesh[0].Materials.Length : ArmsMesh[0].GetNumElements();
  550. for(i=0; i<Cnt;i++)
  551. {
  552. ArmsMesh[0].SetMaterial(i,NewMaterial);
  553. }
  554. }
  555. if ((default.ArmsMesh[1] != none && ArmsMesh[1] != none) && (default.ArmsMesh[1].Materials.Length > 0 || ArmsMesh[1].GetNumElements() > 0))
  556. {
  557. Cnt = default.ArmsMesh[1].Materials.Length > 0 ? default.ArmsMesh[1].Materials.Length : ArmsMesh[1].GetNumElements();
  558. for(i=0; i<Cnt;i++)
  559. {
  560. ArmsMesh[1].SetMaterial(i,NewMaterial);
  561. }
  562. }
  563. }
  564. }
  565. /**
  566. * This function will verify that the BodyMaterialInstance variable is setup and ready to go. This is a key
  567. * component for the BodyMat overlay system
  568. */
  569. simulated function bool VerifyBodyMaterialInstance()
  570. {
  571. local int i;
  572.  
  573. if (WorldInfo.NetMode != NM_DedicatedServer && Mesh != None && BodyMaterialInstances.length < Mesh.GetNumElements())
  574. {
  575. // set up material instances (for overlay effects)
  576. BodyMaterialInstances.length = Mesh.GetNumElements();
  577. for (i = 0; i < BodyMaterialInstances.length; i++)
  578. {
  579. if (BodyMaterialInstances[i] == None)
  580. {
  581. BodyMaterialInstances[i] = Mesh.CreateAndSetMaterialInstanceConstant(i);
  582. }
  583. }
  584. }
  585. return (BodyMaterialInstances.length > 0);
  586. }
  587.  
  588. /** Set various basic properties for this UTPawn based on the character class metadata */
  589. simulated function SetCharacterClassFromInfo(class<UTFamilyInfo> Info)
  590. {
  591. local UTPlayerReplicationInfo PRI;
  592. local int i;
  593. local int TeamNum;
  594. local MaterialInterface TeamMaterialHead, TeamMaterialBody, TeamMaterialArms;
  595.  
  596. PRI = GetUTPlayerReplicationInfo();
  597.  
  598. if (Info != CurrCharClassInfo)
  599. {
  600. // Set Family Info
  601. CurrCharClassInfo = Info;
  602.  
  603. // get the team number (0 red, 1 blue, 255 no team)
  604. TeamNum = GetTeamNum();
  605.  
  606. // AnimSets
  607. Mesh.AnimSets = Info.default.AnimSets;
  608.  
  609. //Apply the team skins if necessary
  610. if (WorldInfo.NetMode != NM_DedicatedServer)
  611. {
  612. Info.static.GetTeamMaterials(TeamNum, TeamMaterialHead, TeamMaterialBody);
  613. }
  614.  
  615. // 3P Mesh and materials
  616. SetCharacterMeshInfo(Info.default.CharacterMesh, TeamMaterialHead, TeamMaterialBody);
  617.  
  618. // First person arms mesh/material (if necessary)
  619. if (WorldInfo.NetMode != NM_DedicatedServer && IsHumanControlled() && IsLocallyControlled())
  620. {
  621. TeamMaterialArms = Info.static.GetFirstPersonArmsMaterial(TeamNum);
  622. SetFirstPersonArmsInfo(Info.static.GetFirstPersonArms(), TeamMaterialArms);
  623. }
  624.  
  625. // PhysicsAsset
  626. // Force it to re-initialise if the skeletal mesh has changed (might be flappy bones etc).
  627. Mesh.SetPhysicsAsset(Info.default.PhysAsset, true);
  628.  
  629. // Make sure bEnableFullAnimWeightBodies is only TRUE if it needs to be (PhysicsAsset has flappy bits)
  630. Mesh.bEnableFullAnimWeightBodies = FALSE;
  631. for(i=0; i<Mesh.PhysicsAsset.BodySetup.length && !Mesh.bEnableFullAnimWeightBodies; i++)
  632. {
  633. // See if a bone has bAlwaysFullAnimWeight set and also
  634. if( Mesh.PhysicsAsset.BodySetup[i].bAlwaysFullAnimWeight &&
  635. Mesh.MatchRefBone(Mesh.PhysicsAsset.BodySetup[i].BoneName) != INDEX_NONE)
  636. {
  637. Mesh.bEnableFullAnimWeightBodies = TRUE;
  638. }
  639. }
  640.  
  641. //Overlay mesh for effects
  642. if (OverlayMesh != None)
  643. {
  644. OverlayMesh.SetSkeletalMesh(Info.default.CharacterMesh);
  645. }
  646.  
  647. //Set some properties on the PRI
  648. if (PRI != None)
  649. {
  650. PRI.bIsFemale = Info.default.bIsFemale;
  651. PRI.VoiceClass = Info.static.GetVoiceClass();
  652.  
  653. // Assign fallback portrait.
  654. PRI.CharPortrait = Info.static.GetCharPortrait(TeamNum);
  655.  
  656. // a little hacky, relies on presumption that enum vals 0-3 are male, 4-8 are female
  657. if ( PRI.bIsFemale )
  658. {
  659. PRI.TTSSpeaker = ETTSSpeaker(Rand(4));
  660. }
  661. else
  662. {
  663. PRI. TTSSpeaker = ETTSSpeaker(Rand(5) + 4);
  664. }
  665. }
  666.  
  667. // Bone names
  668. LeftFootBone = Info.default.LeftFootBone;
  669. RightFootBone = Info.default.RightFootBone;
  670. TakeHitPhysicsFixedBones = Info.default.TakeHitPhysicsFixedBones;
  671.  
  672. // sounds
  673. SoundGroupClass = Info.default.SoundGroupClass;
  674.  
  675. DefaultMeshScale = Info.Default.DefaultMeshScale;
  676. Mesh.SetScale(DefaultMeshScale);
  677. BaseTranslationOffset = CurrCharClassInfo.Default.BaseTranslationOffset;
  678. CrouchTranslationOffset = BaseTranslationOffset + CylinderComponent.Default.CollisionHeight - CrouchHeight;
  679. }
  680. }
  681.  
  682. /** Accessor that sets the character mesh to use for this pawn, and updates instance of player in map if there is one. */
  683. simulated function SetCharacterMeshInfo(SkeletalMesh SkelMesh, MaterialInterface HeadMaterial, MaterialInterface BodyMaterial)
  684. {
  685. Mesh.SetSkeletalMesh(SkelMesh);
  686.  
  687. if (WorldInfo.NetMode != NM_DedicatedServer)
  688. {
  689. if (VerifyBodyMaterialInstance())
  690. {
  691. BodyMaterialInstances[0].SetParent(HeadMaterial);
  692. if (BodyMaterialInstances.length > 1)
  693. {
  694. BodyMaterialInstances[1].SetParent(BodyMaterial);
  695. }
  696. }
  697. else
  698. {
  699. `log("VerifyBodyMaterialInstance failed on pawn"@self);
  700. }
  701. }
  702. }
  703.  
  704. simulated function SetPawnRBChannels(bool bRagdollMode)
  705. {
  706. if(bRagdollMode)
  707. {
  708. Mesh.SetRBChannel(RBCC_Pawn);
  709. Mesh.SetRBCollidesWithChannel(RBCC_Default,TRUE);
  710. Mesh.SetRBCollidesWithChannel(RBCC_Pawn,TRUE);
  711. Mesh.SetRBCollidesWithChannel(RBCC_Vehicle,TRUE);
  712. Mesh.SetRBCollidesWithChannel(RBCC_Untitled3,FALSE);
  713. Mesh.SetRBCollidesWithChannel(RBCC_BlockingVolume,TRUE);
  714. }
  715. else
  716. {
  717. Mesh.SetRBChannel(RBCC_Untitled3);
  718. Mesh.SetRBCollidesWithChannel(RBCC_Default,FALSE);
  719. Mesh.SetRBCollidesWithChannel(RBCC_Pawn,FALSE);
  720. Mesh.SetRBCollidesWithChannel(RBCC_Vehicle,FALSE);
  721. Mesh.SetRBCollidesWithChannel(RBCC_Untitled3,TRUE);
  722. Mesh.SetRBCollidesWithChannel(RBCC_BlockingVolume,FALSE);
  723. }
  724. }
  725.  
  726. simulated function ResetCharPhysState()
  727. {
  728. local UTVehicle UTV;
  729.  
  730. if(Mesh.PhysicsAssetInstance != None)
  731. {
  732. // Now set up the physics based on what we are currently doing.
  733. if(Physics == PHYS_RigidBody)
  734. {
  735. // Ragdoll case
  736. Mesh.PhysicsAssetInstance.SetAllBodiesFixed(FALSE);
  737. SetPawnRBChannels(TRUE);
  738. SetHandIKEnabled(FALSE);
  739. }
  740. else
  741. {
  742. // Normal case
  743. Mesh.PhysicsAssetInstance.SetAllBodiesFixed(TRUE);
  744. Mesh.PhysicsAssetInstance.SetFullAnimWeightBonesFixed(FALSE, Mesh);
  745. SetPawnRBChannels(FALSE);
  746. SetHandIKEnabled(TRUE);
  747.  
  748. // Allow vehicles to do any specific modifications to driver
  749. if(DrivenVehicle != None)
  750. {
  751. UTV = UTVehicle(DrivenVehicle);
  752. if(UTV != None)
  753. {
  754. UTV.OnDriverPhysicsAssetChanged(self);
  755. }
  756. }
  757. }
  758. }
  759. }
  760.  
  761. simulated function NotifyTeamChanged()
  762. {
  763. local UTPlayerReplicationInfo PRI;
  764. local int i;
  765.  
  766. // set mesh to the one in the PRI, or default for this team if not found
  767. PRI = GetUTPlayerReplicationInfo();
  768.  
  769. if (PRI != None)
  770. {
  771. SetCharacterClassFromInfo(GetFamilyInfo());
  772.  
  773. if (WorldInfo.NetMode != NM_DedicatedServer)
  774. {
  775. // refresh weapon attachment
  776. if (CurrentWeaponAttachmentClass != None)
  777. {
  778. // recreate weapon attachment in case the socket on the new mesh is in a different place
  779. if (CurrentWeaponAttachment != None)
  780. {
  781. CurrentWeaponAttachment.DetachFrom(Mesh);
  782. CurrentWeaponAttachment.Destroy();
  783. CurrentWeaponAttachment = None;
  784. }
  785. WeaponAttachmentChanged();
  786. }
  787. // refresh overlay
  788. if (OverlayMaterialInstance != None)
  789. {
  790. SetOverlayMaterial(OverlayMaterialInstance);
  791. }
  792. }
  793.  
  794. // Make sure physics is in the correct state.
  795. // Rebuild array of bodies to not apply joint drive to.
  796. NoDriveBodies.length = 0;
  797. for( i=0; i<Mesh.PhysicsAsset.BodySetup.Length; i++)
  798. {
  799. if(Mesh.PhysicsAsset.BodySetup[i].bAlwaysFullAnimWeight)
  800. {
  801. NoDriveBodies.AddItem(Mesh.PhysicsAsset.BodySetup[i].BoneName);
  802. }
  803. }
  804.  
  805. // Reset physics state.
  806. bIsHoverboardAnimPawn = FALSE;
  807. ResetCharPhysState();
  808. }
  809.  
  810. if (!bReceivedValidTeam)
  811. {
  812. SetTeamColor();
  813. bReceivedValidTeam = (GetTeam() != None);
  814. }
  815. }
  816.  
  817. /** Assign an arm mesh and material to this pawn */
  818. simulated function SetFirstPersonArmsInfo(SkeletalMesh FirstPersonArmMesh, MaterialInterface ArmMaterial)
  819. {
  820. // Arms
  821. ArmsMesh[0].SetSkeletalMesh(FirstPersonArmMesh);
  822. ArmsMesh[1].SetSkeletalMesh(FirstPersonArmMesh);
  823.  
  824. SetArmsSkin(ArmMaterial);
  825. }
  826.  
  827. /**
  828. * When a pawn's team is set or replicated, SetTeamColor is called. By default, this will setup
  829. * any required material parameters.
  830. */
  831. simulated function SetTeamColor()
  832. {
  833. local int i;
  834. local UTPlayerReplicationInfo PRI;
  835. local LinearColor LinColor;
  836.  
  837. if ( PlayerReplicationInfo != None )
  838. {
  839. PRI = UTPlayerReplicationInfo(PlayerReplicationInfo);
  840. }
  841. else if ( DrivenVehicle != None )
  842. {
  843. PRI = UTPlayerReplicationInfo(DrivenVehicle.PlayerReplicationInfo);
  844. }
  845. if ( PRI == None )
  846. return;
  847.  
  848. LinColor.A = 1.0;
  849.  
  850. if ( PRI.Team == None )
  851. {
  852. if ( VerifyBodyMaterialInstance() )
  853. {
  854. LinColor.R = 2.0;
  855. LinColor.G = 2.0;
  856.  
  857. for (i = 0; i < BodyMaterialInstances.length; i++)
  858. {
  859. BodyMaterialInstances[i].SetVectorParameterValue('Char_TeamColor', LinColor);
  860. BodyMaterialInstances[i].SetScalarParameterValue('Char_DistSaturateSwitch', 1.0);
  861. }
  862. }
  863. }
  864. else if (VerifyBodyMaterialInstance())
  865. {
  866. if ( PRI.Team.TeamIndex == 0 )
  867. {
  868. LinColor.R = 2.0;
  869. for (i = 0; i < BodyMaterialInstances.length; i++)
  870. {
  871. BodyMaterialInstances[i].SetVectorParameterValue('Char_TeamColor', LinColor);
  872. BodyMaterialInstances[i].SetScalarParameterValue('Char_DistSaturateSwitch', 1.0);
  873. }
  874. }
  875. else
  876. {
  877. LinColor.B = 2.0;
  878. for (i = 0; i < BodyMaterialInstances.length; i++)
  879. {
  880. BodyMaterialInstances[i].SetVectorParameterValue('Char_TeamColor', LinColor);
  881. BodyMaterialInstances[i].SetScalarParameterValue('Char_DistSaturateSwitch', 1.0);
  882. }
  883. }
  884. }
  885. }
  886.  
  887. simulated function PostBeginPlay()
  888. {
  889. local rotator R;
  890. local PlayerController PC;
  891.  
  892. StartedFallingTime = WorldInfo.TimeSeconds;
  893.  
  894. Super.PostBeginPlay();
  895.  
  896. if (!bDeleteMe)
  897. {
  898. if (Mesh != None)
  899. {
  900. BaseTranslationOffset = Mesh.Translation.Z;
  901. CrouchTranslationOffset = Mesh.Translation.Z + CylinderComponent.CollisionHeight - CrouchHeight;
  902. OverlayMesh.SetParentAnimComponent(Mesh);
  903. }
  904.  
  905. bCanDoubleJump = CanMultiJump();
  906.  
  907. // Zero out Pitch and Roll
  908. R.Yaw = Rotation.Yaw;
  909. SetRotation(R);
  910.  
  911. // add to local HUD's post-rendered list
  912. ForEach LocalPlayerControllers(class'PlayerController', PC)
  913. {
  914. if ( PC.MyHUD != None )
  915. {
  916. PC.MyHUD.AddPostRenderedActor(self);
  917. }
  918. }
  919.  
  920. if ( WorldInfo.NetMode != NM_DedicatedServer )
  921. {
  922. UpdateShadowSettings(class'UTPlayerController'.default.PawnShadowMode == SHADOW_All);
  923. }
  924.  
  925. // create a blob shadow on mobile platforms that don't support real shadows
  926. if (WorldInfo.IsConsoleBuild(CONSOLE_Mobile))
  927. {
  928. BlobShadow = new(self) class'StaticMeshComponent';
  929. BlobShadow.SetStaticMesh(StaticMesh'BlobShadow.ShadowMesh');
  930. BlobShadow.SetActorCollision(FALSE, FALSE);
  931. BlobShadow.SetScale(0.2);
  932. BlobShadow.SetRotation(rot(16384, 0, 0));
  933. BlobShadow.SetTranslation(vect(0.0, 0.0, -44.0));
  934. AttachComponent(BlobShadow);
  935. }
  936. }
  937. }
  938.  
  939. simulated function UpdateShadowSettings(bool bWantShadow)
  940. {
  941. local bool bNewCastShadow, bNewCastDynamicShadow;
  942.  
  943. if (Mesh != None)
  944. {
  945. bNewCastShadow = default.Mesh.CastShadow && bWantShadow;
  946. bNewCastDynamicShadow = default.Mesh.bCastDynamicShadow && bWantShadow;
  947. if (bNewCastShadow != Mesh.CastShadow || bNewCastDynamicShadow != Mesh.bCastDynamicShadow)
  948. {
  949. // if there is a pending Attach then this will set the shadow immediately as the flags have changed an a reattached has occurred
  950. Mesh.CastShadow = bNewCastShadow;
  951. Mesh.bCastDynamicShadow = bNewCastDynamicShadow;
  952.  
  953. // defer if we can do so without it being noticeable
  954. if (LastRenderTime < WorldInfo.TimeSeconds - 1.0)
  955. {
  956. SetTimer(0.1 + FRand() * 0.5, false, 'ReattachMesh');
  957. }
  958. else
  959. {
  960. ReattachMesh();
  961. }
  962. }
  963. }
  964. }
  965.  
  966. /** reattaches the mesh component, because settings were updated */
  967. simulated function ReattachMesh()
  968. {
  969. DetachComponent(Mesh);
  970. AttachComponent(Mesh);
  971. EnsureOverlayComponentLast();
  972. }
  973.  
  974. simulated event PostInitAnimTree(SkeletalMeshComponent SkelComp)
  975. {
  976. if (SkelComp == Mesh)
  977. {
  978. LeftLegControl = SkelControlFootPlacement(Mesh.FindSkelControl(LeftFootControlName));
  979. RightLegControl = SkelControlFootPlacement(Mesh.FindSkelControl(RightFootControlName));
  980. FeignDeathBlend = AnimNodeBlend(Mesh.FindAnimNode('FeignDeathBlend'));
  981. FullBodyAnimSlot = AnimNodeSlot(Mesh.FindAnimNode('FullBodySlot'));
  982. TopHalfAnimSlot = AnimNodeSlot(Mesh.FindAnimNode('TopHalfSlot'));
  983.  
  984. LeftHandIK = SkelControlLimb( mesh.FindSkelControl('LeftHandIK') );
  985.  
  986. RightHandIK = SkelControlLimb( mesh.FindSkelControl('RightHandIK') );
  987.  
  988. RootRotControl = SkelControlSingleBone( mesh.FindSkelControl('RootRot') );
  989. AimNode = AnimNodeAimOffset( mesh.FindAnimNode('AimNode') );
  990. GunRecoilNode = GameSkelCtrl_Recoil( mesh.FindSkelControl('GunRecoilNode') );
  991. LeftRecoilNode = GameSkelCtrl_Recoil( mesh.FindSkelControl('LeftRecoilNode') );
  992. RightRecoilNode = GameSkelCtrl_Recoil( mesh.FindSkelControl('RightRecoilNode') );
  993.  
  994. DrivingNode = UTAnimBlendByDriving( mesh.FindAnimNode('DrivingNode') );
  995. VehicleNode = UTAnimBlendByVehicle( mesh.FindAnimNode('VehicleNode') );
  996. HoverboardingNode = UTAnimBlendByHoverboarding( mesh.FindAnimNode('Hoverboarding') );
  997.  
  998. FlyingDirOffset = AnimNodeAimOffset( mesh.FindAnimNode('FlyingDirOffset') );
  999. }
  1000. }
  1001.  
  1002. /** Enable or disable IK that keeps hands on IK bones. */
  1003. simulated function SetHandIKEnabled(bool bEnabled)
  1004. {
  1005. if (WorldInfo.NetMode != NM_DedicatedServer && Mesh.Animations != None)
  1006. {
  1007. if (bEnabled)
  1008. {
  1009. LeftHandIK.SetSkelControlStrength(1.0, 0.0);
  1010. RightHandIK.SetSkelControlStrength(1.0, 0.0);
  1011. }
  1012. else
  1013. {
  1014. LeftHandIK.SetSkelControlStrength(0.0, 0.0);
  1015. RightHandIK.SetSkelControlStrength(0.0, 0.0);
  1016. }
  1017. }
  1018. }
  1019.  
  1020. /** Util for scaling running anims etc. */
  1021. simulated function SetAnimRateScale(float RateScale)
  1022. {
  1023. Mesh.GlobalAnimRateScale = RateScale;
  1024. }
  1025.  
  1026. /** Change the type of weapon animation we are playing. */
  1027. simulated function SetWeapAnimType(EWeapAnimType AnimType)
  1028. {
  1029. if (AimNode != None)
  1030. {
  1031. switch(AnimType)
  1032. {
  1033. case EWAT_Default:
  1034. AimNode.SetActiveProfileByName('Default');
  1035. break;
  1036. case EWAT_Pistol:
  1037. AimNode.SetActiveProfileByName('SinglePistol');
  1038. break;
  1039. case EWAT_DualPistols:
  1040. AimNode.SetActiveProfileByName('DualPistols');
  1041. break;
  1042. case EWAT_ShoulderRocket:
  1043. AimNode.SetActiveProfileByName('ShoulderRocket');
  1044. break;
  1045. case EWAT_Stinger:
  1046. AimNode.SetActiveProfileByName('Stinger');
  1047. break;
  1048. }
  1049. }
  1050. }
  1051.  
  1052. /**
  1053. * This will trace against the world and leave a blood splatter decal.
  1054. *
  1055. * This is used for having a back spray / exit wound blood effect on the wall behind us.
  1056. **/
  1057. simulated function LeaveABloodSplatterDecal( vector HitLoc, vector HitNorm )
  1058. {
  1059. local Actor TraceActor;
  1060. local vector out_HitLocation;
  1061. local vector out_HitNormal;
  1062. local vector TraceDest;
  1063. local vector TraceStart;
  1064. local vector TraceExtent;
  1065. local TraceHitInfo HitInfo;
  1066. local MaterialInstanceTimeVarying MITV_Decal;
  1067.  
  1068. TraceStart = HitLoc;
  1069. HitNorm.Z = 0;
  1070. TraceDest = HitLoc + ( HitNorm * 105 );
  1071.  
  1072. TraceActor = Trace( out_HitLocation, out_HitNormal, TraceDest, TraceStart, false, TraceExtent, HitInfo, TRACEFLAG_PhysicsVolumes );
  1073.  
  1074. if (TraceActor != None && Pawn(TraceActor) == None)
  1075. {
  1076. // we might want to move this to the UTFamilyInfo
  1077. MITV_Decal = new(Outer) class'MaterialInstanceTimeVarying';
  1078. MITV_Decal.SetParent( GetFamilyInfo().default.BloodSplatterDecalMaterial );
  1079.  
  1080. WorldInfo.MyDecalManager.SpawnDecal(MITV_Decal, out_HitLocation, rotator(-out_HitNormal), 100, 100, 50, false,, HitInfo.HitComponent, true, false, HitInfo.BoneName, HitInfo.Item, HitInfo.LevelIndex);
  1081.  
  1082. MITV_Decal.SetScalarStartTime( class'UTGib'.default.DecalDissolveParamName, class'UTGib'.default.DecalWaitTimeBeforeDissolve );
  1083. }
  1084. }
  1085.  
  1086.  
  1087. /**
  1088. * Performs an Emote command. This is typically an action that
  1089. * tells the bots to do something. It is server-side only
  1090. *
  1091. * @Param EInfo The emote we are working with
  1092. * @Param PlayerID The ID of the player this emote is directed at. 255 = All Players
  1093. */
  1094. function PerformEmoteCommand(EmoteInfo EInfo, int PlayerID)
  1095. {
  1096. local array<UTPlayerReplicationInfo> PRIs;
  1097. local UTBot Bot;
  1098. local int i;
  1099. local bool bShouldAck;
  1100. local Controller Sender;
  1101.  
  1102. Sender = Controller;
  1103. if (Sender == None && DrivenVehicle != None)
  1104. {
  1105. Sender = DrivenVehicle.Controller;
  1106. }
  1107. if (Sender != None)
  1108. {
  1109. // If we require a player for this command, look it up
  1110. if ( EInfo.bRequiresPlayer || EInfo.CategoryName == 'Order' )
  1111. {
  1112. // Itterate over the PRI array
  1113. for (i=0;i<WorldInfo.GRI.PRIArray.Length;i++)
  1114. {
  1115. // If we are looking for all players or just this player and it matches
  1116. if (PlayerID == 255 || WorldInfo.GRI.PRIArray[i].PlayerID == PlayerID)
  1117. {
  1118. // Only send to bots
  1119. if ( UTBot(WorldInfo.GRI.PRIArray[i].Owner) != none )
  1120. {
  1121. // If we are on the same team
  1122. if ( WorldInfo.GRI.OnSameTeam(WorldInfo.GRI.PRIArray[i], Sender) )
  1123. {
  1124. PRIs[PRIs.Length] = UTPlayerReplicationInfo(WorldInfo.GRI.PRIArray[i]);
  1125. }
  1126. }
  1127. }
  1128. }
  1129.  
  1130. // Quick out if we didn't find targets
  1131.  
  1132. if ( PRIs.Length == 0 )
  1133. {
  1134. return;
  1135. }
  1136. }
  1137. else // See with our own just to have the loop work
  1138. {
  1139. PRIs[0] = UTPlayerReplicationInfo(PlayerReplicationInfo);
  1140. }
  1141.  
  1142. // Give the command to the bot...
  1143. if ( EInfo.Command != '' )
  1144. {
  1145. bShouldAck = true;
  1146. for (i=0;i<PRIs.Length;i++)
  1147. {
  1148. if ( (PlayerID == 255) || (PRIs[i].PlayerID == PlayerID) )
  1149. {
  1150. Bot = UTBot(PRIs[i].Owner);
  1151. if ( Bot != none )
  1152. {
  1153. //`log("### Command:"@EInfo.Command@"to"@PRIs[i].PlayerName);
  1154. Bot.SetBotOrders(EInfo.Command, Sender, bShouldAck);
  1155. bShouldAck = false;
  1156. if ( PlayerID != 255 )
  1157. {
  1158. break;
  1159. }
  1160. }
  1161. }
  1162. }
  1163. }
  1164. }
  1165. }
  1166.  
  1167.  
  1168. /** Play an emote given a category and index within that category. */
  1169. simulated function DoPlayEmote(name InEmoteTag, int InPlayerID)
  1170. {
  1171. local UTPlayerReplicationInfo UTPRI;
  1172. local class<UTFamilyInfo> FamilyInfo;
  1173. local int EmoteIndex;
  1174. local EmoteInfo EInfo;
  1175.  
  1176. UTPRI = UTPlayerReplicationInfo(PlayerReplicationInfo);
  1177. if (UTPRI == None && DrivenVehicle != None)
  1178. {
  1179. UTPRI = UTPlayerReplicationInfo(DrivenVehicle.PlayerReplicationInfo);
  1180. }
  1181. if(UTPRI != None)
  1182. {
  1183. // Find the family we belong to (if we need to)
  1184. FamilyInfo = GetFamilyInfo();
  1185.  
  1186. EmoteIndex = FamilyInfo.static.GetEmoteIndex(InEmoteTag);
  1187.  
  1188. if (EmoteIndex != INDEX_None)
  1189. {
  1190.  
  1191. EInfo = FamilyInfo.default.FamilyEmotes[EmoteIndex];
  1192.  
  1193. // If on server..
  1194. if (Role == ROLE_Authority)
  1195. {
  1196. // Perform any commands associated with this Emote if authoratitive
  1197. if(EInfo.Command != '')
  1198. {
  1199. PerformEmoteCommand(EInfo, InPlayerID);
  1200. }
  1201. }
  1202.  
  1203. // If this isn't a dedicated server, perform the emote
  1204. if(Health > 0 && WorldInfo.NetMode != NM_DedicatedServer && UTPRI != None && !IsInState('FeigningDeath'))
  1205. {
  1206. // Play the anim in correct slot
  1207. if(EInfo.EmoteAnim != '')
  1208. {
  1209. if(EInfo.bTopHalfEmote || DrivenVehicle != None)
  1210. {
  1211. if(TopHalfAnimSlot != None)
  1212. {
  1213. TopHalfAnimSlot.PlayCustomAnim(EInfo.EmoteAnim, 1.0, 0.2, 0.2, FALSE, TRUE);
  1214. }
  1215. }
  1216. else
  1217. {
  1218. if(FullBodyAnimSlot != None)
  1219. {
  1220. FullBodyAnimSlot.PlayCustomAnim(EInfo.EmoteAnim, 1.0, 0.2, 0.2, FALSE, TRUE);
  1221. }
  1222. }
  1223. }
  1224. }
  1225. }
  1226. }
  1227. }
  1228.  
  1229. reliable server function ServerPlayEmote(name InEmoteTag, int InPlayerID)
  1230. {
  1231. EmoteRepInfo.EmoteTag = InEmoteTag;
  1232. EmoteRepInfo.bNewData = !EmoteRepInfo.bNewData;
  1233. DoPlayEmote(InEmoteTag, InPlayerID);
  1234. LastEmoteTime = WorldInfo.TimeSeconds;
  1235. }
  1236.  
  1237. exec simulated function PlayEmote(name InEmoteTag, int InPlayerID)
  1238. {
  1239. // If it has been long enough since the last emote, play one now
  1240. if(WorldInfo.TimeSeconds - LastEmoteTime > MinTimeBetweenEmotes)
  1241. {
  1242. ServerPlayEmote(InEmoteTag, InPlayerID);
  1243. LastEmoteTime = WorldInfo.TimeSeconds;
  1244. }
  1245. }
  1246.  
  1247. function OnPlayAnim( UTSeqAct_PlayAnim InAction )
  1248. {
  1249. if( FullBodyAnimSlot != None )
  1250. {
  1251. FullBodyAnimSlot.PlayCustomAnim(InAction.AnimName, 1.0, 0.2, 0.2, InAction.bLooping, true);
  1252. }
  1253. }
  1254.  
  1255. function SpawnDefaultController()
  1256. {
  1257. local UTGame Game;
  1258. local UTBot Bot;
  1259. local CharacterInfo EmptyBotInfo;
  1260.  
  1261. Super.SpawnDefaultController();
  1262.  
  1263. Game = UTGame(WorldInfo.Game);
  1264. Bot = UTBot(Controller);
  1265. if (Game != None && Bot != None)
  1266. {
  1267. Game.InitializeBot(Bot, Game.GetBotTeam(), EmptyBotInfo);
  1268. }
  1269. }
  1270.  
  1271. simulated function vector WeaponBob(float BobDamping, float JumpDamping)
  1272. {
  1273. Local Vector WBob;
  1274.  
  1275. WBob = BobDamping * WalkBob;
  1276. WBob.Z = (0.45 + 0.55 * BobDamping)*WalkBob.Z;
  1277. if ( !bWeaponBob )
  1278. {
  1279. WBob *= 2.5;
  1280. }
  1281. WBob.Z += JumpDamping *(LandBob - JumpBob);
  1282. return WBob;
  1283. }
  1284.  
  1285. /** TurnOff()
  1286. Freeze pawn - stop sounds, animations, physics, weapon firing
  1287. */
  1288. simulated function TurnOff()
  1289. {
  1290. super.TurnOff();
  1291. PawnAmbientSound.Stop();
  1292. ClearTimer('FeignDeathDelayTimer');
  1293. }
  1294.  
  1295. //==============
  1296. // Encroachment
  1297. event bool EncroachingOn( actor Other )
  1298. {
  1299. if ( (Vehicle(Other) != None) && (Weapon != None) && Weapon.IsA('UTTranslauncher') )
  1300. return true;
  1301.  
  1302. return Super.EncroachingOn(Other);
  1303. }
  1304.  
  1305. event EncroachedBy(Actor Other)
  1306. {
  1307. local UTPawn P;
  1308.  
  1309. // don't get telefragged by non-vehicle ragdolls and pawns feigning death
  1310. P = UTPawn(Other);
  1311. if (P == None || (!P.IsInState('FeigningDeath') && P.Physics != PHYS_RigidBody))
  1312. {
  1313. Super.EncroachedBy(Other);
  1314. }
  1315. }
  1316.  
  1317. function gibbedBy(actor Other)
  1318. {
  1319. local Pawn P;
  1320.  
  1321. if ( Role < ROLE_Authority )
  1322. return;
  1323.  
  1324. P = Pawn(Other);
  1325. if ( P != None )
  1326. {
  1327. Died(Pawn(Other).Controller, class'UTDmgType_Encroached', Location);
  1328. }
  1329. else
  1330. {
  1331. Died(None, class'UTDmgType_Encroached', Location);
  1332. }
  1333. }
  1334.  
  1335. //Base change - if new base is pawn or decoration, damage based on relative mass and old velocity
  1336. // Also, non-players will jump off pawns immediately
  1337. function JumpOffPawn()
  1338. {
  1339. Super.JumpOffPawn();
  1340. bNoJumpAdjust = true;
  1341. if ( UTBot(Controller) != None )
  1342. UTBot(Controller).SetFall();
  1343. }
  1344.  
  1345. /** Called when pawn cylinder embedded in another pawn. (Collision bug that needs to be fixed).
  1346. */
  1347. event StuckOnPawn(Pawn OtherPawn)
  1348. {
  1349. if( UTPawn(OtherPawn) != None )
  1350. {
  1351. TakeDamage( 10, None,Location, vect(0,0,0) , class'DmgType_Crushed');
  1352. ForceRagdoll();
  1353. }
  1354. }
  1355.  
  1356. event Falling()
  1357. {
  1358. if ( UTBot(Controller) != None )
  1359. UTBot(Controller).SetFall();
  1360. }
  1361.  
  1362. function AddVelocity( vector NewVelocity, vector HitLocation, class<DamageType> DamageType, optional TraceHitInfo HitInfo )
  1363. {
  1364. local bool bRagdoll;
  1365.  
  1366. if (!bIgnoreForces && !IsZero(NewVelocity))
  1367. {
  1368. if (Physics == PHYS_Falling && UTBot(Controller) != None)
  1369. {
  1370. UTBot(Controller).ImpactVelocity += NewVelocity;
  1371. }
  1372.  
  1373. if ( Role == ROLE_Authority && Physics == PHYS_Walking && DrivenVehicle == None && Vehicle(Base) != None
  1374. && VSize(Base.Velocity) > GroundSpeed )
  1375. {
  1376. bRagdoll = true;
  1377. }
  1378.  
  1379. Super.AddVelocity(NewVelocity, HitLocation, DamageType, HitInfo);
  1380.  
  1381. // wait until velocity is applied before sending to ragdoll so that new velocity is used to start the physics
  1382. if (bRagdoll)
  1383. {
  1384. ForceRagdoll();
  1385. }
  1386. }
  1387. }
  1388.  
  1389. function bool Died(Controller Killer, class<DamageType> damageType, vector HitLocation)
  1390. {
  1391. if (Super.Died(Killer, DamageType, HitLocation))
  1392. {
  1393. StartFallImpactTime = WorldInfo.TimeSeconds;
  1394. bCanPlayFallingImpacts=true;
  1395. if(ArmsMesh[0] != none)
  1396. {
  1397. ArmsMesh[0].SetHidden(true);
  1398. }
  1399. if(ArmsMesh[1] != none)
  1400. {
  1401. ArmsMesh[1].SetHidden(true);
  1402. }
  1403. SetPawnAmbientSound(None);
  1404. SetWeaponAmbientSound(None);
  1405. return true;
  1406. }
  1407. return false;
  1408. }
  1409.  
  1410. simulated function StartFire(byte FireModeNum)
  1411. {
  1412. // firing cancels feign death
  1413. if (bFeigningDeath)
  1414. {
  1415. FeignDeath();
  1416. }
  1417. else
  1418. {
  1419. Super.StartFire(FireModeNum);
  1420. }
  1421. }
  1422.  
  1423. function bool StopFiring()
  1424. {
  1425. return StopWeaponFiring();
  1426. }
  1427.  
  1428. function bool BotFire(bool bFinished)
  1429. {
  1430. local UTWeapon Weap;
  1431. local UTBot Bot;
  1432.  
  1433. Weap = UTWeapon(Weapon);
  1434. if (Weap == None || (!Weap.ReadyToFire(bFinished) && !Weap.IsFiring()))
  1435. {
  1436. return false;
  1437. }
  1438.  
  1439. Bot = UTBot(Controller);
  1440. if (Bot != None && Bot.ScriptedFireMode != 255)
  1441. {
  1442. StartFire(Bot.ScriptedFireMode);
  1443. }
  1444. else
  1445. {
  1446. StartFire(ChooseFireMode());
  1447. }
  1448. return true;
  1449. }
  1450.  
  1451. function bool StopWeaponFiring()
  1452. {
  1453. local int i;
  1454. local bool bResult;
  1455. local UTWeapon UTWeap;
  1456.  
  1457. UTWeap = UTWeapon(Weapon);
  1458. if (UTWeap != None)
  1459. {
  1460. UTWeap.ClientEndFire(0);
  1461. UTWeap.ClientEndFire(1);
  1462. UTWeap.ServerStopFire(0);
  1463. UTWeap.ServerStopFire(1);
  1464. bResult = true;
  1465. }
  1466.  
  1467. if (InvManager != None)
  1468. {
  1469. for (i = 0; i < InvManager.GetPendingFireLength(Weapon); i++)
  1470. {
  1471. if( InvManager.IsPendingFire(Weapon, i) )
  1472. {
  1473. bResult = true;
  1474. InvManager.ClearPendingFire(Weapon, i);
  1475. }
  1476. }
  1477. }
  1478.  
  1479. return bResult;
  1480. }
  1481.  
  1482. function byte ChooseFireMode()
  1483. {
  1484. if ( UTWeapon(Weapon) != None )
  1485. {
  1486. return UTWeapon(Weapon).BestMode();
  1487. }
  1488. return 0;
  1489. }
  1490.  
  1491. function bool RecommendLongRangedAttack()
  1492. {
  1493. if ( UTWeapon(Weapon) != None )
  1494. return UTWeapon(Weapon).RecommendLongRangedAttack();
  1495. return false;
  1496. }
  1497.  
  1498.  
  1499. function float RangedAttackTime()
  1500. {
  1501. if ( UTWeapon(Weapon) != None )
  1502. return UTWeapon(Weapon).RangedAttackTime();
  1503. return 0;
  1504. }
  1505.  
  1506. simulated function float GetEyeHeight()
  1507. {
  1508. if ( !IsLocallyControlled() )
  1509. return BaseEyeHeight;
  1510. else
  1511. return EyeHeight;
  1512. }
  1513.  
  1514. function PlayVictoryAnimation()
  1515. {
  1516. ServerPlayEmote(TauntNames[Rand(6)], -1);
  1517. }
  1518.  
  1519. simulated function OnModifyHealth(SeqAct_ModifyHealth Action)
  1520. {
  1521. if( Action.bHeal )
  1522. {
  1523. GiveHealth(Action.Amount, HealthMax);
  1524. }
  1525. else
  1526. {
  1527. Super.OnModifyHealth(Action);
  1528. }
  1529. }
  1530.  
  1531. simulated function string GetScreenName()
  1532. {
  1533. return PlayerReplicationInfo.PlayerName;
  1534. }
  1535.  
  1536. /**
  1537. PostRenderFor()
  1538. Hook to allow pawns to render HUD overlays for themselves.
  1539. Called only if pawn was rendered this tick.
  1540. Assumes that appropriate font has already been set
  1541. @todo FIXMESTEVE - special beacon when speaking (SpeakingBeaconTexture)
  1542. */
  1543. simulated event PostRenderFor(PlayerController PC, Canvas Canvas, vector CameraPosition, vector CameraDir)
  1544. {
  1545. local float TextXL, XL, YL, Dist;
  1546. local vector ScreenLoc;
  1547. local LinearColor TeamColor;
  1548. local Color TextColor;
  1549. local string ScreenName;
  1550. local UTWeapon Weap;
  1551. local UTPlayerReplicationInfo PRI;
  1552. local UTHUDBase HUD;
  1553.  
  1554. screenLoc = Canvas.Project(Location + GetCollisionHeight()*vect(0,0,1));
  1555. // make sure not clipped out
  1556. if (screenLoc.X < 0 ||
  1557. screenLoc.X >= Canvas.ClipX ||
  1558. screenLoc.Y < 0 ||
  1559. screenLoc.Y >= Canvas.ClipY)
  1560. {
  1561. return;
  1562. }
  1563.  
  1564. PRI = UTPlayerReplicationInfo(PlayerReplicationInfo);
  1565. if ( !WorldInfo.GRI.OnSameTeam(self, PC) )
  1566. {
  1567. // maybe change to action music if close enough
  1568. if ( WorldInfo.TimeSeconds - LastPostRenderTraceTime > 0.5 )
  1569. {
  1570. if ( !UTPlayerController(PC).AlreadyInActionMusic() && (VSize(CameraPosition - Location) < VSize(PC.ViewTarget.Location - Location)) && !IsInvisible() )
  1571. {
  1572. // check whether close enough to crosshair
  1573. if ( (Abs(screenLoc.X - 0.5*Canvas.ClipX) < 0.1 * Canvas.ClipX)
  1574. && (Abs(screenLoc.Y - 0.5*Canvas.ClipY) < 0.1 * Canvas.ClipY) )
  1575. {
  1576. // periodically make sure really visible using traces
  1577. if ( FastTrace(Location, CameraPosition,, true)
  1578. || FastTrace(Location+GetCollisionHeight()*vect(0,0,1), CameraPosition,, true) )
  1579. {
  1580. UTPlayerController(PC).ClientMusicEvent(0);;
  1581. }
  1582. }
  1583. }
  1584. LastPostRenderTraceTime = WorldInfo.TimeSeconds + 0.2*FRand();
  1585. }
  1586. return;
  1587. }
  1588.  
  1589. // make sure not behind weapon
  1590. if ( UTPawn(PC.Pawn) != None )
  1591. {
  1592. Weap = UTWeapon(UTPawn(PC.Pawn).Weapon);
  1593. if ( (Weap != None) && Weap.CoversScreenSpace(screenLoc, Canvas) )
  1594. {
  1595. return;
  1596. }
  1597. }
  1598. else if ( (UTVehicle_Hoverboard(PC.Pawn) != None) && UTVehicle_Hoverboard(PC.Pawn).CoversScreenSpace(screenLoc, Canvas) )
  1599. {
  1600. return;
  1601. }
  1602.  
  1603. // periodically make sure really visible using traces
  1604. if ( WorldInfo.TimeSeconds - LastPostRenderTraceTime > 0.5 )
  1605. {
  1606. LastPostRenderTraceTime = WorldInfo.TimeSeconds + 0.2*FRand();
  1607. bPostRenderTraceSucceeded = FastTrace(Location, CameraPosition)
  1608. || FastTrace(Location+GetCollisionHeight()*vect(0,0,1), CameraPosition);
  1609. }
  1610. if ( !bPostRenderTraceSucceeded )
  1611. {
  1612. return;
  1613. }
  1614.  
  1615. class'UTHUD'.Static.GetTeamColor( GetTeamNum(), TeamColor, TextColor);
  1616.  
  1617. Dist = VSize(CameraPosition - Location);
  1618. if ( Dist < TeamBeaconPlayerInfoMaxDist )
  1619. {
  1620. ScreenName = GetScreenName();
  1621. Canvas.StrLen(ScreenName, TextXL, YL);
  1622. XL = Max( TextXL, 24 * Canvas.ClipX/1024 * (1 + 2*Square((TeamBeaconPlayerInfoMaxDist-Dist)/TeamBeaconPlayerInfoMaxDist)));
  1623. }
  1624. else
  1625. {
  1626. XL = Canvas.ClipX * 16 * TeamBeaconPlayerInfoMaxDist/(Dist * 1024);
  1627. YL = 0;
  1628. }
  1629.  
  1630. Class'UTHUD'.static.DrawBackground(ScreenLoc.X-0.7*XL,ScreenLoc.Y-1.8*YL,1.4*XL,1.9*YL, TeamColor, Canvas);
  1631.  
  1632. if ( (PRI != None) && (Dist < TeamBeaconPlayerInfoMaxDist) )
  1633. {
  1634. Canvas.DrawColor = TextColor;
  1635. Canvas.SetPos(ScreenLoc.X-0.5*TextXL,ScreenLoc.Y-1.2*YL);
  1636. Canvas.DrawText( ScreenName, true, , , class'UTHUD'.default.TextRenderInfo );
  1637. }
  1638.  
  1639. HUD = UTHUDBase(PC.MyHUD);
  1640. if ( (HUD != None) && !HUD.bCrosshairOnFriendly
  1641. && (Abs(screenLoc.X - 0.5*Canvas.ClipX) < 0.1 * Canvas.ClipX)
  1642. && (screenLoc.Y <= 0.5*Canvas.ClipY) )
  1643. {
  1644. // check if top to bottom crosses center of screen
  1645. screenLoc = Canvas.Project(Location - GetCollisionHeight()*vect(0,0,1));
  1646. if ( screenLoc.Y >= 0.5*Canvas.ClipY )
  1647. {
  1648. HUD.bCrosshairOnFriendly = true;
  1649. }
  1650. }
  1651. }
  1652.  
  1653.  
  1654. simulated function FaceRotation(rotator NewRotation, float DeltaTime)
  1655. {
  1656. if ( Physics == PHYS_Ladder )
  1657. {
  1658. NewRotation = OnLadder.Walldir;
  1659. }
  1660. else if ( (Physics == PHYS_Walking) || (Physics == PHYS_Falling) )
  1661. {
  1662. NewRotation.Pitch = 0;
  1663. }
  1664. NewRotation.Roll = Rotation.Roll;
  1665. SetRotation(NewRotation);
  1666. }
  1667.  
  1668. /* UpdateEyeHeight()
  1669. * Update player eye position, based on smoothing view while moving up and down stairs, and adding view bobs for landing and taking steps.
  1670. * Called every tick only if bUpdateEyeHeight==true.
  1671. */
  1672. event UpdateEyeHeight( float DeltaTime )
  1673. {
  1674. local float smooth, MaxEyeHeight, OldEyeHeight, Speed2D, OldBobTime;
  1675. local Actor HitActor;
  1676. local vector HitLocation,HitNormal, X, Y, Z;
  1677. local int m,n;
  1678.  
  1679. if ( bTearOff )
  1680. {
  1681. // no eyeheight updates if dead
  1682. EyeHeight = Default.BaseEyeheight;
  1683. bUpdateEyeHeight = false;
  1684. return;
  1685. }
  1686.  
  1687. if ( abs(Location.Z - OldZ) > 15 )
  1688. {
  1689. // if position difference too great, don't do smooth land recovery
  1690. bJustLanded = false;
  1691. bLandRecovery = false;
  1692. }
  1693.  
  1694. if ( !bJustLanded )
  1695. {
  1696. // normal walking around
  1697. // smooth eye position changes while going up/down stairs
  1698. smooth = FMin(0.9, 10.0 * DeltaTime/CustomTimeDilation);
  1699. LandBob *= (1 - smooth);
  1700. if( Physics == PHYS_Walking || Physics==PHYS_Spider || Controller.IsInState('PlayerSwimming') )
  1701. {
  1702. OldEyeHeight = EyeHeight;
  1703. EyeHeight = FMax((EyeHeight - Location.Z + OldZ) * (1 - smooth) + BaseEyeHeight * smooth,
  1704. -0.5 * CylinderComponent.CollisionHeight);
  1705. }
  1706. else
  1707. {
  1708. EyeHeight = EyeHeight * ( 1 - smooth) + BaseEyeHeight * smooth;
  1709. }
  1710. }
  1711. else if ( bLandRecovery )
  1712. {
  1713. // return eyeheight back up to full height
  1714. smooth = FMin(0.9, 9.0 * DeltaTime);
  1715. OldEyeHeight = EyeHeight;
  1716. LandBob *= (1 - smooth);
  1717. // linear interpolation at end
  1718. if ( Eyeheight > 0.9 * BaseEyeHeight )
  1719. {
  1720. Eyeheight = Eyeheight + 0.15*BaseEyeheight*Smooth; // 0.15 = (1-0.75)*0.6
  1721. }
  1722. else
  1723. EyeHeight = EyeHeight * (1 - 0.6*smooth) + BaseEyeHeight*0.6*smooth;
  1724. if ( Eyeheight >= BaseEyeheight)
  1725. {
  1726. bJustLanded = false;
  1727. bLandRecovery = false;
  1728. Eyeheight = BaseEyeheight;
  1729. }
  1730. }
  1731. else
  1732. {
  1733. // drop eyeheight a bit on landing
  1734. smooth = FMin(0.65, 8.0 * DeltaTime);
  1735. OldEyeHeight = EyeHeight;
  1736. EyeHeight = EyeHeight * (1 - 1.5*smooth);
  1737. LandBob += 0.08 * (OldEyeHeight - Eyeheight);
  1738. if ( (Eyeheight < 0.25 * BaseEyeheight + 1) || (LandBob > 2.4) )
  1739. {
  1740. bLandRecovery = true;
  1741. Eyeheight = 0.25 * BaseEyeheight + 1;
  1742. }
  1743. }
  1744.  
  1745. // don't bob if disabled, or just landed
  1746. if( bJustLanded || !bUpdateEyeheight )
  1747. {
  1748. BobTime = 0;
  1749. WalkBob = Vect(0,0,0);
  1750. }
  1751. else
  1752. {
  1753. // add some weapon bob based on jumping
  1754. if ( Velocity.Z > 0 )
  1755. {
  1756. JumpBob = FMax(-1.5, JumpBob - 0.03 * DeltaTime * FMin(Velocity.Z,300));
  1757. }
  1758. else
  1759. {
  1760. JumpBob *= (1 - FMin(1.0, 8.0 * DeltaTime));
  1761. }
  1762.  
  1763. // Add walk bob to movement
  1764. OldBobTime = BobTime;
  1765. Bob = FClamp(Bob, -0.05, 0.05);
  1766.  
  1767. if (Physics == PHYS_Walking )
  1768. {
  1769. GetAxes(Rotation,X,Y,Z);
  1770. Speed2D = VSize(Velocity);
  1771. if ( Speed2D < 10 )
  1772. BobTime += 0.2 * DeltaTime;
  1773. else
  1774. BobTime += DeltaTime * (0.3 + 0.7 * Speed2D/GroundSpeed);
  1775. WalkBob = Y * Bob * Speed2D * sin(8 * BobTime);
  1776. AppliedBob = AppliedBob * (1 - FMin(1, 16 * deltatime));
  1777. WalkBob.Z = AppliedBob;
  1778. if ( Speed2D > 10 )
  1779. WalkBob.Z = WalkBob.Z + 0.75 * Bob * Speed2D * sin(16 * BobTime);
  1780. }
  1781. else if ( Physics == PHYS_Swimming )
  1782. {
  1783. GetAxes(Rotation,X,Y,Z);
  1784. BobTime += DeltaTime;
  1785. Speed2D = Sqrt(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y);
  1786. WalkBob = Y * Bob * 0.5 * Speed2D * sin(4.0 * BobTime);
  1787. WalkBob.Z = Bob * 1.5 * Speed2D * sin(8.0 * BobTime);
  1788. }
  1789. else
  1790. {
  1791. BobTime = 0;
  1792. WalkBob = WalkBob * (1 - FMin(1, 8 * deltatime));
  1793. }
  1794.  
  1795. if ( (Physics == PHYS_Walking) && (VSizeSq(Velocity) > 100) && IsFirstPerson() )
  1796. {
  1797. m = int(0.5 * Pi + 9.0 * OldBobTime/Pi);
  1798. n = int(0.5 * Pi + 9.0 * BobTime/Pi);
  1799.  
  1800. if ( (m != n) && !bIsWalking && !bIsCrouched )
  1801. {
  1802. ActuallyPlayFootStepSound(0);
  1803. }
  1804. }
  1805. if ( !bWeaponBob )
  1806. {
  1807. WalkBob *= 0.1;
  1808. }
  1809. }
  1810. if ( (CylinderComponent.CollisionHeight - Eyeheight < 12) && IsFirstPerson() )
  1811. {
  1812. // desired eye position is above collision box
  1813. // check to make sure that viewpoint doesn't penetrate another actor
  1814. // min clip distance 12
  1815. if (bCollideWorld)
  1816. {
  1817. HitActor = trace(HitLocation,HitNormal, Location + WalkBob + (MaxStepHeight + CylinderComponent.CollisionHeight) * vect(0,0,1),
  1818. Location + WalkBob, true, vect(12,12,12),, TRACEFLAG_Blocking);
  1819. MaxEyeHeight = (HitActor == None) ? CylinderComponent.CollisionHeight + MaxStepHeight : HitLocation.Z - Location.Z;
  1820. Eyeheight = FMin(Eyeheight, MaxEyeHeight);
  1821. }
  1822. }
  1823. }
  1824.  
  1825. /* GetPawnViewLocation()
  1826. Called by PlayerController to determine camera position in first person view. Returns
  1827. the location at which to place the camera
  1828. */
  1829. simulated function Vector GetPawnViewLocation()
  1830. {
  1831. if ( bUpdateEyeHeight )
  1832. return Location + EyeHeight * vect(0,0,1) + WalkBob;
  1833. else
  1834. return Location + BaseEyeHeight * vect(0,0,1);
  1835. }
  1836.  
  1837. /* BecomeViewTarget
  1838. Called by Camera when this actor becomes its ViewTarget */
  1839. simulated event BecomeViewTarget( PlayerController PC )
  1840. {
  1841. local UTPlayerController UTPC;
  1842. local UTWeapon UTWeap;
  1843.  
  1844. Super.BecomeViewTarget(PC);
  1845.  
  1846. if (LocalPlayer(PC.Player) != None)
  1847. {
  1848. PawnAmbientSound.bAllowSpatialization = false;
  1849. WeaponAmbientSound.bAllowSpatialization = false;
  1850.  
  1851. bArmsAttached = true;
  1852. AttachComponent(ArmsMesh[0]);
  1853. UTWeap = UTWeapon(Weapon);
  1854. if (UTWeap != None)
  1855. {
  1856. if (UTWeap.bUsesOffhand)
  1857. {
  1858. AttachComponent(ArmsMesh[1]);
  1859. }
  1860. }
  1861.  
  1862. UTPC = UTPlayerController(PC);
  1863. if (UTPC != None)
  1864. {
  1865. SetMeshVisibility(UTPC.bBehindView);
  1866. }
  1867. else
  1868. {
  1869. SetMeshVisibility(true);
  1870. }
  1871. bUpdateEyeHeight = true;
  1872. }
  1873. }
  1874.  
  1875. /* EndViewTarget
  1876. Called by Camera when this actor becomes its ViewTarget */
  1877. simulated event EndViewTarget( PlayerController PC )
  1878. {
  1879. PawnAmbientSound.bAllowSpatialization = true;
  1880. WeaponAmbientSound.bAllowSpatialization = true;
  1881.  
  1882. if (LocalPlayer(PC.Player) != None)
  1883. {
  1884. SetMeshVisibility(true);
  1885. bArmsAttached=false;
  1886. DetachComponent(ArmsMesh[0]);
  1887. DetachComponent(ArmsMesh[1]);
  1888. }
  1889. }
  1890.  
  1891. simulated function SetWeaponVisibility(bool bWeaponVisible)
  1892. {
  1893. local UTWeapon Weap;
  1894. local AnimNodeSequence WeaponAnimNode, ArmAnimNode;
  1895. local int i;
  1896.  
  1897. Weap = UTWeapon(Weapon);
  1898. if (Weap != None)
  1899. {
  1900. Weap.ChangeVisibility(bWeaponVisible);
  1901.  
  1902. // make the arm animations copy the current weapon anim
  1903. WeaponAnimNode = Weap.GetWeaponAnimNodeSeq();
  1904. if (WeaponAnimNode != None)
  1905. {
  1906. for (i = 0; i < ArrayCount(ArmsMesh); i++)
  1907. {
  1908. if (ArmsMesh[i].bAttached)
  1909. {
  1910. ArmAnimNode = AnimNodeSequence(ArmsMesh[i].Animations);
  1911. if (ArmAnimNode != None)
  1912. {
  1913. ArmAnimNode.SetAnim(WeaponAnimNode.AnimSeqName);
  1914. ArmAnimNode.PlayAnim(WeaponAnimNode.bLooping, WeaponAnimNode.Rate, WeaponAnimNode.CurrentTime);
  1915. }
  1916. }
  1917. }
  1918. }
  1919. }
  1920. }
  1921.  
  1922. simulated function SetWeaponAttachmentVisibility(bool bAttachmentVisible)
  1923. {
  1924. bWeaponAttachmentVisible = bAttachmentVisible;
  1925. if (CurrentWeaponAttachment != None )
  1926. {
  1927. CurrentWeaponAttachment.ChangeVisibility(bAttachmentVisible);
  1928. }
  1929. }
  1930.  
  1931. /** sets whether or not the owner of this pawn can see it */
  1932. simulated function SetMeshVisibility(bool bVisible)
  1933. {
  1934. local UTCarriedObject Flag;
  1935.  
  1936. // Handle the main player mesh
  1937. if (Mesh != None)
  1938. {
  1939. Mesh.SetOwnerNoSee(!bVisible);
  1940. }
  1941.  
  1942. SetOverlayVisibility(bVisible);
  1943.  
  1944. // Handle any weapons they might have
  1945. SetWeaponVisibility(!bVisible);
  1946.  
  1947. // realign any attached flags
  1948. foreach BasedActors(class'UTCarriedObject', Flag)
  1949. {
  1950. HoldGameObject(Flag);
  1951. }
  1952. }
  1953.  
  1954. exec function FixedView(string VisibleMeshes)
  1955. {
  1956. local bool bVisibleMeshes;
  1957. local float fov;
  1958.  
  1959. if (WorldInfo.NetMode == NM_Standalone)
  1960. {
  1961. if (VisibleMeshes != "")
  1962. {
  1963. bVisibleMeshes = ( VisibleMeshes ~= "yes" || VisibleMeshes~="true" || VisibleMeshes~="1" );
  1964.  
  1965. if (VisibleMeshes ~= "default")
  1966. bVisibleMeshes = !IsFirstPerson();
  1967.  
  1968. SetMeshVisibility(bVisibleMeshes);
  1969. }
  1970.  
  1971. if (!bFixedView)
  1972. CalcCamera( 0.0f, FixedViewLoc, FixedViewRot, fov );
  1973.  
  1974. bFixedView = !bFixedView;
  1975. `Log("FixedView:" @ bFixedView);
  1976. }
  1977. }
  1978.  
  1979. function DeactivateSpawnProtection()
  1980. {
  1981. if ( Role < ROLE_Authority )
  1982. return;
  1983. if ( !bSpawnDone )
  1984. {
  1985. bSpawnDone = true;
  1986. if (WorldInfo.TimeSeconds - SpawnTime < UTGame(WorldInfo.Game).SpawnProtectionTime)
  1987. {
  1988. bSpawnIn = true;
  1989. if (BodyMatColor == SpawnProtectionColor)
  1990. {
  1991. ClearBodyMatColor();
  1992. }
  1993. SpawnTime = WorldInfo.TimeSeconds - UTGame(WorldInfo.Game).SpawnProtectionTime - 1;
  1994. }
  1995. SpawnTime = -100000;
  1996. }
  1997. }
  1998.  
  1999. function PlayTeleportEffect(bool bOut, bool bSound)
  2000. {
  2001. local int TeamNum, TransCamIndx;
  2002. local UTPlayerController PC;
  2003.  
  2004. if ( (PlayerReplicationInfo != None) && (PlayerReplicationInfo.Team != None) )
  2005. {
  2006. TeamNum = PlayerReplicationInfo.Team.TeamIndex;
  2007. }
  2008. if ( !bSpawnIn && (WorldInfo.TimeSeconds - SpawnTime < UTGame(WorldInfo.Game).SpawnProtectionTime) )
  2009. {
  2010. bSpawnIn = true;
  2011. SetBodyMatColor( SpawnProtectionColor, UTGame(WorldInfo.Game).SpawnProtectionTime );
  2012. SpawnTransEffect(TeamNum);
  2013. if (bSound)
  2014. {
  2015. PlaySound(SpawnSound);
  2016. }
  2017. }
  2018. else
  2019. {
  2020. SetBodyMatColor( TranslocateColor[TeamNum], 1.0 );
  2021. SpawnTransEffect(TeamNum);
  2022. if (bSound)
  2023. {
  2024. PlaySound(TeleportSound);
  2025. }
  2026. }
  2027.  
  2028. if (bOut)
  2029. {
  2030. PC = UTPlayerController(Controller);
  2031. if (PC != None)
  2032. {
  2033. if ( !WorldInfo.Game.bTeamGame || PlayerReplicationInfo == None || PlayerReplicationInfo.Team == None
  2034. || PlayerReplicationInfo.Team.TeamIndex > 1 )
  2035. {
  2036. TransCamIndx = 2;
  2037. }
  2038. else
  2039. {
  2040. TransCamIndx = TeamNum;
  2041. }
  2042. PC.ClientPlayCameraAnim(TransCameraAnim[TransCamIndx], 1.0f);
  2043. }
  2044. }
  2045. Super.PlayTeleportEffect( bOut, bSound );
  2046. }
  2047.  
  2048. function SpawnTransEffect(int TeamNum)
  2049. {
  2050. if (TransInEffects[0] != None)
  2051. {
  2052. Spawn(TransInEffects[TeamNum],self,,Location + GetCollisionHeight() * vect(0,0,0.75));
  2053. }
  2054. }
  2055.  
  2056. simulated event StartDriving(Vehicle V)
  2057. {
  2058. local UTWeaponPawn WeaponPawn;
  2059. local UTWeapon UTWeap;
  2060. local UDKVehicleBase VBase;
  2061.  
  2062. Super.StartDriving(V);
  2063.  
  2064. DeactivateSpawnProtection();
  2065.  
  2066. UTWeap = UTWeapon(Weapon);
  2067. if (UTWeap != None)
  2068. {
  2069. StopWeaponFiring();
  2070. UTWeap.HolderEnteredVehicle();
  2071. }
  2072.  
  2073. SetWeaponVisibility(false);
  2074. SetWeaponAmbientSound(None);
  2075.  
  2076. SetTeamColor();
  2077.  
  2078. if (Role == ROLE_Authority)
  2079. {
  2080. // if we're driving a UTWeaponPawn, fill in the DrivenWeaponPawn info for remote clients
  2081. WeaponPawn = UTWeaponPawn(V);
  2082. if (WeaponPawn != None && WeaponPawn.MyVehicle != None && WeaponPawn.MySeatIndex != INDEX_NONE)
  2083. {
  2084. DrivenWeaponPawn.BaseVehicle = WeaponPawn.MyVehicle;
  2085. DrivenWeaponPawn.SeatIndex = WeaponPawn.MySeatIndex;
  2086. DrivenWeaponPawn.PRI = PlayerReplicationInfo;
  2087. }
  2088. }
  2089.  
  2090. if (WorldInfo.NetMode != NM_DedicatedServer && WeaponOverlayFlags > 0)
  2091. {
  2092. VBase = UDKVehicleBase(V);
  2093. if (VBase != None)
  2094. {
  2095. VBase.ApplyWeaponEffects(WeaponOverlayFlags);
  2096. }
  2097. }
  2098.  
  2099. if (CurrCharClassInfo != None)
  2100. {
  2101. Mesh.SetScale(CurrCharClassInfo.default.DrivingDrawScale);
  2102. }
  2103. }
  2104.  
  2105. /**
  2106. * StartDriving() and StopDriving() also called on clients
  2107. * on transitions of DrivenVehicle variable.
  2108. * Network: ALL
  2109. */
  2110. simulated event StopDriving(Vehicle V)
  2111. {
  2112. local DrivenWeaponPawnInfo EmptyWeaponPawnInfo;
  2113. local UDKVehicleBase VBase;
  2114.  
  2115. Mesh.SetLightEnvironment(LightEnvironment);
  2116. Mesh.SetScale(DefaultMeshScale);
  2117.  
  2118. // ignore on non-owning client if we still have valid DrivenWeaponPawn
  2119. if (Role < ROLE_Authority && DrivenWeaponPawn.BaseVehicle != None && !IsLocallyControlled())
  2120. {
  2121. // restore DrivenVehicle reference
  2122. DrivenVehicle = ClientSideWeaponPawn;
  2123. }
  2124. else
  2125. {
  2126. if ( (Role == ROLE_Authority) && (PlayerController(Controller) != None) && (UTVehicle(V) != None) )
  2127. UTVehicle(V).PlayerStartTime = WorldInfo.TimeSeconds + 12;
  2128. Super.StopDriving(V);
  2129.  
  2130. // don't allow pawn to double jump on exit (if was jumping when entered)
  2131. MultiJumpRemaining = 0;
  2132.  
  2133. SetWeaponVisibility(IsFirstPerson());
  2134. bIgnoreForces = ( (UTGame(WorldInfo.Game) != None) && UTGame(WorldInfo.Game).bDemoMode && (PlayerController(Controller) != None) );
  2135.  
  2136. if (Role == ROLE_Authority)
  2137. {
  2138. DrivenWeaponPawn = EmptyWeaponPawnInfo;
  2139. }
  2140. }
  2141.  
  2142. if (WorldInfo.NetMode != NM_DedicatedServer)
  2143. {
  2144. VBase = UDKVehicleBase(V);
  2145. if (VBase != None)
  2146. {
  2147. VBase.ApplyWeaponEffects(0);
  2148. }
  2149. }
  2150. }
  2151.  
  2152. simulated function ClientReStart()
  2153. {
  2154. local rotator AdjustedRotation;
  2155.  
  2156. Super.ClientRestart();
  2157.  
  2158. if (Controller != None)
  2159. {
  2160. AdjustedRotation = Controller.Rotation;
  2161. AdjustedRotation.Roll = 0;
  2162. Controller.SetRotation(AdjustedRotation);
  2163. }
  2164. }
  2165.  
  2166. //=============================================================================
  2167. // Armor interface.
  2168.  
  2169. /** GetShieldStrength()
  2170. returns total armor value currently held by this pawn (not including helmet).
  2171. */
  2172. function int GetShieldStrength()
  2173. {
  2174. return ShieldBeltArmor + VestArmor + ThighpadArmor;
  2175. }
  2176.  
  2177. /** AbsorbDamage()
  2178. reduce damage and remove shields based on the absorption rate.
  2179. returns the remaining armor strength.
  2180. */
  2181. function int AbsorbDamage(out int Damage, int CurrentShieldStrength, float AbsorptionRate)
  2182. {
  2183. local int MaxAbsorbedDamage;
  2184.  
  2185. MaxAbsorbedDamage = Min(Damage * AbsorptionRate, CurrentShieldStrength);
  2186. Damage -= MaxAbsorbedDamage;
  2187. return CurrentShieldStrength - MaxAbsorbedDamage;
  2188. }
  2189.  
  2190.  
  2191. /** ShieldAbsorb()
  2192. returns the resultant amount of damage after shields have absorbed what they can
  2193. */
  2194. function int ShieldAbsorb( int Damage )
  2195. {
  2196. if ( Health <= 0 )
  2197. {
  2198. return damage;
  2199. }
  2200.  
  2201. // shield belt absorbs 100% of damage
  2202. if ( ShieldBeltArmor > 0 )
  2203. {
  2204. bShieldAbsorb = true;
  2205. ShieldBeltArmor = AbsorbDamage(Damage, ShieldBeltArmor, 1.0);
  2206. if (ShieldBeltArmor == 0)
  2207. {
  2208. SetOverlayMaterial(None);
  2209. }
  2210. if ( Damage == 0 )
  2211. {
  2212. SetBodyMatColor(SpawnProtectionColor, 1.0);
  2213. PlaySound(ArmorHitSound);
  2214. return 0;
  2215. }
  2216. }
  2217.  
  2218. // vest absorbs 75% of damage
  2219. if ( VestArmor > 0 )
  2220. {
  2221. bShieldAbsorb = true;
  2222. VestArmor = AbsorbDamage(Damage, VestArmor, 0.75);
  2223. if ( Damage == 0 )
  2224. {
  2225. return 0;
  2226. }
  2227. }
  2228.  
  2229. // thighpads absorb 50% of damage
  2230. if ( ThighpadArmor > 0 )
  2231. {
  2232. bShieldAbsorb = true;
  2233. ThighpadArmor = AbsorbDamage(Damage, ThighpadArmor, 0.5);
  2234. if ( Damage == 0 )
  2235. {
  2236. return 0;
  2237. }
  2238. }
  2239.  
  2240. return Damage;
  2241. }
  2242.  
  2243. /* AdjustDamage()
  2244. adjust damage based on inventory, other attributes
  2245. */
  2246. function AdjustDamage(out int InDamage, out vector Momentum, Controller InstigatedBy, vector HitLocation, class<DamageType> DamageType, TraceHitInfo HitInfo, Actor DamageCauser)
  2247. {
  2248. local int PreDamage;
  2249.  
  2250. if ( bIsInvulnerable )
  2251. inDamage = 0;
  2252.  
  2253. if ( UTWeapon(Weapon) != None )
  2254. {
  2255. UTWeapon(Weapon).AdjustPlayerDamage( inDamage, InstigatedBy, HitLocation, Momentum, DamageType );
  2256. }
  2257.  
  2258. if( DamageType.default.bArmorStops && (inDamage > 0) )
  2259. {
  2260. PreDamage = inDamage;
  2261. inDamage = ShieldAbsorb(inDamage);
  2262.  
  2263. // still show damage effect on HUD if damage completely absorbed
  2264. if ( (inDamage == 0) && (Controller != None) )
  2265. {
  2266. Controller.NotifyTakeHit(InstigatedBy, HitLocation, Min(PreDamage,10), DamageType, Momentum);
  2267. }
  2268. }
  2269. }
  2270.  
  2271. //=============================================================================
  2272.  
  2273. function DropFlag()
  2274. {
  2275. local UTPlayerReplicationInfo UTPRI;
  2276.  
  2277. UTPRI = UTPlayerReplicationInfo(PlayerReplicationInfo);
  2278. if ( UTPRI==None || !UTPRI.bHasFlag )
  2279. return;
  2280.  
  2281. UTPRI.GetFlag().Drop();
  2282. bJustDroppedOrb = true;
  2283. }
  2284.  
  2285. /**
  2286. * EnableInventoryPickup()
  2287. * Set bCanPickupInventory to true
  2288. */
  2289. function EnableInventoryPickup()
  2290. {
  2291. bCanPickupInventory = true;
  2292. }
  2293.  
  2294. /**
  2295. * Attach GameObject to mesh.
  2296. * @param GameObj : Game object to hold
  2297. */
  2298. simulated event HoldGameObject(UDKCarriedObject GameObj)
  2299. {
  2300. local UTCarriedObject UTGameObj;
  2301.  
  2302. UTGameObj = UTCarriedObject(GameObj);
  2303. UTGameObj.SetHardAttach(UTGameObj.default.bHardAttach);
  2304. UTGameObj.bIgnoreBaseRotation = UTGameObj.default.bIgnoreBaseRotation;
  2305.  
  2306. if ( class'Engine'.static.IsSplitScreen() )
  2307. {
  2308. if ( UTGameObj.GameObjBone3P != '' )
  2309. {
  2310. UTGameObj.SetBase(self,,Mesh,UTGameObj.GameObjBone3P);
  2311. }
  2312. else
  2313. {
  2314. UTGameObj.SetBase(self);
  2315. }
  2316. UTGameObj.SetRelativeRotation(UTGameObj.GameObjRot3P);
  2317. UTGameObj.SetRelativeLocation(UTGameObj.GameObjOffset3P);
  2318. }
  2319. else if (IsFirstPerson())
  2320. {
  2321. UTGameObj.SetBase(self);
  2322. UTGameObj.SetRelativeRotation(UTGameObj.GameObjRot1P);
  2323. UTGameObj.SetRelativeLocation(UTGameObj.GameObjOffset1P);
  2324. }
  2325. else
  2326. {
  2327. if ( UTGameObj.GameObjBone3P != '' )
  2328. {
  2329. UTGameObj.SetBase(self,,Mesh,UTGameObj.GameObjBone3P);
  2330. }
  2331. else
  2332. {
  2333. UTGameObj.SetBase(self);
  2334. }
  2335. UTGameObj.SetRelativeRotation(UTGameObj.GameObjRot3P);
  2336. UTGameObj.SetRelativeLocation(UTGameObj.GameObjOffset3P);
  2337. }
  2338. }
  2339.  
  2340. function bool GiveHealth(int HealAmount, int HealMax)
  2341. {
  2342. if (Health < HealMax)
  2343. {
  2344. Health = Min(HealMax, Health + HealAmount);
  2345. return true;
  2346. }
  2347. return false;
  2348. }
  2349.  
  2350. /**
  2351. * Overridden to return the actual player name from this Pawn's
  2352. * PlayerReplicationInfo (PRI) if available.
  2353. */
  2354. function String GetDebugName()
  2355. {
  2356. // return the actual player name from the PRI if available
  2357. if (PlayerReplicationInfo != None)
  2358. {
  2359. return "";
  2360. }
  2361. // otherwise return the formatted object name
  2362. return GetItemName(string(self));
  2363. }
  2364.  
  2365. simulated event PlayFootStepSound(int FootDown)
  2366. {
  2367. local PlayerController PC;
  2368.  
  2369. if ( !IsFirstPerson() )
  2370. {
  2371. ForEach LocalPlayerControllers(class'PlayerController', PC)
  2372. {
  2373. if ( (PC.ViewTarget != None) && (VSizeSq(PC.ViewTarget.Location - Location) < MaxFootstepDistSq) )
  2374. {
  2375. ActuallyPlayFootstepSound(FootDown);
  2376. return;
  2377. }
  2378. }
  2379. }
  2380. }
  2381.  
  2382. /**
  2383. * Handles actual playing of sound. Separated from PlayFootstepSound so we can
  2384. * ignore footstep sound notifies in first person.
  2385. */
  2386. simulated function ActuallyPlayFootstepSound(int FootDown)
  2387. {
  2388. local SoundCue FootSound;
  2389.  
  2390. FootSound = SoundGroupClass.static.GetFootstepSound(FootDown, GetMaterialBelowFeet());
  2391. if (FootSound != None)
  2392. {
  2393. PlaySound(FootSound, false, true,,, true);
  2394. }
  2395. }
  2396.  
  2397. simulated function name GetMaterialBelowFeet()
  2398. {
  2399. local vector HitLocation, HitNormal;
  2400. local TraceHitInfo HitInfo;
  2401. local UTPhysicalMaterialProperty PhysicalProperty;
  2402. local actor HitActor;
  2403. local float TraceDist;
  2404.  
  2405. TraceDist = 1.5 * GetCollisionHeight();
  2406.  
  2407. HitActor = Trace(HitLocation, HitNormal, Location - TraceDist*vect(0,0,1), Location, false,, HitInfo, TRACEFLAG_PhysicsVolumes);
  2408. if ( WaterVolume(HitActor) != None )
  2409. {
  2410. return (Location.Z - HitLocation.Z < 0.33*TraceDist) ? 'Water' : 'ShallowWater';
  2411. }
  2412. if (HitInfo.PhysMaterial != None)
  2413. {
  2414. PhysicalProperty = UTPhysicalMaterialProperty(HitInfo.PhysMaterial.GetPhysicalMaterialProperty(class'UTPhysicalMaterialProperty'));
  2415. if (PhysicalProperty != None)
  2416. {
  2417. return PhysicalProperty.MaterialType;
  2418. }
  2419. }
  2420. return '';
  2421.  
  2422. }
  2423.  
  2424. function PlayLandingSound()
  2425. {
  2426. local PlayerController PC;
  2427.  
  2428. ForEach LocalPlayerControllers(class'PlayerController', PC)
  2429. {
  2430. if ( (PC.ViewTarget != None) && (VSizeSq(PC.ViewTarget.Location - Location) < MaxJumpSoundDistSq) )
  2431. {
  2432. PlaySound(SoundGroupClass.static.GetLandSound(GetMaterialBelowFeet()));
  2433. return;
  2434. }
  2435. }
  2436. }
  2437.  
  2438. function PlayJumpingSound()
  2439. {
  2440. local PlayerController PC;
  2441.  
  2442. ForEach LocalPlayerControllers(class'PlayerController', PC)
  2443. {
  2444. if ( (PC.ViewTarget != None) && (VSizeSq(PC.ViewTarget.Location - Location) < MaxJumpSoundDistSq) )
  2445. {
  2446. PlaySound(SoundGroupClass.static.GetJumpSound(GetMaterialBelowFeet()));
  2447. return;
  2448. }
  2449. }
  2450. }
  2451.  
  2452. /** @return whether or not we should gib due to damage from the passed in damagetype */
  2453. simulated function bool ShouldGib(class<UTDamageType> UTDamageType)
  2454. {
  2455. return ( (Mesh != None) && (bTearOffGibs || UTDamageType.Static.ShouldGib(self)) );
  2456. }
  2457.  
  2458. /** spawn a special gib for this pawn's head and sets it as the ViewTarget for any players that were viewing this pawn */
  2459. simulated function SpawnHeadGib(class<UTDamageType> UTDamageType, vector HitLocation)
  2460. {
  2461. local UTGib Gib;
  2462. local UTPlayerController PC;
  2463. local class<UDKEmitCameraEffect> CameraEffect;
  2464. local vector ViewLocation;
  2465. local rotator ViewRotation;
  2466. local PlayerReplicationInfo OldRealViewTarget;
  2467. local class<UTFamilyInfo> FamilyInfo;
  2468.  
  2469. if ( class'UTGame'.Static.UseLowGore(WorldInfo) )
  2470. {
  2471. bHeadGibbed = true;
  2472. return;
  2473. }
  2474.  
  2475. if (!bHeadGibbed)
  2476. {
  2477. // create separate actor for the head so it can bounce around independently
  2478. if ( HitLocation == Location )
  2479. {
  2480. HitLocation = Location + vector(Rotation);
  2481. }
  2482.  
  2483. FamilyInfo = CurrCharClassInfo;
  2484. Gib = SpawnGib(CurrCharClassInfo.default.HeadGib.GibClass, FamilyInfo.default.HeadGib.BoneName, UTDamageType, HitLocation, false);
  2485.  
  2486. if (Gib != None)
  2487. {
  2488. Gib.SetRotation(Rotation);
  2489. Gib.SetTexturesToBeResident( Gib.LifeSpan );
  2490. SetHeadScale(0.f);
  2491. WorldInfo.MyEmitterPool.SpawnEmitter(FamilyInfo.default.HeadShotEffect, Gib.Location, rotator(vect(0,0,1)), Gib);
  2492.  
  2493. foreach LocalPlayerControllers(class'UTPlayerController', PC)
  2494. {
  2495. if (PC.ViewTarget == self)
  2496. {
  2497. // save RealViewTarget for spectating so that this transition doesn't affect it
  2498. OldRealViewTarget = PC.RealViewTarget;
  2499. if (UTDamageType.default.bHeadGibCamera && (PC.UsingFirstPersonCamera() || !PC.IsInState('BaseSpectating')))
  2500. {
  2501. PC.SetViewTarget(Gib);
  2502.  
  2503. CameraEffect = UTDamageType.static.GetDeathCameraEffectVictim(self);
  2504. if (CameraEffect != None)
  2505. {
  2506. PC.ClientSpawnCameraEffect(CameraEffect);
  2507. }
  2508. }
  2509. else
  2510. {
  2511. PC.GetPlayerViewPoint(ViewLocation, ViewRotation);
  2512. PC.SetViewTarget(PC);
  2513. PC.SetLocation(ViewLocation);
  2514. PC.SetRotation(ViewRotation);
  2515. }
  2516. PC.RealViewTarget = OldRealViewTarget;
  2517. }
  2518. }
  2519.  
  2520. bHeadGibbed = true;
  2521. }
  2522. }
  2523. }
  2524.  
  2525. simulated function UTGib SpawnGib(class<UTGib> GibClass, name BoneName, class<UTDamageType> UTDamageType, vector HitLocation, bool bSpinGib)
  2526. {
  2527. local UTGib Gib;
  2528. local rotator SpawnRot;
  2529. local int SavedPitch;
  2530. local float GibPerterbation;
  2531. local rotator VelRotation;
  2532. local vector X, Y, Z;
  2533.  
  2534. SpawnRot = QuatToRotator(Mesh.GetBoneQuaternion(BoneName));
  2535.  
  2536. // @todo fixmesteve temp workaround for gib orientation problem
  2537. SavedPitch = SpawnRot.Pitch;
  2538. SpawnRot.Pitch = SpawnRot.Yaw;
  2539. SpawnRot.Yaw = SavedPitch;
  2540. Gib = Spawn(GibClass, self,, Mesh.GetBoneLocation(BoneName), SpawnRot);
  2541.  
  2542. if ( Gib != None )
  2543. {
  2544. // add initial impulse
  2545. GibPerterbation = UTDamageType.default.GibPerterbation * 32768.0;
  2546. VelRotation = rotator(Gib.Location - HitLocation);
  2547. VelRotation.Pitch += (FRand() * 2.0 * GibPerterbation) - GibPerterbation;
  2548. VelRotation.Yaw += (FRand() * 2.0 * GibPerterbation) - GibPerterbation;
  2549. VelRotation.Roll += (FRand() * 2.0 * GibPerterbation) - GibPerterbation;
  2550. GetAxes(VelRotation, X, Y, Z);
  2551.  
  2552. if (Gib.bUseUnrealPhysics)
  2553. {
  2554. Gib.Velocity = Velocity + Z * (FRand() * 400.0 + 400.0);
  2555. Gib.SetPhysics(PHYS_Falling);
  2556. Gib.RotationRate.Yaw = Rand(100000);
  2557. Gib.RotationRate.Pitch = Rand(100000);
  2558. Gib.RotationRate.Roll = Rand(100000);
  2559. }
  2560. else
  2561. {
  2562. Gib.Velocity = Velocity + Z * (FRand() * 50.0);
  2563. Gib.GibMeshComp.WakeRigidBody();
  2564. Gib.GibMeshComp.SetRBLinearVelocity(Gib.Velocity, false);
  2565. if ( bSpinGib )
  2566. {
  2567. Gib.GibMeshComp.SetRBAngularVelocity(VRand() * 50, false);
  2568. }
  2569. }
  2570.  
  2571. // let damagetype spawn any additional effects
  2572. UTDamageType.static.SpawnGibEffects(Gib);
  2573. Gib.LifeSpan = Gib.LifeSpan + (2.0 * FRand());
  2574. }
  2575.  
  2576. return Gib;
  2577. }
  2578.  
  2579. /** spawns gibs and hides the pawn's mesh */
  2580. simulated function SpawnGibs(class<UTDamageType> UTDamageType, vector HitLocation)
  2581. {
  2582. local int i;
  2583. local bool bSpawnHighDetail;
  2584. local GibInfo MyGibInfo;
  2585.  
  2586. // make sure client gibs me too
  2587. bTearOffGibs = true;
  2588.  
  2589. if ( !bGibbed )
  2590. {
  2591. if ( WorldInfo.NetMode == NM_DedicatedServer )
  2592. {
  2593. bGibbed = true;
  2594. return;
  2595. }
  2596.  
  2597. // play sound
  2598. if(WorldInfo.TimeSeconds - DeathTime < 0.35) // had to have just died to do a death scream.
  2599. {
  2600. SoundGroupClass.static.PlayGibSound(self);
  2601. }
  2602. SoundGroupClass.static.PlayBodyExplosion(self); // the body sounds can go off any time
  2603.  
  2604. SpawnHeadGib(UTDamageType, HitLocation);
  2605.  
  2606. // if we had one of these attached we need to hide it (e.g. headshotted and then gibbed)
  2607. if( HeadshotNeckAttachment != none )
  2608. {
  2609. HeadshotNeckAttachment.SetHidden(true);
  2610. }
  2611.  
  2612. // gib particles
  2613. if (GetFamilyInfo().default.GibExplosionTemplate != None && EffectIsRelevant(Location, false, 7000))
  2614. {
  2615. WorldInfo.MyEmitterPool.SpawnEmitter(GetFamilyInfo().default.GibExplosionTemplate, Location, Rotation);
  2616. // spawn all other gibs
  2617. bSpawnHighDetail = !WorldInfo.bDropDetail && (Worldinfo.TimeSeconds - LastRenderTime < 1);
  2618. for (i = 0; i < CurrCharClassInfo.default.Gibs.length; i++)
  2619. {
  2620. MyGibInfo = CurrCharClassInfo.default.Gibs[i];
  2621.  
  2622. if ( bSpawnHighDetail || !MyGibInfo.bHighDetailOnly )
  2623. {
  2624. SpawnGib(MyGibInfo.GibClass, MyGibInfo.BoneName, UTDamageType, HitLocation, true);
  2625. }
  2626. }
  2627. }
  2628.  
  2629. // if standalone or client, destroy here
  2630. if ( WorldInfo.NetMode != NM_DedicatedServer && !WorldInfo.IsRecordingDemo() &&
  2631. ((WorldInfo.NetMode != NM_ListenServer) || (WorldInfo.Game.NumPlayers + WorldInfo.Game.NumSpectators < 2)) )
  2632. {
  2633. Destroy();
  2634. }
  2635. else
  2636. {
  2637. TurnOffPawn();
  2638. }
  2639.  
  2640. bGibbed = true;
  2641. }
  2642. }
  2643.  
  2644. simulated function TurnOffPawn()
  2645. {
  2646. // hide everything, turn off collision
  2647. if (Physics == PHYS_RigidBody)
  2648. {
  2649. Mesh.SetHasPhysicsAssetInstance(FALSE);
  2650. Mesh.PhysicsWeight = 0.f;
  2651. SetPhysics(PHYS_None);
  2652. }
  2653. if (!IsInState('Dying')) // so we don't restart Begin label and possibly play dying sound again
  2654. {
  2655. GotoState('Dying');
  2656. }
  2657. SetPhysics(PHYS_None);
  2658. SetCollision(false, false);
  2659. //@warning: can't set bHidden - that will make us lose net relevancy to everyone
  2660. Mesh.SetHidden(true);
  2661. if (OverlayMesh != None)
  2662. {
  2663. OverlayMesh.SetHidden(true);
  2664. }
  2665. }
  2666.  
  2667. /**
  2668. * Responsible for playing any death effects, animations, etc.
  2669. *
  2670. * @param DamageType - type of damage responsible for this pawn's death
  2671. *
  2672. * @param HitLoc - location of the final shot
  2673. */
  2674. simulated function PlayDying(class<DamageType> DamageType, vector HitLoc)
  2675. {
  2676. local vector ApplyImpulse, ShotDir;
  2677. local TraceHitInfo HitInfo;
  2678. local PlayerController PC;
  2679. local bool bPlayersRagdoll, bUseHipSpring;
  2680. local class<UTDamageType> UTDamageType;
  2681. local RB_BodyInstance HipBodyInst;
  2682. local int HipBoneIndex;
  2683. local matrix HipMatrix;
  2684. local class<UDKEmitCameraEffect> CameraEffect;
  2685. local name HeadShotSocketName;
  2686. local SkeletalMeshSocket SMS;
  2687.  
  2688. bCanTeleport = false;
  2689. bReplicateMovement = false;
  2690. bTearOff = true;
  2691. bPlayedDeath = true;
  2692. bForcedFeignDeath = false;
  2693. bPlayingFeignDeathRecovery = false;
  2694.  
  2695. HitDamageType = DamageType; // these are replicated to other clients
  2696. TakeHitLocation = HitLoc;
  2697.  
  2698. // make sure I don't have an active weaponattachment
  2699. CurrentWeaponAttachmentClass = None;
  2700. WeaponAttachmentChanged();
  2701.  
  2702. if ( WorldInfo.NetMode == NM_DedicatedServer )
  2703. {
  2704. UTDamageType = class<UTDamageType>(DamageType);
  2705. // tell clients whether to gib
  2706. bTearOffGibs = (UTDamageType != None && ShouldGib(UTDamageType));
  2707. bGibbed = bGibbed || bTearOffGibs;
  2708. GotoState('Dying');
  2709. return;
  2710. }
  2711.  
  2712. // Is this the local player's ragdoll?
  2713. ForEach LocalPlayerControllers(class'PlayerController', PC)
  2714. {
  2715. if( pc.ViewTarget == self )
  2716. {
  2717. if ( UTHud(pc.MyHud)!=none )
  2718. UTHud(pc.MyHud).DisplayHit(HitLoc, 100, DamageType);
  2719. bPlayersRagdoll = true;
  2720. break;
  2721. }
  2722. }
  2723. if ( (WorldInfo.TimeSeconds - LastRenderTime > 3) && !bPlayersRagdoll )
  2724. {
  2725. if (WorldInfo.NetMode == NM_ListenServer || WorldInfo.IsRecordingDemo())
  2726. {
  2727. if (WorldInfo.Game.NumPlayers + WorldInfo.Game.NumSpectators < 2 && !WorldInfo.IsRecordingDemo())
  2728. {
  2729. Destroy();
  2730. return;
  2731. }
  2732. bHideOnListenServer = true;
  2733.  
  2734. // check if should gib (for clients)
  2735. UTDamageType = class<UTDamageType>(DamageType);
  2736. if (UTDamageType != None && ShouldGib(UTDamageType))
  2737. {
  2738. bTearOffGibs = true;
  2739. bGibbed = true;
  2740. }
  2741. TurnOffPawn();
  2742. return;
  2743. }
  2744. else
  2745. {
  2746. // if we were not just controlling this pawn,
  2747. // and it has not been rendered in 3 seconds, just destroy it.
  2748. Destroy();
  2749. return;
  2750. }
  2751. }
  2752.  
  2753. UTDamageType = class<UTDamageType>(DamageType);
  2754. if (UTDamageType != None && !class'UTGame'.static.UseLowGore(WorldInfo) && ShouldGib(UTDamageType))
  2755. {
  2756. SpawnGibs(UTDamageType, HitLoc);
  2757. }
  2758. else
  2759. {
  2760. CheckHitInfo( HitInfo, Mesh, Normal(TearOffMomentum), TakeHitLocation );
  2761.  
  2762. // check to see if we should do a CustomDamage Effect
  2763. if( UTDamageType != None )
  2764. {
  2765. if( UTDamageType.default.bUseDamageBasedDeathEffects )
  2766. {
  2767. UTDamageType.static.DoCustomDamageEffects(self, UTDamageType, HitInfo, TakeHitLocation);
  2768. }
  2769.  
  2770. if( UTPlayerController(PC) != none )
  2771. {
  2772. CameraEffect = UTDamageType.static.GetDeathCameraEffectVictim(self);
  2773. if (CameraEffect != None)
  2774. {
  2775. UTPlayerController(PC).ClientSpawnCameraEffect(CameraEffect);
  2776. }
  2777. }
  2778. }
  2779.  
  2780. bBlendOutTakeHitPhysics = false;
  2781.  
  2782. // Turn off hand IK when dead.
  2783. SetHandIKEnabled(false);
  2784.  
  2785. // if we had some other rigid body thing going on, cancel it
  2786. if (Physics == PHYS_RigidBody)
  2787. {
  2788. //@note: Falling instead of None so Velocity/Acceleration don't get cleared
  2789. setPhysics(PHYS_Falling);
  2790. }
  2791.  
  2792. PreRagdollCollisionComponent = CollisionComponent;
  2793. CollisionComponent = Mesh;
  2794.  
  2795. Mesh.MinDistFactorForKinematicUpdate = 0.f;
  2796.  
  2797. // If we had stopped updating kinematic bodies on this character due to distance from camera, force an update of bones now.
  2798. if( Mesh.bNotUpdatingKinematicDueToDistance )
  2799. {
  2800. Mesh.ForceSkelUpdate();
  2801. Mesh.UpdateRBBonesFromSpaceBases(TRUE, TRUE);
  2802. }
  2803.  
  2804. Mesh.PhysicsWeight = 1.0;
  2805.  
  2806. if(UTDamageType != None && UTDamageType.default.DeathAnim != '' && (FRand() > 0.5) )
  2807. {
  2808. // Don't want to use stop player and use hip-spring if in the air (eg PHYS_Falling)
  2809. if(Physics == PHYS_Walking && UTDamageType.default.bAnimateHipsForDeathAnim)
  2810. {
  2811. SetPhysics(PHYS_None);
  2812. bUseHipSpring=true;
  2813. }
  2814. else
  2815. {
  2816. SetPhysics(PHYS_RigidBody);
  2817. // We only want to turn on 'ragdoll' collision when we are not using a hip spring, otherwise we could push stuff around.
  2818. SetPawnRBChannels(TRUE);
  2819. }
  2820.  
  2821. Mesh.PhysicsAssetInstance.SetAllBodiesFixed(FALSE);
  2822.  
  2823. // Turn on angular motors on skeleton.
  2824. Mesh.bUpdateJointsFromAnimation = TRUE;
  2825. Mesh.PhysicsAssetInstance.SetNamedMotorsAngularPositionDrive(false, false, NoDriveBodies, Mesh, true);
  2826. Mesh.PhysicsAssetInstance.SetAngularDriveScale(1.0f, 1.0f, 0.0f);
  2827.  
  2828. // If desired, turn on hip spring to keep physics character upright
  2829. if(bUseHipSpring)
  2830. {
  2831. HipBodyInst = Mesh.PhysicsAssetInstance.FindBodyInstance('b_Hips', Mesh.PhysicsAsset);
  2832. HipBoneIndex = Mesh.MatchRefBone('b_Hips');
  2833. HipMatrix = Mesh.GetBoneMatrix(HipBoneIndex);
  2834. HipBodyInst.SetBoneSpringParams(DeathHipLinSpring, DeathHipLinDamp, DeathHipAngSpring, DeathHipAngDamp);
  2835. HipBodyInst.bMakeSpringToBaseCollisionComponent = FALSE;
  2836. HipBodyInst.EnableBoneSpring(TRUE, TRUE, HipMatrix);
  2837. HipBodyInst.bDisableOnOverextension = TRUE;
  2838. HipBodyInst.OverextensionThreshold = 100.f;
  2839. }
  2840.  
  2841. FullBodyAnimSlot.PlayCustomAnim(UTDamageType.default.DeathAnim, UTDamageType.default.DeathAnimRate, 0.05, -1.0, false, false);
  2842. SetTimer(0.1, true, 'DoingDeathAnim');
  2843. StartDeathAnimTime = WorldInfo.TimeSeconds;
  2844. TimeLastTookDeathAnimDamage = WorldInfo.TimeSeconds;
  2845. DeathAnimDamageType = UTDamageType;
  2846. }
  2847. else
  2848. {
  2849. SetPhysics(PHYS_RigidBody);
  2850. Mesh.PhysicsAssetInstance.SetAllBodiesFixed(FALSE);
  2851. SetPawnRBChannels(TRUE);
  2852.  
  2853. if( TearOffMomentum != vect(0,0,0) )
  2854. {
  2855. ShotDir = normal(TearOffMomentum);
  2856. ApplyImpulse = ShotDir * DamageType.default.KDamageImpulse;
  2857.  
  2858. // If not moving downwards - give extra upward kick
  2859. if ( Velocity.Z > -10 )
  2860. {
  2861. ApplyImpulse += Vect(0,0,1)*DamageType.default.KDeathUpKick;
  2862. }
  2863. Mesh.AddImpulse(ApplyImpulse, TakeHitLocation, HitInfo.BoneName, true);
  2864. }
  2865. }
  2866. GotoState('Dying');
  2867.  
  2868. if (WorldInfo.NetMode != NM_DedicatedServer && UTDamageType != None && UTDamageType.default.bSeversHead && !bDeleteMe)
  2869. {
  2870. SpawnHeadGib(UTDamageType, HitLoc);
  2871.  
  2872. if ( !class'UTGame'.Static.UseLowGore(WorldInfo) )
  2873. {
  2874. HeadShotSocketName = GetFamilyInfo().default.HeadShotGoreSocketName;
  2875. SMS = Mesh.GetSocketByName( HeadShotSocketName );
  2876. if( SMS != none )
  2877. {
  2878. HeadshotNeckAttachment = new(self) class'StaticMeshComponent';
  2879. HeadshotNeckAttachment.SetActorCollision( FALSE, FALSE );
  2880. HeadshotNeckAttachment.SetBlockRigidBody( FALSE );
  2881.  
  2882. Mesh.AttachComponentToSocket( HeadshotNeckAttachment, HeadShotSocketName );
  2883. HeadshotNeckAttachment.SetStaticMesh( GetFamilyInfo().default.HeadShotNeckGoreAttachment );
  2884. HeadshotNeckAttachment.SetLightEnvironment( LightEnvironment );
  2885. }
  2886. }
  2887. }
  2888. }
  2889. }
  2890.  
  2891. simulated function DoingDeathAnim()
  2892. {
  2893. local RB_BodyInstance HipBodyInst;
  2894. local matrix DummyMatrix;
  2895. local AnimNodeSequence SlotSeqNode;
  2896. local float TimeSinceDeathAnimStart, MotorScale;
  2897. local bool bStopAnim;
  2898.  
  2899.  
  2900. if(DeathAnimDamageType.default.MotorDecayTime != 0.0)
  2901. {
  2902. TimeSinceDeathAnimStart = WorldInfo.TimeSeconds - StartDeathAnimTime;
  2903. MotorScale = 1.0 - (TimeSinceDeathAnimStart/DeathAnimDamageType.default.MotorDecayTime);
  2904.  
  2905. // If motors are scaled to zero, stop death anim
  2906. if(MotorScale <= 0.0)
  2907. {
  2908. bStopAnim = TRUE;
  2909. }
  2910. // If non-zero, scale motor strengths
  2911. else
  2912. {
  2913. Mesh.PhysicsAssetInstance.SetAngularDriveScale(MotorScale, MotorScale, 0.0f);
  2914. }
  2915. }
  2916.  
  2917. // If we want to stop animation after a certain
  2918. if( DeathAnimDamageType != None &&
  2919. DeathAnimDamageType.default.StopAnimAfterDamageInterval != 0.0 &&
  2920. (WorldInfo.TimeSeconds - TimeLastTookDeathAnimDamage) > DeathAnimDamageType.default.StopAnimAfterDamageInterval )
  2921. {
  2922. bStopAnim = TRUE;
  2923. }
  2924.  
  2925.  
  2926. // If done playing custom death anim - turn off bone motors.
  2927. SlotSeqNode = AnimNodeSequence(FullBodyAnimSlot.Children[1].Anim);
  2928. if(!SlotSeqNode.bPlaying || bStopAnim)
  2929. {
  2930. SetPhysics(PHYS_RigidBody);
  2931. Mesh.PhysicsAssetInstance.SetAllMotorsAngularPositionDrive(false, false);
  2932. HipBodyInst = Mesh.PhysicsAssetInstance.FindBodyInstance('b_Hips', Mesh.PhysicsAsset);
  2933. HipBodyInst.EnableBoneSpring(FALSE, FALSE, DummyMatrix);
  2934.  
  2935. // Ensure we have ragdoll collision on at this point
  2936. SetPawnRBChannels(TRUE);
  2937.  
  2938. ClearTimer('DoingDeathAnim');
  2939. DeathAnimDamageType = None;
  2940. }
  2941. }
  2942.  
  2943. simulated event Destroyed()
  2944. {
  2945. local PlayerController PC;
  2946. local Actor A;
  2947.  
  2948. Super.Destroyed();
  2949.  
  2950. foreach BasedActors(class'Actor', A)
  2951. {
  2952. A.PawnBaseDied();
  2953. }
  2954.  
  2955. // remove from local HUD's post-rendered list
  2956. ForEach LocalPlayerControllers(class'PlayerController', PC)
  2957. {
  2958. if ( PC.MyHUD != None )
  2959. {
  2960. PC.MyHUD.RemovePostRenderedActor(self);
  2961. }
  2962. }
  2963.  
  2964. if (CurrentWeaponAttachment != None)
  2965. {
  2966. CurrentWeaponAttachment.DetachFrom(Mesh);
  2967. CurrentWeaponAttachment.Destroy();
  2968. }
  2969. }
  2970.  
  2971.  
  2972. function AddDefaultInventory()
  2973. {
  2974. Controller.ClientSwitchToBestWeapon();
  2975. }
  2976.  
  2977. /**
  2978. * Calculate camera view point, when viewing this pawn.
  2979. *
  2980. * @param fDeltaTime delta time seconds since last update
  2981. * @param out_CamLoc Camera Location
  2982. * @param out_CamRot Camera Rotation
  2983. * @param out_FOV Field of View
  2984. *
  2985. * @return true if Pawn should provide the camera point of view.
  2986. */
  2987. simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV )
  2988. {
  2989. // Handle the fixed camera
  2990.  
  2991. if (bFixedView)
  2992. {
  2993. out_CamLoc = FixedViewLoc;
  2994. out_CamRot = FixedViewRot;
  2995. }
  2996. else
  2997. {
  2998. if ( !IsFirstPerson() ) // Handle BehindView
  2999. {
  3000. CalcThirdPersonCam(fDeltaTime, out_CamLoc, out_CamRot, out_FOV);
  3001. }
  3002. else
  3003. {
  3004. // By default, we view through the Pawn's eyes..
  3005. GetActorEyesViewPoint( out_CamLoc, out_CamRot );
  3006. }
  3007.  
  3008. if ( UTWeapon(Weapon) != none)
  3009. {
  3010. UTWeapon(Weapon).WeaponCalcCamera(fDeltaTime, out_CamLoc, out_CamRot);
  3011. }
  3012. }
  3013.  
  3014. return true;
  3015. }
  3016.  
  3017. simulated function SetThirdPersonCamera(bool bNewBehindView)
  3018. {
  3019. if ( bNewBehindView )
  3020. {
  3021. CurrentCameraScale = 1.0;
  3022. CameraZOffset = GetCollisionHeight() + Mesh.Translation.Z;
  3023. }
  3024. SetMeshVisibility(bNewBehindView);
  3025. }
  3026.  
  3027.  
  3028. /** Used by PlayerController.FindGoodView() in RoundEnded State */
  3029. simulated function FindGoodEndView(PlayerController InPC, out Rotator GoodRotation)
  3030. {
  3031. local rotator ViewRotation;
  3032. local int tries;
  3033. local float bestdist, newdist;
  3034. local UTPlayerController PC;
  3035.  
  3036. PC = UTPlayerController(InPC);
  3037.  
  3038. bWinnerCam = true;
  3039. SetHeroCam(GoodRotation);
  3040. GoodRotation.Pitch = HeroCameraPitch;
  3041. ViewRotation = GoodRotation;
  3042. ViewRotation.Yaw = Rotation.Yaw + 32768 + 8192;
  3043. if ( TryNewCamRot(PC, ViewRotation, newdist) )
  3044. {
  3045. GoodRotation = ViewRotation;
  3046. return;
  3047. }
  3048.  
  3049. ViewRotation = GoodRotation;
  3050. ViewRotation.Yaw = Rotation.Yaw + 32768 - 8192;
  3051. if ( TryNewCamRot(PC, ViewRotation, newdist) )
  3052. {
  3053. GoodRotation = ViewRotation;
  3054. return;
  3055. }
  3056.  
  3057. // failed with Hero cam
  3058. ViewRotation.Pitch = 56000;
  3059. tries = 0;
  3060. bestdist = 0.0;
  3061. CameraScale = Default.CameraScale;
  3062. CurrentCameraScale = Default.CameraScale;
  3063. for (tries=0; tries<16; tries++)
  3064. {
  3065. if ( TryNewCamRot(PC, ViewRotation, newdist) )
  3066. {
  3067. GoodRotation = ViewRotation;
  3068. return;
  3069. }
  3070.  
  3071. if (newdist > bestdist)
  3072. {
  3073. bestdist = newdist;
  3074. GoodRotation = ViewRotation;
  3075. }
  3076. ViewRotation.Yaw += 4096;
  3077. }
  3078. }
  3079.  
  3080. simulated function bool TryNewCamRot(UTPlayerController PC, rotator ViewRotation, out float CamDist)
  3081. {
  3082. local vector cameraLoc;
  3083. local rotator cameraRot;
  3084. local float FOVAngle;
  3085.  
  3086. cameraLoc = Location;
  3087. cameraRot = ViewRotation;
  3088. if ( CalcThirdPersonCam(0, cameraLoc, cameraRot, FOVAngle) )
  3089. {
  3090. CamDist = VSize(cameraLoc - Location - vect(0,0,1)*CameraZOffset);
  3091. return true;
  3092. }
  3093. CamDist = VSize(cameraLoc - Location - vect(0,0,1)*CameraZOffset);
  3094. return false;
  3095. }
  3096.  
  3097. simulated function SetHeroCam(out rotator out_CamRot)
  3098. {
  3099. CameraZOffset = 0.0;
  3100. CameraScale = HeroCameraScale;
  3101. CurrentCameraScale = HeroCameraScale;
  3102. }
  3103.  
  3104. simulated function bool CalcThirdPersonCam( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV )
  3105. {
  3106. local vector CamStart, HitLocation, HitNormal, CamDirX, CamDirY, CamDirZ, CurrentCamOffset;
  3107. local float DesiredCameraZOffset;
  3108.  
  3109. ModifyRotForDebugFreeCam(out_CamRot);
  3110.  
  3111. CamStart = Location;
  3112. CurrentCamOffset = CamOffset;
  3113.  
  3114. if ( bWinnerCam )
  3115. {
  3116. // use "hero" cam
  3117. SetHeroCam(out_CamRot);
  3118. CurrentCamOffset = vect(0,0,0);
  3119. CurrentCamOffset.X = GetCollisionRadius();
  3120. }
  3121. else
  3122. {
  3123. DesiredCameraZOffset = (Health > 0) ? 1.2 * GetCollisionHeight() + Mesh.Translation.Z : 0.f;
  3124. CameraZOffset = (fDeltaTime < 0.2) ? DesiredCameraZOffset * 5 * fDeltaTime + (1 - 5*fDeltaTime) * CameraZOffset : DesiredCameraZOffset;
  3125. if ( Health <= 0 )
  3126. {
  3127. CurrentCamOffset = vect(0,0,0);
  3128. CurrentCamOffset.X = GetCollisionRadius();
  3129. }
  3130. }
  3131. CamStart.Z += CameraZOffset;
  3132. GetAxes(out_CamRot, CamDirX, CamDirY, CamDirZ);
  3133. CamDirX *= CurrentCameraScale;
  3134.  
  3135. if ( (Health <= 0) || bFeigningDeath )
  3136. {
  3137. // adjust camera position to make sure it's not clipping into world
  3138. // @todo fixmesteve. Note that you can still get clipping if FindSpot fails (happens rarely)
  3139. FindSpot(GetCollisionExtent(),CamStart);
  3140. }
  3141. if (CurrentCameraScale < CameraScale)
  3142. {
  3143. CurrentCameraScale = FMin(CameraScale, CurrentCameraScale + 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*fDeltaTime);
  3144. }
  3145. else if (CurrentCameraScale > CameraScale)
  3146. {
  3147. CurrentCameraScale = FMax(CameraScale, CurrentCameraScale - 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*fDeltaTime);
  3148. }
  3149. if (CamDirX.Z > GetCollisionHeight())
  3150. {
  3151. CamDirX *= square(cos(out_CamRot.Pitch * 0.0000958738)); // 0.0000958738 = 2*PI/65536
  3152. }
  3153. out_CamLoc = CamStart - CamDirX*CurrentCamOffset.X + CurrentCamOffset.Y*CamDirY + CurrentCamOffset.Z*CamDirZ;
  3154. if (Trace(HitLocation, HitNormal, out_CamLoc, CamStart, false, vect(12,12,12)) != None)
  3155. {
  3156. out_CamLoc = HitLocation;
  3157. return false;
  3158. }
  3159. return true;
  3160. }
  3161.  
  3162. /**
  3163. * Return world location to start a weapon fire trace from.
  3164. *
  3165. * @return World location where to start weapon fire traces from
  3166. */
  3167. simulated function Vector GetWeaponStartTraceLocation(optional Weapon CurrentWeapon)
  3168. {
  3169. return GetPawnViewLocation();
  3170. }
  3171.  
  3172. //=============================================
  3173. // Jumping functionality
  3174.  
  3175. function bool Dodge(eDoubleClickDir DoubleClickMove)
  3176. {
  3177. local vector X,Y,Z, TraceStart, TraceEnd, Dir, Cross, HitLocation, HitNormal;
  3178. local Actor HitActor;
  3179. local rotator TurnRot;
  3180.  
  3181. if ( bIsCrouched || bWantsToCrouch || (Physics != PHYS_Walking && Physics != PHYS_Falling) )
  3182. return false;
  3183.  
  3184. TurnRot.Yaw = Rotation.Yaw;
  3185. GetAxes(TurnRot,X,Y,Z);
  3186.  
  3187. if ( Physics == PHYS_Falling )
  3188. {
  3189. if (DoubleClickMove == DCLICK_Forward)
  3190. TraceEnd = -X;
  3191. else if (DoubleClickMove == DCLICK_Back)
  3192. TraceEnd = X;
  3193. else if (DoubleClickMove == DCLICK_Left)
  3194. TraceEnd = Y;
  3195. else if (DoubleClickMove == DCLICK_Right)
  3196. TraceEnd = -Y;
  3197. TraceStart = Location - (CylinderComponent.CollisionHeight - 16)*Vect(0,0,1) + TraceEnd*(CylinderComponent.CollisionRadius-16);
  3198. TraceEnd = TraceStart + TraceEnd*40.0;
  3199. HitActor = Trace(HitLocation, HitNormal, TraceEnd, TraceStart, false, vect(16,16,16));
  3200.  
  3201. if ( (HitActor == None) || (HitNormal.Z < -0.1) )
  3202. return false;
  3203. if ( !HitActor.bWorldGeometry )
  3204. {
  3205. if ( !HitActor.bBlockActors )
  3206. return false;
  3207. if ( (Pawn(HitActor) != None) && (Vehicle(HitActor) == None) )
  3208. return false;
  3209. }
  3210. }
  3211. if (DoubleClickMove == DCLICK_Forward)
  3212. {
  3213. Dir = X;
  3214. Cross = Y;
  3215. }
  3216. else if (DoubleClickMove == DCLICK_Back)
  3217. {
  3218. Dir = -1 * X;
  3219. Cross = Y;
  3220. }
  3221. else if (DoubleClickMove == DCLICK_Left)
  3222. {
  3223. Dir = -1 * Y;
  3224. Cross = X;
  3225. }
  3226. else if (DoubleClickMove == DCLICK_Right)
  3227. {
  3228. Dir = Y;
  3229. Cross = X;
  3230. }
  3231. if ( AIController(Controller) != None )
  3232. Cross = vect(0,0,0);
  3233. return PerformDodge(DoubleClickMove, Dir,Cross);
  3234. }
  3235.  
  3236. /* BotDodge()
  3237. returns appropriate vector for dodge in direction Dir (which should be normalized)
  3238. */
  3239. function vector BotDodge(Vector Dir)
  3240. {
  3241. local vector Vel;
  3242.  
  3243. Vel = DodgeSpeed*Dir;
  3244. Vel.Z = DodgeSpeedZ;
  3245. return Vel;
  3246. }
  3247.  
  3248. function bool PerformDodge(eDoubleClickDir DoubleClickMove, vector Dir, vector Cross)
  3249. {
  3250. local float VelocityZ;
  3251.  
  3252. if ( Physics == PHYS_Falling )
  3253. {
  3254. TakeFallingDamage();
  3255. }
  3256.  
  3257. bDodging = true;
  3258. bReadyToDoubleJump = (JumpBootCharge > 0);
  3259. VelocityZ = Velocity.Z;
  3260. Velocity = DodgeSpeed*Dir + (Velocity Dot Cross)*Cross;
  3261.  
  3262. if ( VelocityZ < -200 )
  3263. Velocity.Z = VelocityZ + DodgeSpeedZ;
  3264. else
  3265. Velocity.Z = DodgeSpeedZ;
  3266.  
  3267. CurrentDir = DoubleClickMove;
  3268. SetPhysics(PHYS_Falling);
  3269. SoundGroupClass.Static.PlayDodgeSound(self);
  3270. return true;
  3271. }
  3272.  
  3273. function DoDoubleJump( bool bUpdating )
  3274. {
  3275. if ( !bIsCrouched && !bWantsToCrouch )
  3276. {
  3277. if ( !IsLocallyControlled() || AIController(Controller) != None )
  3278. {
  3279. MultiJumpRemaining -= 1;
  3280. }
  3281. Velocity.Z = JumpZ + MultiJumpBoost;
  3282. UTInventoryManager(InvManager).OwnerEvent('MultiJump');
  3283. SetPhysics(PHYS_Falling);
  3284. BaseEyeHeight = DoubleJumpEyeHeight;
  3285. if (!bUpdating)
  3286. {
  3287. SoundGroupClass.Static.PlayDoubleJumpSound(self);
  3288. }
  3289. }
  3290. }
  3291.  
  3292. function Gasp()
  3293. {
  3294. SoundGroupClass.Static.PlayGaspSound(self);
  3295. }
  3296.  
  3297.  
  3298. /** Flying support */
  3299. simulated function StartFlying();
  3300. simulated function StopFlying();
  3301.  
  3302. function bool DoJump( bool bUpdating )
  3303. {
  3304. // This extra jump allows a jumping or dodging pawn to jump again mid-air
  3305. // (via thrusters). The pawn must be within +/- DoubleJumpThreshold velocity units of the
  3306. // apex of the jump to do this special move.
  3307. if ( !bUpdating && CanDoubleJump()&& (Abs(Velocity.Z) < DoubleJumpThreshold) && IsLocallyControlled() )
  3308. {
  3309. if ( PlayerController(Controller) != None )
  3310. PlayerController(Controller).bDoubleJump = true;
  3311. DoDoubleJump(bUpdating);
  3312. MultiJumpRemaining -= 1;
  3313. return true;
  3314. }
  3315.  
  3316. if (bJumpCapable && !bIsCrouched && !bWantsToCrouch && (Physics == PHYS_Walking || Physics == PHYS_Ladder || Physics == PHYS_Spider))
  3317. {
  3318. if ( Physics == PHYS_Spider )
  3319. Velocity = JumpZ * Floor;
  3320. else if ( Physics == PHYS_Ladder )
  3321. Velocity.Z = 0;
  3322. else if ( bIsWalking )
  3323. Velocity.Z = Default.JumpZ;
  3324. else
  3325. Velocity.Z = JumpZ;
  3326. if (Base != None && !Base.bWorldGeometry && Base.Velocity.Z > 0.f)
  3327. {
  3328. if ( (WorldInfo.WorldGravityZ != WorldInfo.DefaultGravityZ) && (GetGravityZ() == WorldInfo.WorldGravityZ) )
  3329. {
  3330. Velocity.Z += Base.Velocity.Z * sqrt(GetGravityZ()/WorldInfo.DefaultGravityZ);
  3331. }
  3332. else
  3333. {
  3334. Velocity.Z += Base.Velocity.Z;
  3335. }
  3336. }
  3337. SetPhysics(PHYS_Falling);
  3338. bReadyToDoubleJump = true;
  3339. bDodging = false;
  3340. if ( !bUpdating )
  3341. PlayJumpingSound();
  3342. return true;
  3343. }
  3344. return false;
  3345. }
  3346.  
  3347. event Landed(vector HitNormal, actor FloorActor)
  3348. {
  3349. local vector Impulse;
  3350.  
  3351. Super.Landed(HitNormal, FloorActor);
  3352.  
  3353. // adds impulses to vehicles and dynamicSMActors (e.g. KActors)
  3354. Impulse.Z = Velocity.Z * 4.0f; // 4.0f works well for landing on a Scorpion
  3355. if (UTVehicle(FloorActor) != None)
  3356. {
  3357. UTVehicle(FloorActor).Mesh.AddImpulse(Impulse, Location);
  3358. }
  3359. else if (DynamicSMActor(FloorActor) != None)
  3360. {
  3361. DynamicSMActor(FloorActor).StaticMeshComponent.AddImpulse(Impulse, Location);
  3362. }
  3363.  
  3364. if ( Velocity.Z < -200 )
  3365. {
  3366. OldZ = Location.Z;
  3367. bJustLanded = bUpdateEyeHeight && (Controller != None) && Controller.LandingShake();
  3368. }
  3369.  
  3370. if (UTInventoryManager(InvManager) != None)
  3371. {
  3372. UTInventoryManager(InvManager).OwnerEvent('Landed');
  3373. }
  3374. if ((MultiJumpRemaining < MaxMultiJump && bStopOnDoubleLanding) || bDodging || Velocity.Z < -2 * JumpZ)
  3375. {
  3376. // slow player down if double jump landing
  3377. Velocity.X *= 0.1;
  3378. Velocity.Y *= 0.1;
  3379. }
  3380.  
  3381. AirControl = DefaultAirControl;
  3382. MultiJumpRemaining = MaxMultiJump;
  3383. bDodging = false;
  3384. bReadyToDoubleJump = false;
  3385. if (UTBot(Controller) != None)
  3386. {
  3387. UTBot(Controller).ImpactVelocity = vect(0,0,0);
  3388. }
  3389.  
  3390. if(!bHidden)
  3391. {
  3392. PlayLandingSound();
  3393. }
  3394. if (Velocity.Z < -MaxFallSpeed)
  3395. {
  3396. SoundGroupClass.Static.PlayFallingDamageLandSound(self);
  3397. }
  3398. else if (Velocity.Z < MaxFallSpeed * -0.5)
  3399. {
  3400. SoundGroupClass.Static.PlayLandSound(self);
  3401. }
  3402.  
  3403. SetBaseEyeheight();
  3404. }
  3405.  
  3406. function JumpOutOfWater(vector jumpDir)
  3407. {
  3408. bReadyToDoubleJump = true;
  3409. bDodging = false;
  3410. Falling();
  3411. Velocity = jumpDir * WaterSpeed;
  3412. Acceleration = jumpDir * AccelRate;
  3413. velocity.Z = OutofWaterZ; //set here so physics uses this for remainder of tick
  3414. bUpAndOut = true;
  3415. }
  3416.  
  3417. function bool CanDoubleJump()
  3418. {
  3419. return ( (MultiJumpRemaining > 0) && (Physics == PHYS_Falling) && (bReadyToDoubleJump || (UTBot(Controller) != None)) );
  3420. }
  3421.  
  3422. function bool CanMultiJump()
  3423. {
  3424. return ( MaxMultiJump > 0 );
  3425. }
  3426.  
  3427. function PlayDyingSound()
  3428. {
  3429. SoundGroupClass.Static.PlayDyingSound(self);
  3430. }
  3431.  
  3432. simulated function DisplayDebug(HUD HUD, out float out_YL, out float out_YPos)
  3433. {
  3434. local int i,j;
  3435. local PrimitiveComponent P;
  3436. local string s;
  3437. local float xl,yl;
  3438.  
  3439. Super.DisplayDebug(HUD, out_YL, out_YPos);
  3440.  
  3441. if (HUD.ShouldDisplayDebug('twist'))
  3442. {
  3443. Hud.Canvas.SetDrawColor(255,255,200);
  3444. Hud.Canvas.SetPos(4,out_YPos);
  3445. Hud.Canvas.DrawText(""$Self$" - "@Rotation@" RootYaw:"@RootYaw@" CurrentSkelAim"@CurrentSkelAim.X@CurrentSkelAim.Y);
  3446. out_YPos += out_YL;
  3447. }
  3448.  
  3449. if ( !HUD.ShouldDisplayDebug('component') )
  3450. return;
  3451.  
  3452. Hud.Canvas.SetDrawColor(255,255,128,255);
  3453.  
  3454. for (i=0;i<Mesh.Attachments.Length;i++)
  3455. {
  3456. HUD.Canvas.SetPos(4,out_YPos);
  3457.  
  3458. s = ""$Mesh.Attachments[i].Component;
  3459. Hud.Canvas.Strlen(s,xl,yl);
  3460. j = len(s);
  3461. while ( xl > (Hud.Canvas.ClipX*0.5) && j>10)
  3462. {
  3463. j--;
  3464. s = Right(S,j);
  3465. Hud.Canvas.StrLen(s,xl,yl);
  3466. }
  3467.  
  3468. HUD.Canvas.DrawText("Attachment"@i@" = "@Mesh.Attachments[i].BoneName@s);
  3469. out_YPos += out_YL;
  3470.  
  3471. P = PrimitiveComponent(Mesh.Attachments[i].Component);
  3472. if (P!=None)
  3473. {
  3474. HUD.Canvas.SetPos(24,out_YPos);
  3475. HUD.Canvas.DrawText("Component = "@P.Owner@P.HiddenGame@P.bOnlyOwnerSee@P.bOwnerNoSee);
  3476. out_YPos += out_YL;
  3477.  
  3478. s = ""$P;
  3479. Hud.Canvas.Strlen(s,xl,yl);
  3480. j = len(s);
  3481. while ( xl > (Hud.Canvas.ClipX*0.5) && j>10)
  3482. {
  3483. j--;
  3484. s = Right(S,j);
  3485. Hud.Canvas.StrLen(s,xl,yl);
  3486. }
  3487.  
  3488. HUD.Canvas.SetPos(24,out_YPos);
  3489. HUD.Canvas.DrawText("Component = "@s);
  3490. out_YPos += out_YL;
  3491. }
  3492. }
  3493.  
  3494. out_YPos += out_YL*2;
  3495. HUD.Canvas.SetPos(24,out_YPos);
  3496. HUD.Canvas.DrawText("Driven Vehicle = "@DrivenVehicle);
  3497. out_YPos += out_YL;
  3498. }
  3499.  
  3500. /** starts playing the given sound via the PawnAmbientSound AudioComponent and sets PawnAmbientSoundCue for replicating to clients
  3501. * @param NewAmbientSound the new sound to play, or None to stop any ambient that was playing
  3502. */
  3503. simulated function SetPawnAmbientSound(SoundCue NewAmbientSound)
  3504. {
  3505. // if the component is already playing this sound, don't restart it
  3506. if (NewAmbientSound != PawnAmbientSound.SoundCue)
  3507. {
  3508. PawnAmbientSoundCue = NewAmbientSound;
  3509. PawnAmbientSound.Stop();
  3510. PawnAmbientSound.SoundCue = NewAmbientSound;
  3511. if (NewAmbientSound != None)
  3512. {
  3513. PawnAmbientSound.Play();
  3514. }
  3515. }
  3516. }
  3517.  
  3518. simulated function SoundCue GetPawnAmbientSound()
  3519. {
  3520. return PawnAmbientSoundCue;
  3521. }
  3522.  
  3523. /** starts playing the given sound via the WeaponAmbientSound AudioComponent and sets WeaponAmbientSoundCue for replicating to clients
  3524. * @param NewAmbientSound the new sound to play, or None to stop any ambient that was playing
  3525. */
  3526. simulated function SetWeaponAmbientSound(SoundCue NewAmbientSound)
  3527. {
  3528. // if the component is already playing this sound, don't restart it
  3529. if (NewAmbientSound != WeaponAmbientSound.SoundCue)
  3530. {
  3531. WeaponAmbientSoundCue = NewAmbientSound;
  3532. WeaponAmbientSound.Stop();
  3533. WeaponAmbientSound.SoundCue = NewAmbientSound;
  3534. if (NewAmbientSound != None)
  3535. {
  3536. WeaponAmbientSound.Play();
  3537. }
  3538. }
  3539. }
  3540.  
  3541. simulated function SoundCue GetWeaponAmbientSound()
  3542. {
  3543. return WeaponAmbientSoundCue;
  3544. }
  3545.  
  3546. /**
  3547. * Apply a given overlay material to the overlay mesh.
  3548. *
  3549. * @Param NewOverlay The material to overlay
  3550. */
  3551. simulated function SetOverlayMaterial(MaterialInterface NewOverlay)
  3552. {
  3553. local int i;
  3554.  
  3555. // If we are authoritative, then set up replication of the new overlay
  3556. if (Role == ROLE_Authority)
  3557. {
  3558. OverlayMaterialInstance = NewOverlay;
  3559. }
  3560.  
  3561. if (Mesh.SkeletalMesh != None)
  3562. {
  3563. if (NewOverlay != None)
  3564. {
  3565. for (i = 0; i < OverlayMesh.SkeletalMesh.Materials.Length; i++)
  3566. {
  3567. OverlayMesh.SetMaterial(i, OverlayMaterialInstance);
  3568. }
  3569.  
  3570. // attach the overlay mesh
  3571. if (!OverlayMesh.bAttached)
  3572. {
  3573. AttachComponent(OverlayMesh);
  3574. }
  3575. }
  3576. else if (OverlayMesh.bAttached)
  3577. {
  3578. if (ShieldBeltArmor > 0)
  3579. {
  3580. // reapply shield belt overlay
  3581. SetOverlayMaterial(GetShieldMaterialInstance(WorldInfo.Game.bTeamGame));
  3582. }
  3583. else
  3584. {
  3585. DetachComponent(OverlayMesh);
  3586. }
  3587. }
  3588. }
  3589. }
  3590.  
  3591. /**
  3592. * @Returns the material to use for an overlay
  3593. */
  3594. simulated function MaterialInterface GetShieldMaterialInstance(bool bTeamGame)
  3595. {
  3596. return (bTeamGame ? default.ShieldBeltTeamMaterialInstances[GetTeamNum()] : default.ShieldBeltMaterialInstance);
  3597. }
  3598.  
  3599.  
  3600. /**
  3601. * This function allows you to access the overlay material stack.
  3602. *
  3603. * @returns the requested material instance
  3604. */
  3605. simulated function MaterialInterface GetOverlayMaterial()
  3606. {
  3607. return OverlayMaterialInstance;
  3608. }
  3609.  
  3610. function SetWeaponOverlayFlag(byte FlagToSet)
  3611. {
  3612. ApplyWeaponOverlayFlags(WeaponOverlayFlags | (1 << FlagToSet));
  3613. }
  3614.  
  3615. function ClearWeaponOverlayFlag(byte FlagToClear)
  3616. {
  3617. ApplyWeaponOverlayFlags(WeaponOverlayFlags & ( 0xFF ^ (1 << FlagToClear)) );
  3618. }
  3619.  
  3620. /**
  3621. * This function is a pass-through to the weapon/weapon attachment that is used to set the various overlays
  3622. */
  3623.  
  3624. simulated function ApplyWeaponOverlayFlags(byte NewFlags)
  3625. {
  3626. local UTWeapon Weap;
  3627. local UDKVehicleBase VBase;
  3628.  
  3629. if (Role == ROLE_Authority)
  3630. {
  3631. WeaponOverlayFlags = NewFlags;
  3632. }
  3633.  
  3634. if ( WorldInfo.NetMode != NM_DedicatedServer )
  3635. {
  3636. Weap = UTWeapon(Weapon);
  3637. if ( Weap != none)
  3638. {
  3639. Weap.SetWeaponOverlayFlags(self);
  3640. }
  3641.  
  3642. if ( CurrentWeaponAttachment != none )
  3643. {
  3644. CurrentWeaponAttachment.SetWeaponOverlayFlags(self);
  3645. }
  3646.  
  3647. VBase = UDKVehicleBase(DrivenVehicle);
  3648. if (VBase != None)
  3649. {
  3650. VBase.ApplyWeaponEffects(WeaponOverlayFlags);
  3651. }
  3652. }
  3653. }
  3654.  
  3655.  
  3656. /** called when bPlayingFeignDeathRecovery and interpolating our Mesh's PhysicsWeight to 0 has completed
  3657. * starts the recovery anim playing
  3658. */
  3659. simulated event StartFeignDeathRecoveryAnim()
  3660. {
  3661. local UTWeapon UTWeap;
  3662.  
  3663. // we're done with the ragdoll, so get rid of it
  3664. RestorePreRagdollCollisionComponent();
  3665. Mesh.PhysicsWeight = 0.f;
  3666. Mesh.MinDistFactorForKinematicUpdate = default.Mesh.MinDistFactorForKinematicUpdate;
  3667. Mesh.PhysicsAssetInstance.SetAllBodiesFixed(TRUE);
  3668. Mesh.PhysicsAssetInstance.SetFullAnimWeightBonesFixed(FALSE, Mesh);
  3669. SetPawnRBChannels(FALSE);
  3670. Mesh.bUpdateKinematicBonesFromAnimation=TRUE;
  3671.  
  3672. // Turn collision on for cylinder and off for skelmeshcomp
  3673. CylinderComponent.SetActorCollision(true, true);
  3674. Mesh.SetActorCollision(false, false);
  3675. Mesh.SetTraceBlocking(false, false);
  3676.  
  3677. Mesh.SetTickGroup(TG_PreAsyncWork);
  3678.  
  3679. if (Physics == PHYS_RigidBody)
  3680. {
  3681. setPhysics(PHYS_Falling);
  3682. }
  3683.  
  3684. UTWeap = UTWeapon(Weapon);
  3685. if (UTWeap != None)
  3686. {
  3687. UTWeap.PlayWeaponEquip();
  3688. }
  3689.  
  3690. if (FeignDeathBlend != None && FeignDeathBlend.Children[1].Anim != None)
  3691. {
  3692. FeignDeathBlend.Children[1].Anim.PlayAnim(false, 1.1);
  3693. }
  3694. else
  3695. {
  3696. // failed to find recovery node, so just pop out of ragdoll
  3697. bNoWeaponFiring = default.bNoWeaponFiring;
  3698. GotoState('Auto');
  3699. }
  3700. }
  3701.  
  3702. /** prevents player from getting out of feign death until the body has come to rest */
  3703. function FeignDeathDelayTimer()
  3704. {
  3705. if ( (WorldInfo.TimeSeconds - FeignDeathStartTime > 1.0)
  3706. && (PhysicsVolume.bWaterVolume || (VSize(Velocity) < 4.0 * FeignDeathBodyAtRestSpeed * (WorldInfo.TimeSeconds - FeignDeathStartTime))) )
  3707. {
  3708. // clear timer, so we can come out of feign death
  3709. ClearTimer('FeignDeathDelayTimer');
  3710. // automatically get up if we were forced into it
  3711. if (bFeigningDeath && bForcedFeignDeath)
  3712. {
  3713. bFeigningDeath = false;
  3714. PlayFeignDeath();
  3715. }
  3716. }
  3717. }
  3718.  
  3719. simulated function PlayFeignDeath()
  3720. {
  3721. local vector FeignLocation, HitLocation, HitNormal, TraceEnd, Impulse;
  3722. local rotator NewRotation;
  3723. local UTWeapon UTWeap;
  3724. local UTVehicle V;
  3725. local Controller Killer;
  3726. local float UnFeignZAdjust;
  3727.  
  3728. if (bFeigningDeath)
  3729. {
  3730. StartFallImpactTime = WorldInfo.TimeSeconds;
  3731. bCanPlayFallingImpacts=true;
  3732. GotoState('FeigningDeath');
  3733.  
  3734. // if we had some other rigid body thing going on, cancel it
  3735. if (Physics == PHYS_RigidBody)
  3736. {
  3737. //@note: Falling instead of None so Velocity/Acceleration don't get cleared
  3738. setPhysics(PHYS_Falling);
  3739. }
  3740.  
  3741. // Ensure we are always updating kinematic
  3742. Mesh.MinDistFactorForKinematicUpdate = 0.0;
  3743.  
  3744. SetPawnRBChannels(TRUE);
  3745. Mesh.ForceSkelUpdate();
  3746.  
  3747. // Move into post so that we are hitting physics from last frame, rather than animated from this
  3748. Mesh.SetTickGroup(TG_PostAsyncWork);
  3749.  
  3750. bBlendOutTakeHitPhysics = false;
  3751.  
  3752. PreRagdollCollisionComponent = CollisionComponent;
  3753. CollisionComponent = Mesh;
  3754.  
  3755. // Turn collision on for skelmeshcomp and off for cylinder
  3756. CylinderComponent.SetActorCollision(false, false);
  3757. Mesh.SetActorCollision(true, true);
  3758. Mesh.SetTraceBlocking(true, true);
  3759.  
  3760. SetPhysics(PHYS_RigidBody);
  3761. Mesh.PhysicsWeight = 1.0;
  3762.  
  3763. // If we had stopped updating kinematic bodies on this character due to distance from camera, force an update of bones now.
  3764. if( Mesh.bNotUpdatingKinematicDueToDistance )
  3765. {
  3766. Mesh.UpdateRBBonesFromSpaceBases(TRUE, TRUE);
  3767. }
  3768.  
  3769. Mesh.PhysicsAssetInstance.SetAllBodiesFixed(FALSE);
  3770. Mesh.bUpdateKinematicBonesFromAnimation=FALSE;
  3771.  
  3772. // Set all kinematic bodies to the current root velocity, since they may not have been updated during normal animation
  3773. // and therefore have zero derived velocity (this happens in 1st person camera mode).
  3774. Mesh.SetRBLinearVelocity(Velocity, false);
  3775.  
  3776. FeignDeathStartTime = WorldInfo.TimeSeconds;
  3777. // reset mesh translation since adjustment code isn't executed on the server
  3778. // but the ragdoll code uses the translation so we need them to match up for the
  3779. // most accurate simulation
  3780. Mesh.SetTranslation(vect(0,0,1) * BaseTranslationOffset);
  3781. // we'll use the rigid body collision to check for falling damage
  3782. Mesh.ScriptRigidBodyCollisionThreshold = MaxFallSpeed;
  3783. Mesh.SetNotifyRigidBodyCollision(true);
  3784. Mesh.WakeRigidBody();
  3785.  
  3786. if (Role == ROLE_Authority)
  3787. {
  3788. SetTimer(0.15, true, 'FeignDeathDelayTimer');
  3789. }
  3790. }
  3791. else
  3792. {
  3793. // fit cylinder collision into location, crouching if necessary
  3794. FeignLocation = Location;
  3795. CollisionComponent = PreRagdollCollisionComponent;
  3796. TraceEnd = Location + vect(0,0,1) * GetCollisionHeight();
  3797. if (Trace(HitLocation, HitNormal, TraceEnd, Location, true, GetCollisionExtent()) == None )
  3798. {
  3799. HitLocation = TraceEnd;
  3800. }
  3801. if ( !SetFeignEndLocation(HitLocation, FeignLocation) )
  3802. {
  3803. CollisionComponent = Mesh;
  3804. SetLocation(FeignLocation);
  3805. bFeigningDeath = true;
  3806. Impulse = VRand();
  3807. Impulse.Z = 0.5;
  3808. Mesh.AddImpulse(800.0*Impulse, Location);
  3809. UnfeignFailedCount++;
  3810. if ( UnFeignfailedCount > 4 )
  3811. {
  3812. Suicide();
  3813. }
  3814. return;
  3815. }
  3816.  
  3817. // Calculate how far we just moved the actor up.
  3818. UnFeignZAdjust = Location.Z - FeignLocation.Z;
  3819. // If its positive, move back down by that amount until it hits the floor
  3820. if(UnFeignZAdjust > 0.0)
  3821. {
  3822. moveSmooth(vect(0,0,-1) * UnFeignZAdjust);
  3823. }
  3824.  
  3825. UnfeignFailedCount = 0;
  3826.  
  3827. CollisionComponent = Mesh;
  3828.  
  3829. bPlayingFeignDeathRecovery = true;
  3830. FeignDeathRecoveryStartTime = WorldInfo.TimeSeconds;
  3831.  
  3832. // don't need collision events anymore
  3833. Mesh.SetNotifyRigidBodyCollision(false);
  3834. // don't allow player to move while animation is in progress
  3835. SetPhysics(PHYS_None);
  3836.  
  3837. if (Role == ROLE_Authority)
  3838. {
  3839. // if cylinder is penetrating a vehicle, kill the pawn to prevent exploits
  3840. CollisionComponent = PreRagdollCollisionComponent;
  3841. foreach CollidingActors(class'UTVehicle', V, GetCollisionRadius(),, true)
  3842. {
  3843. if (IsOverlapping(V))
  3844. {
  3845. if (V.Class == HoverboardClass)
  3846. {
  3847. // don't want to kill pawn in this case, so push vehicle away instead
  3848. Impulse = VRand() * V.GroundSpeed;
  3849. Impulse.Z = 500.0;
  3850. V.Mesh.AddImpulse(Impulse,,, true);
  3851. }
  3852. else
  3853. {
  3854. CollisionComponent = Mesh;
  3855. if (V.Controller != None)
  3856. {
  3857. Killer = V.Controller;
  3858. }
  3859. else if (V.Instigator != None)
  3860. {
  3861. Killer = V.Instigator.Controller;
  3862. }
  3863. Died(Killer, V.RanOverDamageType, Location);
  3864. return;
  3865. }
  3866. }
  3867. }
  3868. CollisionComponent = Mesh;
  3869. }
  3870.  
  3871. // find getup animation, and freeze it at the first frame
  3872. if ( (FeignDeathBlend != None) && !bIsCrouched )
  3873. {
  3874. // physics weight interpolated to 0 in C++, then StartFeignDeathRecoveryAnim() is called
  3875. Mesh.PhysicsWeight = 1.0;
  3876. FeignDeathBlend.SetBlendTarget(1.0, 0.0);
  3877. // force rotation to match the body's direction so the blend to the getup animation looks more natural
  3878. NewRotation = Rotation;
  3879. NewRotation.Yaw = rotator(Mesh.GetBoneAxis('b_Hips', AXIS_X)).Yaw;
  3880. // flip it around if the head is facing upwards, since the animation for that makes the character
  3881. // end up facing in the opposite direction that its body is pointing on the ground
  3882. // FIXME: generalize this somehow (stick it in the AnimNode, I guess...)
  3883. if (Mesh.GetBoneAxis(HeadBone, AXIS_Y).Z < 0.0)
  3884. {
  3885. NewRotation.Yaw += 32768;
  3886. }
  3887. SetRotation(NewRotation);
  3888. }
  3889. else
  3890. {
  3891. // failed to find recovery node, so just pop out of ragdoll
  3892. RestorePreRagdollCollisionComponent();
  3893. Mesh.PhysicsWeight = 0.f;
  3894. Mesh.PhysicsAssetInstance.SetAllBodiesFixed(TRUE);
  3895. Mesh.bUpdateKinematicBonesFromAnimation=TRUE;
  3896. Mesh.MinDistFactorForKinematicUpdate = default.Mesh.MinDistFactorForKinematicUpdate;
  3897. SetPawnRBChannels(FALSE);
  3898.  
  3899. if (Physics == PHYS_RigidBody)
  3900. {
  3901. setPhysics(PHYS_Falling);
  3902. }
  3903.  
  3904. UTWeap = UTWeapon(Weapon);
  3905. if (UTWeap != None)
  3906. {
  3907. UTWeap.PlayWeaponEquip();
  3908. }
  3909. GotoState('Auto');
  3910. }
  3911. }
  3912. }
  3913.  
  3914. simulated function bool SetFeignEndLocation(vector HitLocation, vector FeignLocation)
  3915. {
  3916. local vector NewDest;
  3917.  
  3918. if ( SetLocation(HitLocation) && CheckValidLocation(FeignLocation) )
  3919. {
  3920. return true;
  3921. }
  3922.  
  3923. // try crouching
  3924. ForceCrouch();
  3925. if ( SetLocation(HitLocation) && CheckValidLocation(FeignLocation) )
  3926. {
  3927. return true;
  3928. }
  3929.  
  3930. newdest = HitLocation + GetCollisionRadius() * vect(1,1,0);
  3931. if ( SetLocation(newdest) && CheckValidLocation(FeignLocation) )
  3932. return true;
  3933. newdest = HitLocation + GetCollisionRadius() * vect(1,-1,0);
  3934. if ( SetLocation(newdest) && CheckValidLocation(FeignLocation) )
  3935. return true;
  3936. newdest = HitLocation + GetCollisionRadius() * vect(-1,1,0);
  3937. if ( SetLocation(newdest) && CheckValidLocation(FeignLocation) )
  3938. return true;
  3939. newdest = HitLocation + GetCollisionRadius() * vect(-1,-1,0);
  3940. if ( SetLocation(newdest) && CheckValidLocation(FeignLocation) )
  3941. return true;
  3942.  
  3943. return false;
  3944. }
  3945.  
  3946. /**
  3947. * Make sure location pawn ended up at out of feign death is valid (not through a wall)
  3948. */
  3949. simulated function bool CheckValidLocation(vector FeignLocation)
  3950. {
  3951. local vector HitLocation, HitNormal, DestFinalZ;
  3952.  
  3953. // try trace down to dest
  3954. if (Trace(HitLocation, HitNormal, Location, FeignLocation, false, vect(10,10,10),, TRACEFLAG_Bullet) == None)
  3955. {
  3956. return true;
  3957. }
  3958.  
  3959. // try trace straight up, then sideways to final location
  3960. DestFinalZ = FeignLocation;
  3961. FeignLocation.Z = Location.Z;
  3962. if ( Trace(HitLocation, HitNormal, DestFinalZ, FeignLocation, false, vect(10,10,10)) == None &&
  3963. Trace(HitLocation, HitNormal, Location, DestFinalZ, false, vect(10,10,10),, TRACEFLAG_Bullet) == None )
  3964. {
  3965. return true;
  3966. }
  3967. return false;
  3968. }
  3969.  
  3970.  
  3971. reliable server function ServerFeignDeath()
  3972. {
  3973. if (Role == ROLE_Authority && !WorldInfo.Game.IsInState('MatchOver') && DrivenVehicle == None && Controller != None && !bFeigningDeath)
  3974. {
  3975. bFeigningDeath = true;
  3976. PlayFeignDeath();
  3977. }
  3978. }
  3979.  
  3980. exec simulated function FeignDeath()
  3981. {
  3982. ServerFeignDeath();
  3983. }
  3984.  
  3985. /** force the player to ragdoll, automatically getting up when the body comes to rest
  3986. * (basically, force activate the feign death code)
  3987. */
  3988. function ForceRagdoll()
  3989. {
  3990. bFeigningDeath = true;
  3991. bForcedFeignDeath = true;
  3992. PlayFeignDeath();
  3993. }
  3994.  
  3995. simulated function FiringModeUpdated(Weapon InWeapon, byte InFiringMode, bool bViaReplication)
  3996. {
  3997. super.FiringModeUpdated(InWeapon, InFiringMode, bViaReplication);
  3998. if(CurrentWeaponAttachment != none)
  3999. {
  4000. CurrentWeaponAttachment.FireModeUpdated(InFiringMode, bViaReplication);
  4001. }
  4002. }
  4003.  
  4004. /**
  4005. * Called by Bighead mutator when spawned, and also if bKillsAffectHead when kill someone
  4006. */
  4007. function SetBigHead()
  4008. {
  4009. bKillsAffectHead = true;
  4010. if ( PlayerReplicationInfo != None )
  4011. {
  4012. SetHeadScale(FClamp((5+PlayerReplicationInfo.Kills)/(5+PlayerReplicationInfo.Deaths), 0.75, 2.0));
  4013. }
  4014. }
  4015.  
  4016. /** called when FireRateMultiplier is changed to update weapon timers */
  4017. simulated function FireRateChanged()
  4018. {
  4019. if (Weapon != None && Weapon.IsTimerActive('RefireCheckTimer'))
  4020. {
  4021. // make currently firing weapon slow down firing rate
  4022. Weapon.ClearTimer('RefireCheckTimer');
  4023. Weapon.TimeWeaponFiring(Weapon.CurrentFireMode);
  4024. }
  4025. if (DrivenVehicle != None && DrivenVehicle.Weapon != None && DrivenVehicle.Weapon.IsTimerActive('RefireCheckTimer'))
  4026. {
  4027. // make currently firing vehicle weapon slow down firing rate
  4028. DrivenVehicle.Weapon.ClearTimer('RefireCheckTimer');
  4029. DrivenVehicle.Weapon.TimeWeaponFiring(DrivenVehicle.Weapon.CurrentFireMode);
  4030. }
  4031. }
  4032.  
  4033. /**
  4034. * Check on various replicated data and act accordingly.
  4035. */
  4036. simulated event ReplicatedEvent(name VarName)
  4037. {
  4038. if ( VarName == 'Controller' && Controller != None )
  4039. {
  4040. // Reset the weapon when you get the controller and
  4041. // make sure it has ammo.
  4042. if (UTWeapon(Weapon) != None)
  4043. {
  4044. UTWeapon(Weapon).ClientEndFire(0);
  4045. UTWeapon(Weapon).ClientEndFire(1);
  4046. if ( !Weapon.HasAnyAmmo() )
  4047. {
  4048. Weapon.WeaponEmpty();
  4049. }
  4050. }
  4051. }
  4052. // If CurrentWeaponAttachmentClass has changed, the player has switched weapons and
  4053. // will need to update itself accordingly.
  4054. else if ( VarName == 'CurrentWeaponAttachmentClass' )
  4055. {
  4056. WeaponAttachmentChanged();
  4057. return;
  4058. }
  4059. else if ( VarName == 'CompressedBodyMatColor' )
  4060. {
  4061. BodyMatColor.R = CompressedBodyMatColor.Pitch/256.0;
  4062. BodyMatColor.G = CompressedBodyMatColor.Yaw/256.0;
  4063. BodyMatColor.B = CompressedBodyMatColor.Roll/256.0;
  4064. }
  4065. else if ( VarName == 'ClientBodyMatDuration' )
  4066. {
  4067. SetBodyMatColor(BodyMatColor,ClientBodyMatDuration);
  4068. }
  4069. else if ( VarName == 'HeadScale' )
  4070. {
  4071. SetHeadScale(HeadScale);
  4072. }
  4073. else if (VarName == 'PawnAmbientSoundCue')
  4074. {
  4075. SetPawnAmbientSound(PawnAmbientSoundCue);
  4076. }
  4077. else if (VarName == 'WeaponAmbientSoundCue')
  4078. {
  4079. SetWeaponAmbientSound(WeaponAmbientSoundCue);
  4080. }
  4081. else if (VarName == 'ReplicatedBodyMaterial')
  4082. {
  4083. SetSkin(ReplicatedBodyMaterial);
  4084. }
  4085. else if (VarName == 'OverlayMaterialInstance')
  4086. {
  4087. SetOverlayMaterial(OverlayMaterialInstance);
  4088. }
  4089. else if (VarName == 'bFeigningDeath')
  4090. {
  4091. PlayFeignDeath();
  4092. }
  4093. else if (VarName == 'WeaponOverlayFlags')
  4094. {
  4095. ApplyWeaponOverlayFlags(WeaponOverlayFlags);
  4096. }
  4097. else if (VarName == 'LastTakeHitInfo')
  4098. {
  4099. PlayTakeHitEffects();
  4100. }
  4101. else if (VarName == 'DrivenWeaponPawn')
  4102. {
  4103. if (DrivenWeaponPawn.BaseVehicle != LastDrivenWeaponPawn.BaseVehicle || DrivenWeaponPawn.SeatIndex != LastDrivenWeaponPawn.SeatIndex)
  4104. {
  4105. if (DrivenWeaponPawn.BaseVehicle != None)
  4106. {
  4107. // create a client side pawn to drive
  4108. if (ClientSideWeaponPawn == None || ClientSideWeaponPawn.bDeleteMe)
  4109. {
  4110. ClientSideWeaponPawn = Spawn(class'UTClientSideWeaponPawn', DrivenWeaponPawn.BaseVehicle);
  4111. }
  4112. ClientSideWeaponPawn.MyVehicle =UTVehicle(DrivenWeaponPawn.BaseVehicle);
  4113. ClientSideWeaponPawn.MySeatIndex = DrivenWeaponPawn.SeatIndex;
  4114. StartDriving(ClientSideWeaponPawn);
  4115. }
  4116. else if (ClientSideWeaponPawn != None && ClientSideWeaponPawn == DrivenVehicle)
  4117. {
  4118. StopDriving(ClientSideWeaponPawn);
  4119. }
  4120. }
  4121. if (ClientSideWeaponPawn != None && ClientSideWeaponPawn == DrivenVehicle && ClientSideWeaponPawn.PlayerReplicationInfo != DrivenWeaponPawn.PRI)
  4122. {
  4123. ClientSideWeaponPawn.PlayerReplicationInfo = DrivenWeaponPawn.PRI;
  4124. ClientSideWeaponPawn.NotifyTeamChanged();
  4125. }
  4126. LastDrivenWeaponPawn = DrivenWeaponPawn;
  4127. }
  4128. else if (VarName == 'bPuttingDownWeapon')
  4129. {
  4130. SetPuttingDownWeapon(bPuttingDownWeapon);
  4131. }
  4132. else if (VarName == 'EmoteRepInfo')
  4133. {
  4134. DoPlayEmote(EmoteRepInfo.EmoteTag, EmoteRepInfo.EmoteID);
  4135. }
  4136. else if (VarName == 'bIsInvisible')
  4137. {
  4138. SetInvisible(bIsInvisible);
  4139. }
  4140. else if (VarName == 'BigTeleportCount')
  4141. {
  4142. PostBigTeleport();
  4143. }
  4144. else if (VarName == 'FireRateMultiplier')
  4145. {
  4146. FireRateChanged();
  4147. }
  4148. else
  4149. {
  4150. Super.ReplicatedEvent(VarName);
  4151. }
  4152. }
  4153.  
  4154. simulated function SetHeadScale(float NewScale)
  4155. {
  4156. local SkelControlBase SkelControl;
  4157.  
  4158. HeadScale = NewScale;
  4159. SkelControl = Mesh.FindSkelControl('HeadControl');
  4160. if (SkelControl != None)
  4161. {
  4162. SkelControl.BoneScale = NewScale;
  4163. SkelControl.IgnoreAtOrAboveLOD = 1000;
  4164. }
  4165.  
  4166. // we need to scale the neck bone also as otherwise the head piece leaves a point and doesn't show the neck cavity
  4167. SkelControl = Mesh.FindSkelControl('NeckControl');
  4168. if (SkelControl != None)
  4169. {
  4170. // NeckScale should only ever between 0 or 1
  4171. SkelControl.BoneScale = FClamp( NewScale, 0.f, 1.0f );
  4172. SkelControl.IgnoreAtOrAboveLOD = 1000;
  4173. }
  4174. }
  4175.  
  4176. /** sets the value of bPuttingDownWeapon and plays any appropriate animations for the change */
  4177. simulated function SetPuttingDownWeapon(bool bNowPuttingDownWeapon)
  4178. {
  4179. if (bPuttingDownWeapon != bNowPuttingDownWeapon || Role < ROLE_Authority)
  4180. {
  4181. bPuttingDownWeapon = bNowPuttingDownWeapon;
  4182. if (CurrentWeaponAttachment != None)
  4183. {
  4184. CurrentWeaponAttachment.SetPuttingDownWeapon(bPuttingDownWeapon);
  4185. }
  4186. }
  4187. }
  4188.  
  4189. /** @return the value of bPuttingDownWeapon */
  4190. simulated function bool GetPuttingDownWeapon()
  4191. {
  4192. return bPuttingDownWeapon;
  4193. }
  4194.  
  4195. /**
  4196. * We override TakeDamage and allow the weapon to modify it
  4197. * @See Pawn.TakeDamage
  4198. */
  4199. event TakeDamage(int Damage, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
  4200. {
  4201. local int OldHealth;
  4202.  
  4203. // Attached Bio glob instigator always gets kill credit
  4204. if (AttachedProj != None && !AttachedProj.bDeleteMe && AttachedProj.InstigatorController != None)
  4205. {
  4206. EventInstigator = AttachedProj.InstigatorController;
  4207. }
  4208.  
  4209. // reduce rocket jumping
  4210. if (EventInstigator == Controller)
  4211. {
  4212. momentum *= 0.6;
  4213. }
  4214.  
  4215. // accumulate damage taken in a single tick
  4216. if ( AccumulationTime != WorldInfo.TimeSeconds )
  4217. {
  4218. AccumulateDamage = 0;
  4219. AccumulationTime = WorldInfo.TimeSeconds;
  4220. }
  4221. OldHealth = Health;
  4222. AccumulateDamage += Damage;
  4223. Super.TakeDamage(Damage, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser);
  4224. AccumulateDamage = AccumulateDamage + OldHealth - Health - Damage;
  4225.  
  4226. }
  4227.  
  4228. /**
  4229. * Called when a pawn's weapon has fired and is responsibile for
  4230. * delegating the creation off all of the different effects.
  4231. *
  4232. * bViaReplication denotes if this call in as the result of the
  4233. * flashcount/flashlocation being replicated. It's used filter out
  4234. * when to make the effects.
  4235. */
  4236. simulated function WeaponFired(Weapon InWeapon, bool bViaReplication, optional vector HitLocation)
  4237. {
  4238. if (CurrentWeaponAttachment != None)
  4239. {
  4240. if ( !IsFirstPerson() )
  4241. {
  4242. CurrentWeaponAttachment.ThirdPersonFireEffects(HitLocation);
  4243. }
  4244. else
  4245. {
  4246. CurrentWeaponAttachment.FirstPersonFireEffects(Weapon, HitLocation);
  4247. if ( class'Engine'.static.IsSplitScreen() && CurrentWeaponAttachment.EffectIsRelevant(CurrentWeaponAttachment.Location,false,CurrentWeaponAttachment.MaxFireEffectDistance) )
  4248. {
  4249. // third person muzzle flash
  4250. CurrentWeaponAttachment.CauseMuzzleFlash();
  4251. }
  4252. }
  4253.  
  4254. if ( HitLocation != Vect(0,0,0) && (WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_Standalone || bViaReplication) )
  4255. {
  4256. CurrentWeaponAttachment.PlayImpactEffects(HitLocation);
  4257. }
  4258. }
  4259. }
  4260.  
  4261. simulated function WeaponStoppedFiring(Weapon InWeapon, bool bViaReplication)
  4262. {
  4263. if (CurrentWeaponAttachment != None)
  4264. {
  4265. // always call function for both viewpoints, as during the delay between calling EndFire() on the weapon
  4266. // and it actually stopping, we might have switched viewpoints (e.g. this commonly happens when entering a vehicle)
  4267. CurrentWeaponAttachment.StopThirdPersonFireEffects();
  4268. CurrentWeaponAttachment.StopFirstPersonFireEffects(Weapon);
  4269. }
  4270. }
  4271.  
  4272. /**
  4273. * Called when a weapon is changed and is responsible for making sure
  4274. * the new weapon respects the current pawn's states/etc.
  4275. */
  4276.  
  4277. simulated function WeaponChanged(UTWeapon NewWeapon)
  4278. {
  4279. local UDKSkeletalMeshComponent UTSkel;
  4280.  
  4281. // Make sure the new weapon respects behindview
  4282. if (NewWeapon.Mesh != None)
  4283. {
  4284. NewWeapon.Mesh.SetHidden(!IsFirstPerson());
  4285. UTSkel = UDKSkeletalMeshComponent(NewWeapon.Mesh);
  4286. if (UTSkel != none)
  4287. {
  4288. ArmsMesh[0].SetFOV(UTSkel.FOV);
  4289. ArmsMesh[1].SetFOV(UTSkel.FOV);
  4290. ArmsMesh[0].SetScale(UTSkel.Scale);
  4291. ArmsMesh[1].SetScale(UTSkel.Scale);
  4292. NewWeapon.PlayWeaponEquip();
  4293. }
  4294. }
  4295. }
  4296.  
  4297. /**
  4298. * Called when there is a need to change the weapon attachment (either via
  4299. * replication or locally if controlled.
  4300. */
  4301. simulated function WeaponAttachmentChanged()
  4302. {
  4303. if ((CurrentWeaponAttachment == None || CurrentWeaponAttachment.Class != CurrentWeaponAttachmentClass) && Mesh.SkeletalMesh != None)
  4304. {
  4305. // Detach/Destroy the current attachment if we have one
  4306. if (CurrentWeaponAttachment!=None)
  4307. {
  4308. CurrentWeaponAttachment.DetachFrom(Mesh);
  4309. CurrentWeaponAttachment.Destroy();
  4310. }
  4311.  
  4312. // Create the new Attachment.
  4313. if (CurrentWeaponAttachmentClass!=None)
  4314. {
  4315. CurrentWeaponAttachment = Spawn(CurrentWeaponAttachmentClass,self);
  4316. CurrentWeaponAttachment.Instigator = self;
  4317. }
  4318. else
  4319. CurrentWeaponAttachment = none;
  4320.  
  4321. // If all is good, attach it to the Pawn's Mesh.
  4322. if (CurrentWeaponAttachment != None)
  4323. {
  4324. CurrentWeaponAttachment.AttachTo(self);
  4325. CurrentWeaponAttachment.SetSkin(ReplicatedBodyMaterial);
  4326. CurrentWeaponAttachment.ChangeVisibility(bWeaponAttachmentVisible);
  4327. }
  4328. }
  4329. }
  4330.  
  4331. function PlayHit(float Damage, Controller InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum, TraceHitInfo HitInfo)
  4332. {
  4333. local UTPlayerController Hearer;
  4334. local class<UTDamageType> UTDamage;
  4335.  
  4336. if ( InstigatedBy != None && (class<UTDamageType>(DamageType) != None) && class<UTDamageType>(DamageType).default.bDirectDamage )
  4337. {
  4338. Hearer = UTPlayerController(InstigatedBy);
  4339. if (Hearer != None)
  4340. {
  4341. Hearer.bAcuteHearing = true;
  4342. }
  4343. }
  4344.  
  4345. if (WorldInfo.TimeSeconds - LastPainSound >= MinTimeBetweenPainSounds)
  4346. {
  4347. LastPainSound = WorldInfo.TimeSeconds;
  4348.  
  4349. if (Damage > 0 && Health > 0)
  4350. {
  4351.  
  4352. if ( DamageType == class'UTDmgType_Drowned' )
  4353. {
  4354. SoundGroupClass.static.PlayDrownSound(self);
  4355. }
  4356. else
  4357. {
  4358. SoundGroupClass.static.PlayTakeHitSound(self, Damage);
  4359. }
  4360. }
  4361. }
  4362.  
  4363. if ( Health <= 0 && PhysicsVolume.bDestructive && (WaterVolume(PhysicsVolume) != None) && (WaterVolume(PhysicsVolume).ExitActor != None) )
  4364. {
  4365. Spawn(WaterVolume(PhysicsVolume).ExitActor);
  4366. }
  4367.  
  4368. Super.PlayHit(Damage, InstigatedBy, HitLocation, DamageType, Momentum, HitInfo);
  4369.  
  4370. if (Hearer != None)
  4371. {
  4372. Hearer.bAcuteHearing = false;
  4373. }
  4374.  
  4375. UTDamage = class<UTDamageType>(DamageType);
  4376.  
  4377. if (Damage > 0 || (Controller != None && Controller.bGodMode))
  4378. {
  4379. CheckHitInfo( HitInfo, Mesh, Normal(Momentum), HitLocation );
  4380.  
  4381. // play serverside effects
  4382. if (bShieldAbsorb)
  4383. {
  4384. SetBodyMatColor(SpawnProtectionColor, 1.0);
  4385. PlaySound(ArmorHitSound);
  4386. bShieldAbsorb = false;
  4387. return;
  4388. }
  4389. else if (UTDamage != None && UTDamage.default.DamageOverlayTime > 0.0 && UTDamage.default.XRayEffectTime <= 0.0)
  4390. {
  4391. SetBodyMatColor(UTDamage.default.DamageBodyMatColor, UTDamage.default.DamageOverlayTime);
  4392. }
  4393.  
  4394. LastTakeHitInfo.Damage = Damage;
  4395. LastTakeHitInfo.HitLocation = HitLocation;
  4396. LastTakeHitInfo.Momentum = Momentum;
  4397. LastTakeHitInfo.DamageType = DamageType;
  4398. LastTakeHitInfo.HitBone = HitInfo.BoneName;
  4399. LastTakeHitTimeout = WorldInfo.TimeSeconds + ( (UTDamage != None) ? UTDamage.static.GetHitEffectDuration(self, Damage)
  4400. : class'UTDamageType'.static.GetHitEffectDuration(self, Damage) );
  4401.  
  4402. // play clientside effects
  4403. PlayTakeHitEffects();
  4404. }
  4405. }
  4406.  
  4407. /** plays clientside hit effects using the data in LastTakeHitInfo */
  4408. simulated function PlayTakeHitEffects()
  4409. {
  4410. local class<UTDamageType> UTDamage;
  4411. local vector BloodMomentum;
  4412. local UTEmit_HitEffect HitEffect;
  4413. local ParticleSystem BloodTemplate;
  4414.  
  4415. if (EffectIsRelevant(Location, false))
  4416. {
  4417. UTDamage = class<UTDamageType>(LastTakeHitInfo.DamageType);
  4418. if ( UTDamage != None )
  4419. {
  4420. if (UTDamage.default.bCausesBloodSplatterDecals && !IsZero(LastTakeHitInfo.Momentum) && !class'UTGame'.Static.UseLowGore(WorldInfo))
  4421. {
  4422. LeaveABloodSplatterDecal(LastTakeHitInfo.HitLocation, LastTakeHitInfo.Momentum);
  4423. }
  4424.  
  4425. if (!IsFirstPerson() || class'Engine'.static.IsSplitScreen())
  4426. {
  4427. if ( UTDamage.default.bCausesBlood && !class'UTGame'.Static.UseLowGore(WorldInfo) )
  4428. {
  4429. BloodTemplate = class'UTEmitter'.static.GetTemplateForDistance(GetFamilyInfo().default.BloodEffects, LastTakeHitInfo.HitLocation, WorldInfo);
  4430. if (BloodTemplate != None)
  4431. {
  4432. BloodMomentum = Normal(-1.0 * LastTakeHitInfo.Momentum) + (0.5 * VRand());
  4433. HitEffect = Spawn(GetFamilyInfo().default.BloodEmitterClass, self,, LastTakeHitInfo.HitLocation, rotator(BloodMomentum));
  4434. HitEffect.SetTemplate(BloodTemplate, true);
  4435. HitEffect.AttachTo(self, LastTakeHitInfo.HitBone);
  4436. }
  4437. }
  4438.  
  4439. if ( !Mesh.bNotUpdatingKinematicDueToDistance )
  4440. {
  4441. // physics based takehit animations
  4442. if (UTDamage != None)
  4443. {
  4444. //@todo: apply impulse when in full ragdoll too (that also needs to happen on the server)
  4445. if ( !class'Engine'.static.IsSplitScreen() && Health > 0 && DrivenVehicle == None && Physics != PHYS_RigidBody &&
  4446. VSize(LastTakeHitInfo.Momentum) > UTDamage.default.PhysicsTakeHitMomentumThreshold )
  4447. {
  4448. if (Mesh.PhysicsAssetInstance != None)
  4449. {
  4450. // just add an impulse to the asset that's already there
  4451. Mesh.AddImpulse(LastTakeHitInfo.Momentum, LastTakeHitInfo.HitLocation);
  4452. // if we were already playing a take hit effect, restart it
  4453. if (bBlendOutTakeHitPhysics)
  4454. {
  4455. Mesh.PhysicsWeight = 0.5;
  4456. }
  4457. }
  4458. else if (Mesh.PhysicsAsset != None)
  4459. {
  4460. Mesh.PhysicsWeight = 0.5;
  4461. Mesh.PhysicsAssetInstance.SetNamedBodiesFixed(true, TakeHitPhysicsFixedBones, Mesh, true);
  4462. Mesh.AddImpulse(LastTakeHitInfo.Momentum, LastTakeHitInfo.HitLocation);
  4463. bBlendOutTakeHitPhysics = true;
  4464. }
  4465. }
  4466. UTDamage.static.SpawnHitEffect(self, LastTakeHitInfo.Damage, LastTakeHitInfo.Momentum, LastTakeHitInfo.HitBone, LastTakeHitInfo.HitLocation);
  4467. }
  4468. }
  4469. }
  4470. }
  4471. }
  4472. }
  4473.  
  4474. /** called when bBlendOutTakeHitPhysics is true and our Mesh's PhysicsWeight has reached 0.0 */
  4475. simulated event TakeHitBlendedOut()
  4476. {
  4477. Mesh.PhysicsWeight = 0.0;
  4478. Mesh.PhysicsAssetInstance.SetAllBodiesFixed(TRUE);
  4479. }
  4480.  
  4481. reliable server function ServerHoverboard()
  4482. {
  4483. local UTVehicle Board;
  4484. local vector Start, End, HitLoc, HitNorm;
  4485. local actor HitActor;
  4486. local TraceHitInfo HitInfo;
  4487. local bool bInDeepWater;
  4488.  
  4489. // Do a line check to see if we are too deep in water
  4490. Start = Location;
  4491. End = Location - vect(0,0,15);
  4492. HitActor = Trace(HitLoc, HitNorm, End, Start, false, vect(0,0,0), HitInfo, TRACEFLAG_PhysicsVolumes);
  4493. if(HitActor != None && WaterVolume(HitActor) != None)
  4494. {
  4495. bInDeepWater = TRUE;
  4496. }
  4497.  
  4498. if ( bHasHoverboard && !bIsCrouched && (DrivenVehicle == None) && !PhysicsVolume.bWaterVolume && (WorldInfo.TimeSeconds - LastHoverboardTime > MinHoverboardInterval) && (Physics != PHYS_Swimming) && !bInDeepWater)
  4499. {
  4500. LastHoverboardTime = WorldInfo.TimeSeconds;
  4501. //Temp turn off collision
  4502. SetCollision(false, false);
  4503. Board = Spawn(HoverboardClass);
  4504. if (Board != None && !Board.bDeleteMe)
  4505. {
  4506. // make sure it didn't get spawned on the other side of a wall
  4507. if (!FastTrace(Board.Location, Location) || !Board.TryToDrive(self))
  4508. {
  4509. Board.Destroy();
  4510. SetCollision(true, true);
  4511. }
  4512. }
  4513. else
  4514. {
  4515. SetCollision(true, true);
  4516. }
  4517. }
  4518. }
  4519.  
  4520. function OnUseHoverboard(UTSeqAct_UseHoverboard Action)
  4521. {
  4522. bHasHoverboard = true;
  4523. ServerHoverboard();
  4524. Action.Hoverboard = UTVehicle(DrivenVehicle);
  4525. }
  4526.  
  4527. simulated function SwitchWeapon(byte NewGroup)
  4528. {
  4529. if (NewGroup == 0 && bHasHoverboard && DrivenVehicle == None)
  4530. {
  4531. if ( WorldInfo.TimeSeconds - LastHoverboardTime > MinHoverboardInterval )
  4532. {
  4533. ServerHoverboard();
  4534. LastHoverboardTime = WorldInfo.TimeSeconds;
  4535. }
  4536. return;
  4537. }
  4538.  
  4539. if (UTInventoryManager(InvManager) != None)
  4540. {
  4541. UTInventoryManager(InvManager).SwitchWeapon(NewGroup);
  4542. }
  4543. }
  4544.  
  4545. function TakeDrowningDamage()
  4546. {
  4547. TakeDamage(5, None, Location + GetCollisionHeight() * vect(0,0,0.5)+ 0.7 * GetCollisionRadius() * vector(Controller.Rotation), vect(0,0,0), class'UTDmgType_Drowned');
  4548. }
  4549.  
  4550. function bool IsLocationOnHead(const out ImpactInfo Impact, float AdditionalScale)
  4551. {
  4552. local vector HeadLocation;
  4553. local float Distance;
  4554.  
  4555. if (HeadBone == '')
  4556. {
  4557. return False;
  4558. }
  4559.  
  4560. Mesh.ForceSkelUpdate();
  4561. HeadLocation = Mesh.GetBoneLocation(HeadBone) + vect(0,0,1) * HeadHeight;
  4562.  
  4563. // Find distance from head location to bullet vector
  4564. Distance = PointDistToLine(HeadLocation, Impact.RayDir, Impact.HitLocation);
  4565.  
  4566. return ( Distance < (HeadRadius * HeadScale * AdditionalScale) );
  4567. }
  4568.  
  4569. simulated function ModifyRotForDebugFreeCam(out rotator out_CamRot)
  4570. {
  4571. local UTPlayerController UPC;
  4572.  
  4573. UPC = UTPlayerController(Controller);
  4574. //`log(GetFuncName()@self@UPC@Controller@UPC.bDebugFreeCam@DrivenVehicle);
  4575.  
  4576. if ( (UPC == None) && (DrivenVehicle != None) )
  4577. {
  4578. UPC = UTPlayerController(DrivenVehicle.Controller);
  4579. }
  4580.  
  4581. if (UPC != None)
  4582. {
  4583. if (UPC.bDebugFreeCam)
  4584. {
  4585. // `log(GetFuncName()@"setting rot");
  4586. out_CamRot = UPC.DebugFreeCamRot;
  4587. }
  4588. }
  4589. }
  4590.  
  4591. simulated function bool IsFirstPerson()
  4592. {
  4593. local PlayerController PC;
  4594.  
  4595. ForEach LocalPlayerControllers(class'PlayerController', PC)
  4596. {
  4597. if ( (PC.ViewTarget == self) && PC.UsingFirstPersonCamera() )
  4598. return true;
  4599. }
  4600. return false;
  4601. }
  4602.  
  4603. /** moves the camera in or out one */
  4604. simulated function AdjustCameraScale(bool bMoveCameraIn)
  4605. {
  4606. if ( !IsFirstPerson() )
  4607. {
  4608. CameraScale = FClamp(CameraScale + (bMoveCameraIn ? -1.0 : 1.0), CameraScaleMin, CameraScaleMax);
  4609. }
  4610. }
  4611.  
  4612. simulated event rotator GetViewRotation()
  4613. {
  4614. local rotator Result;
  4615.  
  4616. //@FIXME: eventually bot Rotation.Pitch will be nonzero?
  4617. if (UTBot(Controller) != None)
  4618. {
  4619. Result = Controller.Rotation;
  4620. Result.Pitch = rotator(Controller.GetFocalPoint() - Location).Pitch;
  4621. return Result;
  4622. }
  4623. else
  4624. {
  4625. return Super.GetViewRotation();
  4626. }
  4627. }
  4628.  
  4629. simulated event TornOff()
  4630. {
  4631. local class<UTDamageType> UTDamage;
  4632.  
  4633. Super.TornOff();
  4634.  
  4635. SetPawnAmbientSound(None);
  4636. SetWeaponAmbientSound(None);
  4637.  
  4638. UTDamage = class<UTDamageType>(HitDamageType);
  4639.  
  4640. if ( UTDamage != None)
  4641. {
  4642. if ( UTDamage.default.DamageOverlayTime > 0 )
  4643. {
  4644. SetBodyMatColor(UTDamage.default.DamageBodyMatColor, UTDamage.default.DamageOverlayTime);
  4645. }
  4646. UTDamage.Static.PawnTornOff(self);
  4647. }
  4648. }
  4649.  
  4650. simulated function SetOverlayVisibility(bool bVisible)
  4651. {
  4652. OverlayMesh.SetOwnerNoSee(!bVisible);
  4653. }
  4654.  
  4655. simulated function TakeFallingDamage()
  4656. {
  4657. local UTPlayerController UTPC;
  4658.  
  4659. Super.TakeFallingDamage();
  4660.  
  4661. if (Velocity.Z < -0.5 * MaxFallSpeed)
  4662. {
  4663. UTPC = UTPlayerController(Controller);
  4664. if(UTPC != None && LocalPlayer(UTPC.Player) != None)
  4665. {
  4666. UTPC.ClientPlayForceFeedbackWaveform(FallingDamageWaveForm);
  4667. }
  4668. }
  4669. }
  4670.  
  4671. simulated event RigidBodyCollision( PrimitiveComponent HitComponent, PrimitiveComponent OtherComponent,
  4672. const out CollisionImpactData RigidCollisionData, int ContactIndex )
  4673. {
  4674. // only check fall damage for Z axis collisions
  4675. if (Abs(RigidCollisionData.ContactInfos[0].ContactNormal.Z) > 0.5)
  4676. {
  4677. Velocity = Mesh.GetRootBodyInstance().PreviousVelocity;
  4678. TakeFallingDamage();
  4679. // zero out the z velocity on the body now so that we don't get stacked collisions
  4680. Velocity.Z = 0.0;
  4681. Mesh.SetRBLinearVelocity(Velocity, false);
  4682. Mesh.GetRootBodyInstance().PreviousVelocity = Velocity;
  4683. Mesh.GetRootBodyInstance().Velocity = Velocity;
  4684. }
  4685. }
  4686.  
  4687. /** Called when an SVehicle wheel physically contacts this Pawn. We kill it! */
  4688. event OnRanOver(SVehicle Vehicle, PrimitiveComponent RunOverComponent, int WheelIndex)
  4689. {
  4690. local UTVehicle UTV;
  4691.  
  4692. if(Role == ROLE_Authority)
  4693. {
  4694. UTV = UTVehicle(Vehicle);
  4695. if(UTV != None)
  4696. {
  4697. TakeDamage( 10000, UTV.Controller, Location, vect(0,0,0), UTV.RanOverDamageType, , Vehicle);
  4698. }
  4699. }
  4700. }
  4701.  
  4702. /** called when we have been stuck falling for a long time with zero velocity
  4703. * and couldn't find a place to move to get out of it
  4704. */
  4705. event StuckFalling()
  4706. {
  4707. if (AIController(Controller) != None)
  4708. {
  4709. Suicide();
  4710. }
  4711. else
  4712. {
  4713. StartedFallingTime = WorldInfo.TimeSeconds;
  4714. }
  4715. }
  4716.  
  4717. /** Kismet hook for kicking a Pawn out of a vehicle */
  4718. function OnExitVehicle(UTSeqAct_ExitVehicle Action)
  4719. {
  4720. if (DrivenVehicle != None)
  4721. {
  4722. DrivenVehicle.DriverLeave(true);
  4723. }
  4724. }
  4725.  
  4726. /** Kismet hook for enabling/disabling infinite ammo for this Pawn */
  4727. function OnInfiniteAmmo(UTSeqAct_InfiniteAmmo Action)
  4728. {
  4729. local UTInventoryManager UTInvManager;
  4730.  
  4731. UTInvManager = UTInventoryManager(InvManager);
  4732. if (UTInvManager != None)
  4733. {
  4734. UTInvManager.bInfiniteAmmo = Action.bInfiniteAmmo;
  4735. }
  4736. }
  4737.  
  4738. function PossessedBy(Controller C, bool bVehicleTransition)
  4739. {
  4740. Super.PossessedBy(C, bVehicleTransition);
  4741. NotifyTeamChanged();
  4742. }
  4743.  
  4744. function bool NeedToTurn(vector targ)
  4745. {
  4746. local vector LookDir, AimDir;
  4747. local UTBot B;
  4748. local float RequiredAim;
  4749.  
  4750. LookDir = Vector(Rotation);
  4751. LookDir.Z = 0;
  4752. LookDir = Normal(LookDir);
  4753. AimDir = targ - Location;
  4754. AimDir.Z = 0;
  4755. AimDir = Normal(AimDir);
  4756.  
  4757. RequiredAim = 0.93;
  4758. B = UTBot(Controller);
  4759. if (B != None)
  4760. {
  4761. RequiredAim += 0.0085 * FClamp(B.Skill, 0.0, 7.0);
  4762. }
  4763. return ((LookDir Dot AimDir) < RequiredAim);
  4764. }
  4765.  
  4766. state FeigningDeath
  4767. {
  4768. ignores ServerHoverboard, SwitchWeapon, FaceRotation, ForceRagdoll, AdjustCameraScale, SetMovementPhysics;
  4769.  
  4770. exec simulated function FeignDeath()
  4771. {
  4772. if (bFeigningDeath)
  4773. {
  4774. Global.FeignDeath();
  4775. }
  4776. }
  4777.  
  4778. reliable server function ServerFeignDeath()
  4779. {
  4780. if (Role == ROLE_Authority && !WorldInfo.GRI.bMatchIsOver && !IsTimerActive('FeignDeathDelayTimer') && bFeigningDeath)
  4781. {
  4782. bFeigningDeath = false;
  4783. PlayFeignDeath();
  4784. }
  4785. }
  4786.  
  4787. event bool EncroachingOn(Actor Other)
  4788. {
  4789. if ( ForcedDirVolume(Other) != None )
  4790. {
  4791. if ( ForcedDirVolume(Other).bBlockPawns && Other.ContainsPoint(Location) )
  4792. {
  4793. TakeDamage(10000, Controller, Location, vect(0,0,0), class'DmgType_Crushed');
  4794. }
  4795. }
  4796. // don't abort moves in ragdoll
  4797. return false;
  4798. }
  4799.  
  4800. simulated function bool CanThrowWeapon()
  4801. {
  4802. return false;
  4803. }
  4804.  
  4805. simulated function Tick(float DeltaTime)
  4806. {
  4807. local rotator NewRotation;
  4808.  
  4809. if (bPlayingFeignDeathRecovery && PlayerController(Controller) != None)
  4810. {
  4811. // interpolate Controller yaw to our yaw so that we don't get our rotation snapped around when we get out of feign death
  4812. NewRotation = Controller.Rotation;
  4813. NewRotation.Yaw = RInterpTo(NewRotation, Rotation, DeltaTime, 2.0).Yaw;
  4814. Controller.SetRotation(NewRotation);
  4815.  
  4816. if ( WorldInfo.TimeSeconds - FeignDeathRecoveryStartTime > 0.8 )
  4817. {
  4818. CameraScale = 1.0;
  4819. }
  4820. }
  4821. }
  4822.  
  4823. simulated function bool CalcThirdPersonCam( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV )
  4824. {
  4825. local vector CamStart, HitLocation, HitNormal, CamDir;
  4826. local RB_BodyInstance RootBodyInst;
  4827. local matrix RootBodyTM;
  4828.  
  4829. if (CurrentCameraScale < CameraScale)
  4830. {
  4831. CurrentCameraScale = FMin(CameraScale, CurrentCameraScale + 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*fDeltaTime);
  4832. }
  4833. else if (CurrentCameraScale > CameraScale)
  4834. {
  4835. CurrentCameraScale = FMax(CameraScale, CurrentCameraScale - 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*fDeltaTime);
  4836. }
  4837.  
  4838. CamStart = Mesh.GetPosition();
  4839. if(Mesh.PhysicsAssetInstance != None)
  4840. {
  4841. RootBodyInst = Mesh.PhysicsAssetInstance.Bodies[Mesh.PhysicsAssetInstance.RootBodyIndex];
  4842. if(RootBodyInst.IsValidBodyInstance())
  4843. {
  4844. RootBodyTM = RootBodyInst.GetUnrealWorldTM();
  4845. CamStart.X = RootBodyTM.WPlane.X;
  4846. CamStart.Y = RootBodyTM.WPlane.Y;
  4847. CamStart.Z = RootBodyTM.WPlane.Z;
  4848. }
  4849. }
  4850. CamStart += vect(0,0,1) * BaseEyeHeight;
  4851.  
  4852. CamDir = vector(out_CamRot) * GetCollisionRadius() * CurrentCameraScale;
  4853. // `log("Mesh"@Mesh.Bounds.Origin@" --- Base Eye Height "@BaseEyeHeight);
  4854.  
  4855. if (CamDir.Z > GetCollisionHeight())
  4856. {
  4857. CamDir *= square(cos(out_CamRot.Pitch * 0.0000958738)); // 0.0000958738 = 2*PI/65536
  4858. }
  4859. out_CamLoc = CamStart - CamDir;
  4860. if (Trace(HitLocation, HitNormal, out_CamLoc, CamStart, false, vect(12,12,12)) != None)
  4861. {
  4862. out_CamLoc = HitLocation;
  4863. }
  4864. return true;
  4865. }
  4866.  
  4867. simulated event OnAnimEnd(AnimNodeSequence SeqNode, float PlayedTime, float ExcessTime)
  4868. {
  4869. if (Physics != PHYS_RigidBody && !bPlayingFeignDeathRecovery)
  4870. {
  4871. // blend out of feign death animation
  4872. if (FeignDeathBlend != None)
  4873. {
  4874. FeignDeathBlend.SetBlendTarget(0.0, 0.5);
  4875. }
  4876. GotoState('Auto');
  4877. }
  4878. }
  4879.  
  4880. simulated event BeginState(name PreviousStateName)
  4881. {
  4882. local UTPlayerController PC;
  4883. local UTWeapon UTWeap;
  4884.  
  4885. PC = UTPlayerController(Controller);
  4886.  
  4887. bCanPickupInventory = false;
  4888. StopFiring();
  4889. bNoWeaponFiring = true;
  4890.  
  4891. UTWeap = UTWeapon(Weapon);
  4892. if (UTWeap != None)
  4893. {
  4894. UTWeap.PlayWeaponPutDown();
  4895. }
  4896. if(UTWeap != none && PC != none)
  4897. {
  4898. PC.EndZoom();
  4899. }
  4900.  
  4901. if (PC != None)
  4902. {
  4903. PC.SetBehindView(true);
  4904. CurrentCameraScale = 1.5;
  4905. CameraScale = 2.25;
  4906. }
  4907.  
  4908. DropFlag();
  4909. }
  4910.  
  4911. simulated function EndState(name NextStateName)
  4912. {
  4913. local UTPlayerController PC;
  4914. local UTPawn P;
  4915. local Actor A;
  4916.  
  4917. if (NextStateName != 'Dying')
  4918. {
  4919. bNoWeaponFiring = default.bNoWeaponFiring;
  4920. bCanPickupInventory = default.bCanPickupInventory;
  4921.  
  4922. ForEach TouchingActors(class'Actor', A)
  4923. {
  4924. if ( (DroppedPickup(A) != None)
  4925. || (PickupFactory(A) != None)
  4926. || (UTCarriedObject(A) != None) )
  4927. {
  4928. A.Touch(self, CylinderComponent, A.Location, Normal(Location - A.Location));
  4929. }
  4930. }
  4931. Global.SetMovementPhysics();
  4932. PC = UTPlayerController(Controller);
  4933. if (PC != None)
  4934. {
  4935. PC.SetBehindView(PC.default.bBehindView);
  4936. }
  4937.  
  4938. CurrentCameraScale = default.CurrentCameraScale;
  4939. CameraScale = default.CameraScale;
  4940. bForcedFeignDeath = false;
  4941. bPlayingFeignDeathRecovery = false;
  4942.  
  4943. // jump away from other feigning death pawns to make sure we don't get stuck
  4944. foreach TouchingActors(class'UTPawn', P)
  4945. {
  4946. if (P.IsInState('FeigningDeath'))
  4947. {
  4948. JumpOffPawn();
  4949. }
  4950. }
  4951. }
  4952. }
  4953. }
  4954.  
  4955. simulated State Dying
  4956. {
  4957. ignores OnAnimEnd, Bump, HitWall, HeadVolumeChange, PhysicsVolumeChange, Falling, BreathTimer, StartFeignDeathRecoveryAnim, ForceRagdoll, FellOutOfWorld;
  4958.  
  4959. exec simulated function FeignDeath();
  4960. reliable server function ServerFeignDeath();
  4961.  
  4962. event bool EncroachingOn(Actor Other)
  4963. {
  4964. // don't abort moves in ragdoll
  4965. return false;
  4966. }
  4967.  
  4968. event Timer()
  4969. {
  4970. local PlayerController PC;
  4971. local bool bBehindAllPlayers;
  4972. local vector ViewLocation;
  4973. local rotator ViewRotation;
  4974.  
  4975. // let the dead bodies stay if the game is over
  4976. if (WorldInfo.GRI != None && WorldInfo.GRI.bMatchIsOver)
  4977. {
  4978. LifeSpan = 0.0;
  4979. return;
  4980. }
  4981.  
  4982. if ( !PlayerCanSeeMe() )
  4983. {
  4984. Destroy();
  4985. return;
  4986. }
  4987. // go away if not viewtarget
  4988. //@todo FIXMESTEVE - use drop detail, get rid of backup visibility check
  4989. bBehindAllPlayers = true;
  4990. ForEach LocalPlayerControllers(class'PlayerController', PC)
  4991. {
  4992. if ( (PC.ViewTarget == self) || (PC.ViewTarget == Base) )
  4993. {
  4994. if ( LifeSpan < 3.5 )
  4995. LifeSpan = 3.5;
  4996. SetTimer(2.0, false);
  4997. return;
  4998. }
  4999.  
  5000. PC.GetPlayerViewPoint( ViewLocation, ViewRotation );
  5001. if ( ((Location - ViewLocation) dot vector(ViewRotation) > 0) )
  5002. {
  5003. bBehindAllPlayers = false;
  5004. break;
  5005. }
  5006. }
  5007. if ( bBehindAllPlayers )
  5008. {
  5009. Destroy();
  5010. return;
  5011. }
  5012. SetTimer(2.0, false);
  5013. }
  5014.  
  5015. /**
  5016. * Calculate camera view point, when viewing this pawn.
  5017. *
  5018. * @param fDeltaTime delta time seconds since last update
  5019. * @param out_CamLoc Camera Location
  5020. * @param out_CamRot Camera Rotation
  5021. * @param out_FOV Field of View
  5022. *
  5023. * @return true if Pawn should provide the camera point of view.
  5024. */
  5025. simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV )
  5026. {
  5027. local vector LookAt;
  5028. local class<UTDamageType> UTDamage;
  5029.  
  5030. UTDamage = class<UTDamageType>(HitDamageType);
  5031. if (UTDamage == None || !UTDamage.default.bSpecialDeathCamera)
  5032. {
  5033.  
  5034. CalcThirdPersonCam(fDeltaTime, out_CamLoc, out_CamRot, out_FOV);
  5035. bStopDeathCamera = bStopDeathCamera || (out_CamLoc.Z < WorldInfo.KillZ);
  5036. if ( bStopDeathCamera && (OldCameraPosition != vect(0,0,0)) )
  5037. {
  5038. // Don't allow camera to go below killz, by re-using old camera position once dead pawn falls below killz
  5039. out_CamLoc = OldCameraPosition;
  5040. LookAt = Location;
  5041. CameraZOffset = (fDeltaTime < 0.2) ? (1 - 5*fDeltaTime) * CameraZOffset : 0.0;
  5042. LookAt.Z += CameraZOffset;
  5043. out_CamRot = rotator(LookAt - out_CamLoc);
  5044. }
  5045. OldCameraPosition = out_CamLoc;
  5046. return true;
  5047. }
  5048. else
  5049. {
  5050. UTDamage.static.CalcDeathCamera(self, fDeltaTime, out_CamLoc, out_CamRot, out_FOV);
  5051. return true;
  5052. }
  5053. }
  5054.  
  5055. simulated event Landed(vector HitNormal, Actor FloorActor)
  5056. {
  5057. local vector BounceDir;
  5058.  
  5059. if( Velocity.Z < -500 )
  5060. {
  5061. BounceDir = 0.5 * (Velocity - 2.0*HitNormal*(Velocity dot HitNormal));
  5062. TakeDamage( (1-Velocity.Z/30), Controller, Location, BounceDir, class'DmgType_Crushed');
  5063. }
  5064. }
  5065.  
  5066. simulated event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
  5067. {
  5068. local Vector shotDir, ApplyImpulse,BloodMomentum;
  5069. local class<UTDamageType> UTDamage;
  5070. local UTEmit_HitEffect HitEffect;
  5071.  
  5072. if ( class'UTGame'.Static.UseLowGore(WorldInfo) )
  5073. {
  5074. if ( !bGibbed )
  5075. {
  5076. UTDamage = class<UTDamageType>(DamageType);
  5077. if (UTDamage != None && ShouldGib(UTDamage))
  5078. {
  5079. bTearOffGibs = true;
  5080. bGibbed = true;
  5081. }
  5082. }
  5083. return;
  5084. }
  5085.  
  5086. // When playing death anim, we keep track of how long since we took that kind of damage.
  5087. if(DeathAnimDamageType != None)
  5088. {
  5089. if(DamageType == DeathAnimDamageType)
  5090. {
  5091. TimeLastTookDeathAnimDamage = WorldInfo.TimeSeconds;
  5092. }
  5093. }
  5094.  
  5095. if (!bGibbed && (InstigatedBy != None || EffectIsRelevant(Location, true, 0)))
  5096. {
  5097. UTDamage = class<UTDamageType>(DamageType);
  5098.  
  5099. // accumulate damage taken in a single tick
  5100. if ( AccumulationTime != WorldInfo.TimeSeconds )
  5101. {
  5102. AccumulateDamage = 0;
  5103. AccumulationTime = WorldInfo.TimeSeconds;
  5104. }
  5105. AccumulateDamage += Damage;
  5106.  
  5107. Health -= Damage;
  5108. if ( UTDamage != None )
  5109. {
  5110. if ( ShouldGib(UTDamage) )
  5111. {
  5112. if ( bHideOnListenServer || (WorldInfo.NetMode == NM_DedicatedServer) )
  5113. {
  5114. bTearOffGibs = true;
  5115. bGibbed = true;
  5116. return;
  5117. }
  5118. SpawnGibs(UTDamage, HitLocation);
  5119. }
  5120. else if ( !bHideOnListenServer && (WorldInfo.NetMode != NM_DedicatedServer) )
  5121. {
  5122. CheckHitInfo( HitInfo, Mesh, Normal(Momentum), HitLocation );
  5123. UTDamage.Static.SpawnHitEffect(self, Damage, Momentum, HitInfo.BoneName, HitLocation);
  5124.  
  5125. if ( UTDamage.default.bCausesBlood && !class'UTGame'.Static.UseLowGore(WorldInfo)
  5126. && ((PlayerController(Controller) == None) || (WorldInfo.NetMode != NM_Standalone)) )
  5127. {
  5128. BloodMomentum = Momentum;
  5129. if ( BloodMomentum.Z > 0 )
  5130. BloodMomentum.Z *= 0.5;
  5131. HitEffect = Spawn(GetFamilyInfo().default.BloodEmitterClass,self,, HitLocation, rotator(BloodMomentum));
  5132. HitEffect.AttachTo(Self,HitInfo.BoneName);
  5133. }
  5134.  
  5135. if ( (UTDamage.default.DamageOverlayTime > 0) && (UTDamage.default.DamageBodyMatColor != class'UTDamageType'.default.DamageBodyMatColor) )
  5136. {
  5137. SetBodyMatColor(UTDamage.default.DamageBodyMatColor, UTDamage.default.DamageOverlayTime);
  5138. }
  5139.  
  5140. if( (Physics != PHYS_RigidBody) || (Momentum == vect(0,0,0)) || (HitInfo.BoneName == '') )
  5141. return;
  5142.  
  5143. shotDir = Normal(Momentum);
  5144. ApplyImpulse = (DamageType.Default.KDamageImpulse * shotDir);
  5145.  
  5146. if( UTDamage.Default.bThrowRagdoll && (Velocity.Z > -10) )
  5147. {
  5148. ApplyImpulse += Vect(0,0,1)*DamageType.default.KDeathUpKick;
  5149. }
  5150. // AddImpulse() will only wake up the body for the bone we hit, so force the others to wake up
  5151. Mesh.WakeRigidBody();
  5152. Mesh.AddImpulse(ApplyImpulse, HitLocation, HitInfo.BoneName, true);
  5153. }
  5154. }
  5155. }
  5156. }
  5157.  
  5158. /** Tick only if bio death effect */
  5159. simulated event Tick(FLOAT DeltaSeconds)
  5160. {
  5161. local float BurnLevel;
  5162. local int i;
  5163. local MaterialInstanceConstant MyMIC;
  5164.  
  5165. // tick only if bio death effect
  5166. if ( !bKilledByBio || (Mesh == None) )
  5167. {
  5168. Disable('Tick');
  5169. }
  5170. else
  5171. {
  5172. // first, how far into the burn are we: (scale of 0-9.9)
  5173. BurnLevel = FMin(((WorldInfo.TimeSeconds-DeathTime)/BioBurnAwayTime*10.0),9.9);
  5174. for ( i=0; i<Mesh.Materials.Length; i++ )
  5175. {
  5176. MyMIC = MaterialInstanceConstant(Mesh.Materials[i]);
  5177. if (MyMIC != None)
  5178. {
  5179. MyMIC.SetScalarParameterValue(BioEffectName, BurnLevel);
  5180. }
  5181. }
  5182. if (BurnLevel >= 9.9)
  5183. {
  5184. BioBurnAway.DeactivateSystem();
  5185. bKilledByBio = FALSE; // no need to loop this in anymore.
  5186. Disable('Tick');
  5187. }
  5188. }
  5189. }
  5190.  
  5191. simulated function BeginState(Name PreviousStateName)
  5192. {
  5193. Super.BeginState(PreviousStateName);
  5194. CustomGravityScaling = 1.0;
  5195. DeathTime = WorldInfo.TimeSeconds;
  5196. CylinderComponent.SetActorCollision(false, false);
  5197.  
  5198. if ( bTearOff && (bHideOnListenServer || (WorldInfo.NetMode == NM_DedicatedServer)) )
  5199. LifeSpan = 1.0;
  5200. else
  5201. {
  5202. if ( Mesh != None )
  5203. {
  5204. Mesh.SetTraceBlocking(true, true);
  5205. Mesh.SetActorCollision(true, false);
  5206.  
  5207. // Move into post so that we are hitting physics from last frame, rather than animated from this
  5208. Mesh.SetTickGroup(TG_PostAsyncWork);
  5209. }
  5210. SetTimer(2.0, false);
  5211. LifeSpan = RagDollLifeSpan;
  5212. }
  5213. }
  5214. }
  5215.  
  5216. /** This will determine and then return the FamilyInfo for this pawn **/
  5217. simulated function class<UTFamilyInfo> GetFamilyInfo()
  5218. {
  5219. local UTPlayerReplicationInfo UTPRI;
  5220.  
  5221. UTPRI = GetUTPlayerReplicationInfo();
  5222. if (UTPRI != None)
  5223. {
  5224. return UTPRI.CharClassInfo;
  5225. }
  5226.  
  5227. return CurrCharClassInfo;
  5228. }
  5229.  
  5230. simulated function PostTeleport(Teleporter OutTeleporter)
  5231. {
  5232. Super.PostTeleport(OutTeleporter);
  5233.  
  5234. BigTeleportCount++;
  5235. PostBigTeleport();
  5236. }
  5237.  
  5238. /** Called when teleporting */
  5239. simulated function PostBigTeleport()
  5240. {
  5241. ForceUpdateComponents();
  5242. Mesh.UpdateRBBonesFromSpaceBases(TRUE, TRUE);
  5243. }
  5244.  
  5245. exec function BackSpring(float LinSpring)
  5246. {
  5247. local RB_BodyInstance BodyInst;
  5248. local RB_BodySetup BodySetup;
  5249. local int i;
  5250.  
  5251. for(i=0; i<Mesh.PhysicsAsset.BodySetup.Length; i++)
  5252. {
  5253. BodyInst = Mesh.PhysicsAssetInstance.Bodies[i];
  5254. BodySetup = Mesh.PhysicsAsset.BodySetup[i];
  5255.  
  5256. if (BodySetup.BoneName == 'b_Spine2')
  5257. {
  5258. BodyInst.SetBoneSpringParams(LinSpring, BodyInst.BoneLinearDamping, 0.1*LinSpring, BodyInst.BoneAngularDamping);
  5259. }
  5260. }
  5261.  
  5262. //`log("Hip Spring set to "$LinSpring);
  5263. }
  5264.  
  5265. exec function BackDamp(float LinDamp)
  5266. {
  5267. local RB_BodyInstance BodyInst;
  5268. local RB_BodySetup BodySetup;
  5269. local int i;
  5270.  
  5271. for(i=0; i<Mesh.PhysicsAsset.BodySetup.Length; i++)
  5272. {
  5273. BodyInst = Mesh.PhysicsAssetInstance.Bodies[i];
  5274. BodySetup = Mesh.PhysicsAsset.BodySetup[i];
  5275.  
  5276. if (BodySetup.BoneName == 'b_Spine2')
  5277. {
  5278. BodyInst.SetBoneSpringParams(BodyInst.BoneLinearSpring, LinDamp, BodyInst.BoneAngularDamping, LinDamp);
  5279. }
  5280. }
  5281.  
  5282. //`log("Hip Damp set to "$LinDamp);
  5283. }
  5284.  
  5285. exec function HandSpring(float LinSpring)
  5286. {
  5287. local RB_BodyInstance BodyInst;
  5288. local RB_BodySetup BodySetup;
  5289. local int i;
  5290.  
  5291. for(i=0; i<Mesh.PhysicsAsset.BodySetup.Length; i++)
  5292. {
  5293. BodyInst = Mesh.PhysicsAssetInstance.Bodies[i];
  5294. BodySetup = Mesh.PhysicsAsset.BodySetup[i];
  5295.  
  5296. if (BodySetup.BoneName == 'b_RightHand' || BodySetup.BoneName == 'b_LeftHand')
  5297. {
  5298. BodyInst.SetBoneSpringParams(LinSpring, BodyInst.BoneLinearDamping, 0.1*LinSpring, BodyInst.BoneAngularDamping);
  5299. }
  5300. }
  5301.  
  5302. //`log("Hip Spring set to "$LinSpring);
  5303. }
  5304.  
  5305. exec function HandDamp(float LinDamp)
  5306. {
  5307. local RB_BodyInstance BodyInst;
  5308. local RB_BodySetup BodySetup;
  5309. local int i;
  5310.  
  5311. for(i=0; i<Mesh.PhysicsAsset.BodySetup.Length; i++)
  5312. {
  5313. BodyInst = Mesh.PhysicsAssetInstance.Bodies[i];
  5314. BodySetup = Mesh.PhysicsAsset.BodySetup[i];
  5315.  
  5316. if (BodySetup.BoneName == 'b_RightHand' || BodySetup.BoneName == 'b_LeftHand')
  5317. {
  5318. BodyInst.SetBoneSpringParams(BodyInst.BoneLinearSpring, LinDamp, BodyInst.BoneAngularDamping, LinDamp);
  5319. }
  5320. }
  5321.  
  5322. //`log("Hip Damp set to "$LinDamp);
  5323. }
  5324.  
  5325. defaultproperties
  5326. {
  5327. Components.Remove(Sprite)
  5328.  
  5329. Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
  5330. bSynthesizeSHLight=TRUE
  5331. bIsCharacterLightEnvironment=TRUE
  5332. bUseBooleanEnvironmentShadowing=FALSE
  5333. InvisibleUpdateTime=1
  5334. MinTimeBetweenFullUpdates=.2
  5335. End Object
  5336. Components.Add(MyLightEnvironment)
  5337. LightEnvironment=MyLightEnvironment
  5338.  
  5339. Begin Object Class=SkeletalMeshComponent Name=WPawnSkeletalMeshComponent
  5340. bCacheAnimSequenceNodes=FALSE
  5341. AlwaysLoadOnClient=true
  5342. AlwaysLoadOnServer=true
  5343. bOwnerNoSee=true
  5344. CastShadow=true
  5345. BlockRigidBody=TRUE
  5346. bUpdateSkelWhenNotRendered=false
  5347. bIgnoreControllersWhenNotRendered=TRUE
  5348. bUpdateKinematicBonesFromAnimation=true
  5349. bCastDynamicShadow=true
  5350. Translation=(Z=8.0)
  5351. RBChannel=RBCC_Untitled3
  5352. RBCollideWithChannels=(Untitled3=true)
  5353. LightEnvironment=MyLightEnvironment
  5354. bOverrideAttachmentOwnerVisibility=true
  5355. bAcceptsDynamicDecals=FALSE
  5356. AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'
  5357. bHasPhysicsAssetInstance=true
  5358. TickGroup=TG_PreAsyncWork
  5359. MinDistFactorForKinematicUpdate=0.2
  5360. bChartDistanceFactor=true
  5361. //bSkipAllUpdateWhenPhysicsAsleep=TRUE
  5362. RBDominanceGroup=20
  5363. Scale=1.075
  5364. // Nice lighting for hair
  5365. bUseOnePassLightingOnTranslucency=TRUE
  5366. bPerBoneMotionBlur=true
  5367. End Object
  5368. Mesh=WPawnSkeletalMeshComponent
  5369. Components.Add(WPawnSkeletalMeshComponent)
  5370.  
  5371. DefaultMeshScale=1.075
  5372. BaseTranslationOffset=6.0
  5373.  
  5374. Begin Object Name=OverlayMeshComponent0 Class=SkeletalMeshComponent
  5375. Scale=1.015
  5376. bAcceptsDynamicDecals=FALSE
  5377. CastShadow=false
  5378. bOwnerNoSee=true
  5379. bUpdateSkelWhenNotRendered=false
  5380. bOverrideAttachmentOwnerVisibility=true
  5381. TickGroup=TG_PostAsyncWork
  5382. bPerBoneMotionBlur=true
  5383. End Object
  5384. OverlayMesh=OverlayMeshComponent0
  5385.  
  5386. Begin Object class=AnimNodeSequence Name=MeshSequenceA
  5387. End Object
  5388.  
  5389. Begin Object class=AnimNodeSequence Name=MeshSequenceB
  5390. End Object
  5391.  
  5392. Begin Object Class=UDKSkeletalMeshComponent Name=FirstPersonArms
  5393. PhysicsAsset=None
  5394. FOV=55
  5395. Animations=MeshSequenceA
  5396. DepthPriorityGroup=SDPG_Foreground
  5397. bUpdateSkelWhenNotRendered=false
  5398. bIgnoreControllersWhenNotRendered=true
  5399. bOnlyOwnerSee=true
  5400. bOverrideAttachmentOwnerVisibility=true
  5401. bAcceptsDynamicDecals=FALSE
  5402. AbsoluteTranslation=false
  5403. AbsoluteRotation=true
  5404. AbsoluteScale=true
  5405. bSyncActorLocationToRootRigidBody=false
  5406. CastShadow=false
  5407. TickGroup=TG_DuringASyncWork
  5408. End Object
  5409. ArmsMesh[0]=FirstPersonArms
  5410.  
  5411. Begin Object Class=UDKSkeletalMeshComponent Name=FirstPersonArms2
  5412. PhysicsAsset=None
  5413. FOV=55
  5414. Scale3D=(Y=-1.0)
  5415. Animations=MeshSequenceB
  5416. DepthPriorityGroup=SDPG_Foreground
  5417. bUpdateSkelWhenNotRendered=false
  5418. bIgnoreControllersWhenNotRendered=true
  5419. bOnlyOwnerSee=true
  5420. bOverrideAttachmentOwnerVisibility=true
  5421. HiddenGame=true
  5422. bAcceptsDynamicDecals=FALSE
  5423. AbsoluteTranslation=false
  5424. AbsoluteRotation=true
  5425. AbsoluteScale=true
  5426. bSyncActorLocationToRootRigidBody=false
  5427. CastShadow=false
  5428. TickGroup=TG_DuringASyncWork
  5429. End Object
  5430. ArmsMesh[1]=FirstPersonArms2
  5431.  
  5432. Begin Object Name=CollisionCylinder
  5433. CollisionRadius=+0021.000000
  5434. CollisionHeight=+0044.000000
  5435. End Object
  5436. CylinderComponent=CollisionCylinder
  5437.  
  5438. Begin Object Class=UTAmbientSoundComponent name=AmbientSoundComponent
  5439. End Object
  5440. PawnAmbientSound=AmbientSoundComponent
  5441. Components.Add(AmbientSoundComponent)
  5442.  
  5443. Begin Object Class=UTAmbientSoundComponent name=AmbientSoundComponent2
  5444. End Object
  5445. WeaponAmbientSound=AmbientSoundComponent2
  5446. Components.Add(AmbientSoundComponent2)
  5447.  
  5448. ViewPitchMin=-18000
  5449. ViewPitchMax=18000
  5450.  
  5451. WalkingPct=+0.4
  5452. CrouchedPct=+0.4
  5453. BaseEyeHeight=38.0
  5454. EyeHeight=38.0
  5455. GroundSpeed=440.0
  5456. AirSpeed=440.0
  5457. WaterSpeed=220.0
  5458. DodgeSpeed=600.0
  5459. DodgeSpeedZ=295.0
  5460. AccelRate=2048.0
  5461. JumpZ=322.0
  5462. CrouchHeight=29.0
  5463. CrouchRadius=21.0
  5464. WalkableFloorZ=0.78
  5465.  
  5466. AlwaysRelevantDistanceSquared=+1960000.0
  5467. InventoryManagerClass=class'UTInventoryManager'
  5468.  
  5469. MeleeRange=+20.0
  5470. bMuffledHearing=true
  5471.  
  5472. Buoyancy=+000.99000000
  5473. UnderWaterTime=+00020.000000
  5474. bCanStrafe=True
  5475. bCanSwim=true
  5476. RotationRate=(Pitch=20000,Yaw=20000,Roll=20000)
  5477. MaxLeanRoll=2048
  5478. AirControl=+0.35
  5479. DefaultAirControl=+0.35
  5480. bCanCrouch=true
  5481. bCanClimbLadders=True
  5482. bCanPickupInventory=True
  5483. bCanDoubleJump=true
  5484. SightRadius=+12000.0
  5485.  
  5486. MaxMultiJump=1
  5487. MultiJumpRemaining=1
  5488. MultiJumpBoost=-45.0
  5489.  
  5490. SoundGroupClass=class'UTGame.UTPawnSoundGroup'
  5491.  
  5492. TransInEffects(0)=class'UTEmit_TransLocateOutRed'
  5493. TransInEffects(1)=class'UTEmit_TransLocateOut'
  5494.  
  5495. MaxStepHeight=26.0
  5496. MaxJumpHeight=49.0
  5497. MaxDoubleJumpHeight=87.0
  5498. DoubleJumpEyeHeight=43.0
  5499.  
  5500. HeadRadius=+9.0
  5501. HeadHeight=5.0
  5502. HeadScale=+1.0
  5503. HeadOffset=32
  5504.  
  5505. SpawnProtectionColor=(R=40,G=40)
  5506. TranslocateColor[0]=(R=20)
  5507. TranslocateColor[1]=(B=20)
  5508. DamageParameterName=DamageOverlay
  5509. SaturationParameterName=Char_DistSatRangeMultiplier
  5510.  
  5511. TeamBeaconMaxDist=3000.f
  5512. TeamBeaconPlayerInfoMaxDist=3000.f
  5513. RagdollLifespan=18.0
  5514.  
  5515. bPhysRigidBodyOutOfWorldCheck=TRUE
  5516. bRunPhysicsWithNoController=true
  5517.  
  5518. ControllerClass=class'UTGame.UTBot'
  5519.  
  5520. CurrentCameraScale=1.0
  5521. CameraScale=9.0
  5522. CameraScaleMin=3.0
  5523. CameraScaleMax=40.0
  5524.  
  5525. LeftFootControlName=LeftFootControl
  5526. RightFootControlName=RightFootControl
  5527. bEnableFootPlacement=true
  5528. MaxFootPlacementDistSquared=56250000.0 // 7500 squared
  5529.  
  5530. SlopeBoostFriction=0.2
  5531. bStopOnDoubleLanding=true
  5532. DoubleJumpThreshold=160.0
  5533. FireRateMultiplier=1.0
  5534.  
  5535. ArmorHitSound=SoundCue'A_Gameplay.Gameplay.A_Gameplay_ArmorHitCue'
  5536. SpawnSound=SoundCue'A_Gameplay.A_Gameplay_PlayerSpawn01Cue'
  5537. TeleportSound=SoundCue'A_Weapon_Translocator.Translocator.A_Weapon_Translocator_Teleport_Cue'
  5538.  
  5539. MaxFallSpeed=+1250.0
  5540. AIMaxFallSpeedFactor=1.1 // so bots will accept a little falling damage for shorter routes
  5541. LastPainSound=-1000.0
  5542.  
  5543. FeignDeathBodyAtRestSpeed=12.0
  5544. bReplicateRigidBodyLocation=true
  5545.  
  5546. MinHoverboardInterval=0.7
  5547. HoverboardClass=class'UTVehicle_Hoverboard'
  5548.  
  5549. FeignDeathPhysicsBlendOutSpeed=2.0
  5550. TakeHitPhysicsBlendOutSpeed=0.5
  5551.  
  5552. TorsoBoneName=b_Spine2
  5553. FallImpactSound=SoundCue'A_Character_BodyImpacts.BodyImpacts.A_Character_BodyImpact_BodyFall_Cue'
  5554. FallSpeedThreshold=125.0
  5555.  
  5556. SuperHealthMax=199
  5557.  
  5558. // moving here for now until we can fix up the code to have it pass in the armor object
  5559. ShieldBeltMaterialInstance=Material'Pickups.Armor_ShieldBelt.M_ShieldBelt_Overlay'
  5560. ShieldBeltTeamMaterialInstances(0)=Material'Pickups.Armor_ShieldBelt.M_ShieldBelt_Red'
  5561. ShieldBeltTeamMaterialInstances(1)=Material'Pickups.Armor_ShieldBelt.M_ShieldBelt_Blue'
  5562. ShieldBeltTeamMaterialInstances(2)=Material'Pickups.Armor_ShieldBelt.M_ShieldBelt_Red'
  5563. ShieldBeltTeamMaterialInstances(3)=Material'Pickups.Armor_ShieldBelt.M_ShieldBelt_Blue'
  5564.  
  5565. HeroCameraPitch=6000
  5566. HeroCameraScale=6.0
  5567.  
  5568. //@TEXTURECHANGEFIXME - Needs actual UV's for the Player Icon
  5569. IconCoords=(U=657,V=129,UL=68,VL=58)
  5570. MapSize=1.0
  5571.  
  5572. // default bone names
  5573. WeaponSocket=WeaponPoint
  5574. WeaponSocket2=DualWeaponPoint
  5575. HeadBone=b_Head
  5576. PawnEffectSockets[0]=L_JB
  5577. PawnEffectSockets[1]=R_JB
  5578.  
  5579.  
  5580. MinTimeBetweenEmotes=1.0
  5581.  
  5582. DeathHipLinSpring=10000.0
  5583. DeathHipLinDamp=500.0
  5584. DeathHipAngSpring=10000.0
  5585. DeathHipAngDamp=500.0
  5586.  
  5587. bWeaponAttachmentVisible=true
  5588.  
  5589. TransCameraAnim[0]=CameraAnim'Envy_Effects.Camera_Shakes.C_Res_IN_Red'
  5590. TransCameraAnim[1]=CameraAnim'Envy_Effects.Camera_Shakes.C_Res_IN_Blue'
  5591. TransCameraAnim[2]=CameraAnim'Envy_Effects.Camera_Shakes.C_Res_IN'
  5592.  
  5593. MaxFootstepDistSq=9000000.0
  5594. MaxJumpSoundDistSq=16000000.0
  5595.  
  5596. SwimmingZOffset=-30.0
  5597. SwimmingZOffsetSpeed=45.0
  5598.  
  5599. TauntNames(0)=TauntA
  5600. TauntNames(1)=TauntB
  5601. TauntNames(2)=TauntC
  5602. TauntNames(3)=TauntD
  5603. TauntNames(4)=TauntE
  5604. TauntNames(5)=TauntF
  5605.  
  5606. Begin Object Class=ForceFeedbackWaveform Name=ForceFeedbackWaveformFall
  5607. Samples(0)=(LeftAmplitude=50,RightAmplitude=40,LeftFunction=WF_Sin90to180,RightFunction=WF_Sin90to180,Duration=0.200)
  5608. End Object
  5609. FallingDamageWaveForm=ForceFeedbackWaveformFall
  5610.  
  5611. CamOffset=(X=4.0,Y=16.0,Z=-13.0)
  5612. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement