Guest User

Untitled

a guest
May 12th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class GVBreakable extends InterpActor
  2.     DependsOn(GVEffectActor);
  3.  
  4. // Static mesh for this state
  5. struct SBreakableState
  6. {      
  7.     var() StaticMesh StaticMesh; // Effects to create when entering this state 
  8.     var() array<sGVEffect> Effects; // When the breakable's health is below this, it will activate this state. This is a percentage representation of the health, thus keep values between 0.f and 1.f 
  9.     var() float HealthPercentage<UIMin=0|UIMax=1>; // When the breakable's health is below this, it will activate this state. This is the actual health, thus keep values between 0 and Health
  10. };
  11.  
  12. // Health of the breakable
  13. var(GVBreakable) int Health;
  14. // Minimum damage that must be exceeded to cause damage to the breakable
  15. var(GVBreakable) float MinimumDamage;
  16.  
  17. // Breakable states
  18. var(GVBreakable) array<SBreakableState> BreakableStates;
  19. // Hide if breakable is below zero health
  20. var(GVBreakable) bool HideWhenDead;
  21. // Disable collision if breakable is below zero health
  22. var(GVBreakable) bool DisableCollisionWhenDead;
  23. // Time delay, in seconds, between each state change
  24. var(GVBreakable) float StateChangeInterval;
  25.  
  26. // Damage caused to other actors in the vicinity when the breakable dies
  27. var(GVBreakable) float DamageOnDeath;
  28. // Radius of the damage, use a value less than or equal to zero to disable
  29. var(GVBreakable) float DamageOnDeathRadius;
  30. // Damage type to use when radial damage is done on death
  31. var(GVBreakable) class<DamageType> DamageTypeOnDeath;
  32. // Damage momentum to use when radial damage is done on death
  33. var(GVBreakable) float DamageMomentumOnDeath;
  34. // Apply linear fall off from the damage applied to victims when radial damage is done on death
  35. var(GVBreakable) bool LinearFallOffDamageOnDeath;
  36. // Apply vertical offset to damage location. This is useful if the breakable is positioned on the floor, as their static meshes have the pivot point aligned to the base of the mesh
  37. var(GVBreakable) bool ApplyVerticalOffsetOnRadialDamageLocation;
  38.  
  39. var array<GVEffectActor> EffectActors;
  40. var int HealthMax;
  41. var int CurrentStateIndex;
  42. var int DesiredStateIndex;
  43.  
  44. simulated function PostBeginPlay()
  45. {
  46.     local SBreakableState BreakableState;
  47.  
  48.     Super.PostBeginPlay();
  49.  
  50.     HealthMax = Health;
  51.  
  52.     if (BreakableStates.Length > 0)
  53.     {
  54.         // Add HealthPercentage == 0.f if it doesn't exist
  55.         if (BreakableStates.Find('HealthPercentage', 0.f) == INDEX_NONE)
  56.         {
  57.             BreakableState.StaticMesh = StaticMeshComponent.StaticMesh;
  58.             BreakableState.HealthPercentage = 0.f;
  59.             BreakableStates.AddItem(BreakableState);
  60.         }
  61.  
  62.         // Add HealthPercentage == 1.f if it doesn't exist
  63.         if (BreakableStates.Find('HealthPercentage', 1.f) == INDEX_NONE)
  64.         {
  65.             BreakableState.StaticMesh = BreakableStates[BreakableStates.Length - 1].StaticMesh;
  66.             BreakableState.HealthPercentage = 1.f;
  67.             BreakableStates.Insert(0, 1);
  68.             BreakableStates[0] = BreakableState;
  69.         }
  70.     }
  71. }
  72.  
  73. event TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
  74. {
  75.     local int i;
  76.     local float HealthPercentage;
  77.     local float BoundingCylinderRadius, BoundingCylinderHeight;
  78.     local Vector DamageLocation;
  79.  
  80.     // Abort this function if the damage amount is less than the minimum damage
  81.     if (DamageAmount < MinimumDamage)
  82.     {
  83.         return;
  84.     }
  85.  
  86.     Super.TakeDamage(DamageAmount, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser);
  87.     Health -= DamageAmount;
  88.  
  89.     if (Health < 0)
  90.     {
  91.         // Kismet event triggering
  92.         TriggerEventClass(class'SeqEvent_Destroyed', DamageCauser);
  93.  
  94.         if (DamageOnDeathRadius > 0.f)
  95.         {
  96.             DamageLocation = Location;
  97.  
  98.             if (ApplyVerticalOffsetOnRadialDamageLocation)
  99.             {
  100.                 GetBoundingCylinder(BoundingCylinderRadius, BoundingCylinderHeight);
  101.                 DamageLocation.Z += BoundingCylinderHeight;
  102.             }
  103.  
  104.             HurtRadius(DamageOnDeath, DamageOnDeathRadius, DamageTypeOnDeath, DamageMomentumOnDeath, DamageLocation, Self, None, !LinearFallOffDamageOnDeath);
  105.         }
  106.  
  107.         if (HideWhenDead)
  108.         {
  109.             SetHidden(true);
  110.         }
  111.  
  112.         if (DisableCollisionWhenDead)
  113.         {
  114.             SetCollision(false, false, false);
  115.         }
  116.     }
  117.     else
  118.     {
  119.         if (BreakableStates.Length > 0)
  120.         {      
  121.             HealthPercentage = float(Health) / float(HealthMax);
  122.    
  123.             // Get the next state index
  124.             for (i = 0; i < BreakableStates.Length - 1; ++i)
  125.             {          
  126.                 if (BreakableStates[i].HealthPercentage >= HealthPercentage && BreakableStates[i + 1].HealthPercentage <= HealthPercentage && DesiredStateIndex != i)
  127.                 {
  128.                     // The new state that we wish to switch to is only 1 difference away
  129.                     if (Abs(i - CurrentStateIndex) == 1)
  130.                     {
  131.                         CurrentStateIndex = i;
  132.                         SetState();
  133.                     }
  134.                     else // The new state is a few states away, so we want to interpolate to it
  135.                     {  
  136.                         DesiredStateIndex = i;
  137.  
  138.                         if (DesiredStateIndex > CurrentStateIndex)
  139.                         {
  140.                             ++CurrentStateIndex;
  141.                         }
  142.                         else if (DesiredStateIndex < CurrentStateIndex)
  143.                         {
  144.                             --CurrentStateIndex;
  145.                         }
  146.  
  147.                         SetState();
  148.                         SetTimer(StateChangeInterval, true, NameOf(SetStateTimer));                    
  149.                     }
  150.  
  151.                     break;
  152.                 }
  153.             }
  154.         }
  155.     }
  156. }
  157.  
  158. function SetStateTimer()
  159. {
  160.     if (DesiredStateIndex > CurrentStateIndex)
  161.     {
  162.         ++CurrentStateIndex;
  163.     }
  164.     else if (DesiredStateIndex < CurrentStateIndex)
  165.     {
  166.         --CurrentStateIndex;
  167.     }
  168.  
  169.     if (CurrentStateIndex == DesiredStateIndex)
  170.     {
  171.         SetState();
  172.         ClearTimer(NameOf(SetStateTimer));
  173.     }
  174.     else
  175.     {
  176.         SetState(false);
  177.     }
  178. }
  179.  
  180. function SetState(optional bool CreateEffects = true)
  181. {
  182.     // Handle previous effect destruction
  183.     if (EffectActors.Length >= 0)
  184.     {
  185.         class'GVEffectActor'.static.StopAndDestroyEffectArray(EffectActors);
  186.         EffectActors.Length = 0;
  187.     }
  188.  
  189.     // Handle creation of effects for this state
  190.     if (CreateEffects && BreakableStates[CurrentStateIndex].Effects.Length > 0)
  191.     {
  192.         EffectActors = class'GVEffectActor'.static.CreateEffects(BreakableStates[CurrentStateIndex].Effects, Self);
  193.     }
  194.  
  195.     if (StaticMeshComponent != None)
  196.     {
  197.         StaticMeshComponent.SetStaticMesh(BreakableStates[CurrentStateIndex].StaticMesh);
  198.     }
  199. }
  200.  
  201. defaultproperties
  202. {
  203.     Health=100
  204.     HideWhenDead=true
  205.     DisableCollisionWhenDead=true
  206.     StateChangeInterval=0.0166667f
  207.     LinearFallOffDamageOnDeath=true
  208.  
  209.     Begin Object Class=DynamicLightEnvironmentComponent Name=BreakableLightEnvironment
  210.         bEnabled=false
  211.         bDynamic=false
  212.     End Object
  213.     LightEnvironment=BreakableLightEnvironment
  214.     Components.Add(BreakableLightEnvironment)
  215.  
  216.     Begin Object Name=StaticMeshComponent0
  217.         bUsePrecomputedShadows=true
  218.         BlockRigidBody=true
  219.         LightEnvironment=BreakableLightEnvironment
  220.     End Object
  221.  
  222.     CollisionType=COLLIDE_BlockAll
  223.     BlockRigidBody=true
  224.     bCollideActors=true
  225.     bBlockActors=true
  226.  
  227.     SupportedEvents.Empty
  228.     SupportedEvents(0)=class'SeqEvent_Touch'
  229.     SupportedEvents(1)=class'SeqEvent_Destroyed'
  230.     SupportedEvents(2)=class'SeqEvent_TakeDamage'
  231.     SupportedEvents(3)=class'SeqEvent_Mover'
  232. }
Add Comment
Please, Sign In to add comment