Guest User

PWNWeapon.cpp

a guest
Mar 11th, 2015
227
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2.  
  3. #include "PWNGame.h"
  4. #include "PWNPlayerCharacter.h"
  5. #include "PWNWeapon.h"
  6.  
  7.  
  8. APWNWeapon::APWNWeapon(const class FPostConstructInitializeProperties& PCIP)
  9.     : Super(PCIP)
  10. {      
  11.     this->SetActorHiddenInGame(true);
  12.  
  13.     // We must tick
  14.     PrimaryActorTick.bCanEverTick = true;
  15.    
  16.     // Dummy root component
  17.     RootComponentDummy = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("RootComponentDummy"));
  18.     RootComponent = RootComponentDummy;
  19.    
  20.     // Defaults
  21.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_Inactive;
  22.     ArmStateNextTimeLeft = 0.0f;
  23.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_Inactive;
  24.  
  25.     // Arm Comp
  26.     Arm = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("Arm"));
  27.     Arm->SetHiddenInGame(true, false);
  28.     Arm->AttachParent = RootComponentDummy;
  29.     ArmRelativeLocation = FVector(0.0f, 0.0f, -30.0f);
  30.     ArmRelativeScale = 0.75f * FVector(1.0f, 1.0f, 1.0f);  
  31.    
  32.     // Weapon Comp
  33.     Weapon = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("Weapon"));
  34.     Weapon->SetHiddenInGame(true, false);
  35.     Weapon->SetRelativeScale3D(WeaponRelativeScale);
  36.  
  37.     // DamageType
  38.     DamageTypeClass = UPWNDamageType::StaticClass();
  39. }
  40.  
  41. void APWNWeapon::PostInitializeComponents()
  42. {
  43.     Super::PostInitializeComponents(); 
  44. }
  45.  
  46. void APWNWeapon::BeginPlay()
  47. {  
  48.     //UPWNGameGlobals::PrintOnscreenString(TEXT("BeginPlay - APWNWeapon"));
  49.     Super::BeginPlay();
  50. }
  51.  
  52. /**************************************/
  53. /*** Asset Loaders and Initialisers ***/
  54. /**************************************/
  55. USkeletalMesh* APWNWeapon::LoadSkeletalMeshFromPath(FString path)
  56. {  
  57.     return Cast<USkeletalMesh>(StaticLoadObject(USkeletalMesh::StaticClass(), NULL, *path));
  58. }
  59.  
  60. UAnimBlueprintGeneratedClass* APWNWeapon::LoadAnimBlueprintGeneratedClassFromPath(FString path)
  61. {
  62.     return Cast<UAnimBlueprintGeneratedClass>(StaticLoadObject(UAnimBlueprintGeneratedClass::StaticClass(), NULL, *path));
  63. }
  64.  
  65. void APWNWeapon::Init(bool isInLeftHand)
  66. {
  67.     // Hand
  68.     IsInLeftHand = isInLeftHand;
  69.  
  70.     // Set our own constructor references
  71.     SetAssetReferences_Base();
  72.     SetAssetReferences_Specific();
  73.  
  74.     // Spawn our required assets
  75.     SpawnAssets_Base();
  76.     SpawnAssets_Specific();
  77.  
  78.     // Set our assets  
  79.     SetAssets_Base();  
  80.     SetAssets_Specific();
  81. }
  82.  
  83. void APWNWeapon::SetAssetReferences_Base()
  84. {
  85.     // Arm
  86.     //TODO: Move these out to another function as ALL weapons will use them
  87.     ConstRefArmMeshLeftName = TEXT("SkeletalMesh'/Game/PWNGame/FPSArms/Mesh/FPSArm_Left.FPSArm_Left'");
  88.     ConstRefArmMeshRightName = TEXT("SkeletalMesh'/Game/PWNGame/FPSArms/Mesh/FPSArm_Right.FPSArm_Right'");
  89.     ConstRefArmAnimBlueprintLeftClassName = TEXT("AnimBlueprintGeneratedClass'/Game/PWNGame/FPSArms/Mesh/FPSArm_Left_AnimBlueprint.FPSArm_Left_AnimBlueprint_C'");
  90.     ConstRefArmAnimBlueprintRightClassName = TEXT("AnimBlueprintGeneratedClass'/Game/PWNGame/FPSArms/Mesh/FPSArm_Right_AnimBlueprint.FPSArm_Right_AnimBlueprint_C'");  
  91. }
  92.  
  93. void APWNWeapon::SetAssetReferences_Specific()
  94. {      
  95.     // Anims - Basic
  96.     ConstRef_ArmAnimSet_Basic_Left_BP.Empty();
  97.     ConstRef_ArmAnimSet_Basic_Right_BP.Empty();
  98.  
  99.     // Anims - Attacking
  100.     ConstRef_ArmAnimSet_Attacking_Left_BP.Empty();
  101.     ConstRef_ArmAnimSet_Attacking_Right_BP.Empty();
  102.  
  103.     // Weapon
  104.     ConstRefWeaponMeshName = TEXT("");
  105.     WeaponSocketName = TEXT("HandSocket");
  106.     WeaponRotationOffsetLeft = FVector(0.0f, 0.0f, 0.0f);
  107.     WeaponRotationOffsetRight = FVector(0.0f, 0.0f, 0.0f);
  108. }
  109.  
  110.  
  111. void APWNWeapon::SpawnAssets_Base()
  112. {
  113.     /***********/
  114.     /*** Arm ***/
  115.     /***********/
  116.     // Arm Mesh
  117.     if (ConstRefArmMeshLeftName.IsEmpty() || ConstRefArmMeshRightName.IsEmpty())
  118.     {
  119.         //UPWNGameGlobals::PrintOnscreenString("No ConstRefArmMeshLeftName mesh specified.");
  120.     }
  121.     else
  122.     {
  123.         // Load arm mesh asset from path
  124.         ArmMesh = LoadSkeletalMeshFromPath(IsInLeftHand ? ConstRefArmMeshLeftName : ConstRefArmMeshRightName);
  125.     }
  126.  
  127.     // Arm Anim Blueprint
  128.     if (ConstRefArmAnimBlueprintLeftClassName.IsEmpty() || ConstRefArmAnimBlueprintRightClassName.IsEmpty())
  129.     {
  130.         //UPWNGameGlobals::PrintOnscreenString("No ConstRefArmAnimBlueprintLeftClassName mesh specified.");
  131.     }
  132.     else
  133.     {
  134.         ArmAnimBlueprintClass = LoadAnimBlueprintGeneratedClassFromPath(IsInLeftHand ? ConstRefArmAnimBlueprintLeftClassName : ConstRefArmAnimBlueprintRightClassName);
  135.     }
  136.  
  137.     // Interpleaders
  138.     InterpLeaderYaw = NewObject<UPWNInterpLeader>(UPWNInterpLeader::StaticClass());
  139. }
  140.  
  141. void APWNWeapon::SpawnAssets_Specific()
  142. {
  143.     // Get world object for spawning
  144.     UWorld* world = GetWorld();
  145.  
  146.     // Arm Anim Set - Basic
  147.     if (ConstRef_ArmAnimSet_Basic_Left_BP.IsEmpty() || ConstRef_ArmAnimSet_Basic_Right_BP.IsEmpty())
  148.     {
  149.         //UPWNGameGlobals::PrintOnscreenString("No ConstRefArmAnimSetLeftClassName mesh specified.");
  150.     }
  151.     else
  152.     {      
  153.         // Get AnimsetClass
  154.         TSubclassOf<APWNAnimSet_Basic> armAnimSetClass_Basic = LoadPWNAnimSetBlueprintFromPath_Basic(IsInLeftHand ? ConstRef_ArmAnimSet_Basic_Left_BP : ConstRef_ArmAnimSet_Basic_Right_BP);
  155.  
  156.         // Spawn animset
  157.         if (world && armAnimSetClass_Basic)
  158.         {
  159.             ArmAnimSet_Basic = world->SpawnActor<APWNAnimSet_Basic>(armAnimSetClass_Basic);
  160.         }
  161.        
  162.     }
  163.  
  164.     if (world)
  165.     {
  166.         Spawn_AnimSet_Attacking_Instance(world, IsInLeftHand ? ConstRef_ArmAnimSet_Attacking_Left_BP : ConstRef_ArmAnimSet_Attacking_Right_BP, ArmAnimSet_Attacking);
  167.     }
  168.  
  169.     // Set relative dimensions 
  170.     Arm->SetRelativeLocation(ArmRelativeLocation);
  171.     Arm->SetRelativeScale3D(ArmRelativeScale);
  172.  
  173.     /**************/
  174.     /*** Weapon ***/
  175.     /**************/
  176.     // Arm Meshes  
  177.     if (ConstRefWeaponMeshName.IsEmpty())
  178.     {
  179.         //UPWNGameGlobals::PrintOnscreenString("No weapon mesh specified.");
  180.     }
  181.     else
  182.     {
  183.         WeaponMesh = LoadSkeletalMeshFromPath(ConstRefWeaponMeshName);
  184.         Weapon->SetRelativeScale3D(WeaponRelativeScale);
  185.     }
  186.     /**************/
  187. }
  188.  
  189. void APWNWeapon::Spawn_AnimSet_Attacking_Instance(UWorld* worldRef, FString animSetAttackingAssetRef, APWNAnimSet_Attacking* &animSetAttackingToAssignTo)
  190. {
  191.     // Arm Anim Set - Attacking
  192.     if (animSetAttackingAssetRef.IsEmpty())
  193.     {
  194.         //UPWNGameGlobals::PrintOnscreenString("AnimSetAttackingAssetRef is Empty. Not spawning Animset: " + animSetAttackingAssetRef);
  195.     }
  196.     else
  197.     {
  198.         // Get AnimsetClass
  199.         TSubclassOf<APWNAnimSet_Attacking> armAnimSetClass_Attacking = LoadPWNAnimSetBlueprintFromPath_Attacking(animSetAttackingAssetRef);
  200.  
  201.         // Spawn animset
  202.         if (armAnimSetClass_Attacking)
  203.         {
  204.             animSetAttackingToAssignTo = worldRef->SpawnActor<APWNAnimSet_Attacking>(armAnimSetClass_Attacking);
  205.         }
  206.     }
  207. }
  208.  
  209. TSubclassOf<APWNAnimSet_Basic> APWNWeapon::LoadPWNAnimSetBlueprintFromPath_Basic(FString path)
  210. {
  211.     // Get anim blueprint
  212.     UBlueprint* bluePrint = Cast<UBlueprint>(StaticLoadObject(UBlueprint::StaticClass(), NULL, *path));
  213.  
  214.     // Cast and return class
  215.     if (bluePrint)
  216.         return Cast<UClass>(bluePrint->GeneratedClass);
  217.     else
  218.         return nullptr;
  219. }
  220.  
  221. TSubclassOf<APWNAnimSet_Attacking> APWNWeapon::LoadPWNAnimSetBlueprintFromPath_Attacking(FString path)
  222. {
  223.     // Get anim blueprint
  224.     UBlueprint* bluePrint = Cast<UBlueprint>(StaticLoadObject(UBlueprint::StaticClass(), NULL, *path));
  225.  
  226.     // Cast and return class
  227.     if (bluePrint)
  228.         return Cast<UClass>(bluePrint->GeneratedClass);
  229.     else
  230.         return nullptr;
  231. }
  232.  
  233. void APWNWeapon::SetAssets_Base()
  234. {
  235.     /***********/
  236.     /*** Arm ***/
  237.     /***********/
  238.     // Set Skel Mesh       
  239.     if (ArmMesh)
  240.         Arm->SetSkeletalMesh(ArmMesh);
  241.     else
  242.     {
  243.         UPWNGameGlobals::PrintOnscreenString("ArmMesh is NULL. Aborting.");
  244.         return;
  245.     }
  246.  
  247.     // Set anim blueprint  
  248.     if (ArmAnimBlueprintClass)
  249.     {
  250.         Arm->AnimBlueprintGeneratedClass = ArmAnimBlueprintClass;
  251.  
  252.         // Arm Anim Instance
  253.         Arm->InitializeAnimScriptInstance();
  254.         ArmAnimInstance = Cast<UPWNWeaponAnimInstance>(Arm->GetAnimInstance());
  255.  
  256.         if (ArmAnimInstance)
  257.         {
  258.             ArmAnimEndDelegate.BindUObject(this, &APWNWeapon::ArmAnimEndedNotify);
  259.         }
  260.     }
  261.     else
  262.     {
  263.         UPWNGameGlobals::PrintOnscreenString("ArmAnimBlueprintClass is NULL. No animations will be played.");
  264.     }  
  265.     /***********/
  266. }
  267.  
  268. void APWNWeapon::SetAssets_Specific()
  269. {  
  270.     /***********/
  271.     /*** Arm ***/
  272.     /***********/
  273.  
  274.     /**************/
  275.     /*** Weapon ***/
  276.     /**************/
  277.     if (Arm && Weapon && WeaponMesh)
  278.     {
  279.         Weapon->SetSkeletalMesh(WeaponMesh);
  280.  
  281.         if (!WeaponSocketName.IsNone())
  282.         {
  283.             Weapon->AttachTo(Arm, WeaponSocketName);
  284.  
  285.             if (IsInLeftHand)
  286.                 Weapon->SetRelativeRotation(FRotator::MakeFromEuler(WeaponRotationOffsetLeft));
  287.             else
  288.                 Weapon->SetRelativeRotation(FRotator::MakeFromEuler(WeaponRotationOffsetRight));
  289.         }
  290.     }
  291.     /**************/
  292. }
  293.  
  294. /**************************************/
  295.  
  296.  
  297. void APWNWeapon::Tick(float DeltaTime)
  298. {  
  299.     if (ArmStateNext != EWeaponStateEnum::WEAPONSTATE_Inactive)
  300.     {
  301.         ArmStateNextCheckTransition(DeltaTime);    
  302.     }
  303.  
  304.     Super::Tick(DeltaTime);
  305. }
  306.  
  307. void APWNWeapon::UpdateDisplay(float deltaTime, FRotator newRotation, FVector newLocation)
  308. {
  309.    
  310.     FRotator appliedRot = newRotation; 
  311.  
  312.     // Ensure we use correct rotators - todo
  313.     float dYaw, dPitch, newYaw;
  314.     dYaw = FMath::Abs(newRotation.Yaw - PrevRot.Yaw);
  315.     dPitch = FMath::Abs(newRotation.Pitch - PrevRot.Pitch);
  316.     dYaw = FMath::Max(0.001f, dYaw);
  317.     newYaw = InterpLeaderYaw->Update(deltaTime, newRotation.Yaw);
  318.  
  319.     if ((dYaw > dPitch) || (FMath::Abs(InterpLeaderYaw->Interp) > 0.01f))
  320.         appliedRot.Yaw = newYaw;
  321.  
  322.     SetActorRotation(appliedRot);
  323.     SetActorLocation(newLocation);
  324.  
  325.     PrevRot = newRotation;
  326. }
  327.  
  328.  
  329. /*************/
  330. /*** DEBUG ***/
  331. /*************/
  332. void APWNWeapon::PWNDebugTest()
  333. {
  334.     UPWNGameGlobals::PrintOnscreenString("MONTAGE ENDED");
  335. }
  336. /*************/
  337.  
  338. /**************************/
  339. /*** Playing Animations ***/
  340. /**************************/
  341. bool APWNWeapon::SetArmAnimSet_Attacking(APWNAnimSet_Attacking* animSetToUse)
  342. {
  343.     if (animSetToUse)
  344.     {
  345.         ArmAnimSet_Attacking = animSetToUse;
  346.         return true;
  347.     }
  348.     else
  349.         return false;  
  350. }
  351.  
  352. UAnimMontage* APWNWeapon::FindArmAnim(EWeaponStateEnum::EWeaponState animState)
  353. {
  354.     UAnimMontage* anim = nullptr;
  355.  
  356.     switch (animState)
  357.     {
  358.     case EWeaponStateEnum::WEAPONSTATE_Equipping:
  359.         anim = ArmAnimSet_Basic->Anim_Equipping;
  360.         break;
  361.     case EWeaponStateEnum::WEAPONSTATE_Idling:
  362.         anim = ArmAnimSet_Basic->Anim_Idles[0];
  363.         break;
  364.     case EWeaponStateEnum::WEAPONSTATE_AttackPreparing:
  365.         anim = (ArmAnimSet_Attacking) ? ArmAnimSet_Attacking->Anim_AttackPreparing : nullptr;
  366.         break;
  367.     case EWeaponStateEnum::WEAPONSTATE_PreAttacking:
  368.         anim = (ArmAnimSet_Attacking) ? ArmAnimSet_Attacking->Anim_PreAttacking : nullptr;
  369.         break;
  370.     case EWeaponStateEnum::WEAPONSTATE_Attacking:
  371.         anim = (ArmAnimSet_Attacking) ? ArmAnimSet_Attacking->Anim_Attacking : nullptr;
  372.         break;
  373.     case EWeaponStateEnum::WEAPONSTATE_PostAttacking:
  374.         anim = (ArmAnimSet_Attacking) ? ArmAnimSet_Attacking->Anim_PostAttacking : nullptr;
  375.         break;
  376.     case EWeaponStateEnum::WEAPONSTATE_AttackReturning:
  377.         anim = (ArmAnimSet_Attacking) ? ArmAnimSet_Attacking->Anim_AttackReturning : nullptr;
  378.         break;
  379.     case EWeaponStateEnum::WEAPONSTATE_AttackRebounding:
  380.         anim = (ArmAnimSet_Attacking) ? ArmAnimSet_Attacking->Anim_AttackRebounding : nullptr;
  381.         break;
  382.     case EWeaponStateEnum::WEAPONSTATE_AttackRebounded:
  383.         anim = (ArmAnimSet_Attacking) ? ArmAnimSet_Attacking->Anim_AttackRebounded : nullptr;
  384.         break;
  385.     case EWeaponStateEnum::WEAPONSTATE_AttackReboundReturning:
  386.         anim = (ArmAnimSet_Attacking) ? ArmAnimSet_Attacking->Anim_AttackReboundReturning : nullptr;
  387.         break;
  388.     case EWeaponStateEnum::WEAPONSTATE_ReloadPreparing:
  389.         anim = ArmAnimSet_Basic->Anim_ReloadPreparing;
  390.         break;
  391.     case EWeaponStateEnum::WEAPONSTATE_Reloading:
  392.         anim = ArmAnimSet_Basic->Anim_Reloading;
  393.         break;
  394.     case EWeaponStateEnum::WEAPONSTATE_ReloadReturning:
  395.         anim = ArmAnimSet_Basic->Anim_ReloadReturning;
  396.         break;
  397.     case EWeaponStateEnum::WEAPONSTATE_PuttingDown:
  398.         anim = ArmAnimSet_Basic->Anim_PuttingDown;
  399.         break;
  400.     case EWeaponStateEnum::WEAPONSTATE_Inactive:
  401.         anim = ArmAnimSet_Basic->Anim_Inactive;
  402.         break;
  403.     }
  404.        
  405.     //UPWNGameGlobals::PrintOnscreenString(TEXT("Could not find Anim, because Animset is null!"));
  406.     return anim;
  407. }
  408.  
  409. float APWNWeapon::PlayArmAnim(EWeaponStateEnum::EWeaponState weaponState, float const rate, float const startingPosPct)
  410. {
  411.     // Find the actual montage to play
  412.     UAnimMontage* animToPlay = FindArmAnim(weaponState);
  413.  
  414.     if (!animToPlay)
  415.     {  
  416.         //UPWNGameGlobals::PrintOnscreenString(TEXT("Arm animation is null."), GetWeaponsStateString(weaponState));    
  417.         return -1.0f;      
  418.     }
  419.  
  420.     if (!ArmAnimInstance)
  421.     {
  422.         //UPWNGameGlobals::PrintOnscreenString(TEXT("Arm anim instance is null: "), GetWeaponsStateString(weaponState));
  423.         return -1.0f;
  424.     }
  425.  
  426.     // Play anim
  427.     float const currAnimDuration = ArmAnimInstance->Montage_Play(animToPlay, rate) / (animToPlay->RateScale);  
  428.  
  429.     // Reregister our OnMontageEnded event
  430.     ArmAnimInstance->Montage_SetEndDelegate(ArmAnimEndDelegate);
  431.  
  432.     float startingPos = 0.0f;
  433.    
  434.     if (startingPosPct > 0.0f)
  435.     {
  436.         UPWNGameGlobals::PrintOnscreenFloat(currAnimDuration);
  437.         UPWNGameGlobals::PrintOnscreenFloat(startingPosPct);
  438.         startingPos = currAnimDuration * startingPosPct;
  439.         //ArmAnimInstance->Montage_SetPosition(animToPlay, startingPos);
  440.         ArmAnimInstance->Montage_SetPosition(animToPlay, startingPosPct);
  441.        
  442.     }
  443.  
  444.     Arm->RefreshBoneTransforms();
  445.     //UPWNGameGlobals::PrintOnscreenString(TEXT("Playing arm anim: "), GetWeaponsStateString(weaponState));
  446.     //return currAnimDuration - startingPos;
  447.     return currAnimDuration - startingPosPct;
  448. }
  449. /**************************/
  450.  
  451. /**************/
  452. /*** States ***/
  453. /**************/
  454. void APWNWeapon::AttackStart(TEnumAsByte<EMovementDirectionEnum::EMovementDirection> attackDirection)
  455. {
  456.     if (ArmStateCurrent == EWeaponStateEnum::WEAPONSTATE_Idling)
  457.     {      
  458.         AttackDirection = attackDirection;
  459.         UpdateAttackDirectionAnimset();
  460.         ArmState_AttackPreparing_Start();
  461.     }
  462. }
  463. void APWNWeapon::AttackStop(){}
  464. void APWNWeapon::UpdateAttackDirectionAnimset(){}
  465.  
  466.  
  467. void APWNWeapon::Equip()
  468. {
  469.     // Unhide us
  470.     this->SetActorHiddenInGame(false);
  471.     Arm->SetHiddenInGame(false, true);
  472.     Weapon->SetHiddenInGame(false, true);
  473.  
  474.     // Start equipping sequence
  475.     ArmState_Equipping_Start();
  476. }
  477.  
  478. float APWNWeapon::GetActiveMontagePosition(USkeletalMeshComponent* skelComp)
  479. {
  480.     UAnimInstance* animInstance = skelComp->GetAnimInstance();
  481.  
  482.     if (animInstance)
  483.     {
  484.         FAnimMontageInstance* currMontage = animInstance->GetActiveMontageInstance();
  485.  
  486.         if (currMontage)
  487.         {
  488.             return currMontage->Position;
  489.         }
  490.     }
  491.  
  492.     return -1.0f;
  493. }
  494.  
  495. float APWNWeapon::GetActiveMontageLength(USkeletalMeshComponent* skelComp)
  496. {
  497.     UAnimInstance* animInstance = skelComp->GetAnimInstance();
  498.  
  499.     if (animInstance)
  500.     {
  501.         FAnimMontageInstance* currMontage = animInstance->GetActiveMontageInstance();
  502.  
  503.         if (currMontage)
  504.         {
  505.             if (currMontage->Montage)
  506.                 return currMontage->Montage->SequenceLength;
  507.         }
  508.     }
  509.  
  510.     return -1.0f;
  511. }
  512.  
  513. FMontageDetails APWNWeapon::GetActiveMontageDetails(USkeletalMeshComponent* skelComp)
  514. {
  515.     FMontageDetails details;
  516.     details.Length = -1.0f;
  517.     details.Position = -1.0f;
  518.     details.Name = TEXT("NONE");
  519.  
  520.     UAnimInstance* animInstance = skelComp->GetAnimInstance();
  521.  
  522.     if (animInstance)
  523.     {
  524.         FAnimMontageInstance* currMontage = animInstance->GetActiveMontageInstance();
  525.  
  526.         if (currMontage)
  527.         {
  528.             details.Position = currMontage->Position;
  529.            
  530.             if (currMontage->Montage)
  531.             {
  532.                 details.Length = currMontage->Montage->SequenceLength;
  533.                 details.Name = currMontage->Montage->GetName();
  534.             }
  535.         }
  536.     }
  537.  
  538.     return details;
  539. }
  540.  
  541. void APWNWeapon::SetActiveMontagePosition(USkeletalMeshComponent* skelComp, float pos)
  542. {
  543.     UAnimInstance* animInstance = skelComp->GetAnimInstance();
  544.  
  545.     if (animInstance)
  546.     {
  547.         FAnimMontageInstance* currMontage = animInstance->GetActiveMontageInstance();
  548.  
  549.         if (currMontage)
  550.         {
  551.             if (currMontage->Montage)
  552.                 currMontage->Position = pos;
  553.         }
  554.     }  
  555. }
  556.  
  557. void APWNWeapon::ArmStateNextCheckTransition(float deltaTime)
  558. {
  559.     // Minimum time left before end of anim before we transition
  560.     float minTimeLeftBeforeTrans = 1.0f * deltaTime;
  561.    
  562.     // Update how long we've spent in this state
  563.     ArmStateCurrentTimeSpent += deltaTime;
  564.  
  565.     // Check whether we must transition
  566.     if (ArmStateNextTimeLeft > minTimeLeftBeforeTrans)
  567.         ArmStateNextTimeLeft -= deltaTime;// DIV BY WORLDINFO.GAMESPEED
  568.  
  569.     // Most accurate check - First line of defense
  570.     if (ArmAnimInstance)
  571.     {
  572.         float currMontagePos = GetActiveMontagePosition(Arm);
  573.         float currMontageLength = GetActiveMontageLength(Arm);
  574.  
  575.         if (currMontagePos >= 0.0f && currMontageLength > 0.0f)
  576.         {
  577.             if (currMontagePos > currMontageLength - minTimeLeftBeforeTrans)
  578.             {
  579.                 ArmStateNextHandleTransition(0.0f);
  580.                 return;
  581.             }
  582.         }
  583.     }
  584.  
  585.     // Hacky check - Second line of defense if we ever run into problems
  586.     if (ArmStateNextTimeLeft < minTimeLeftBeforeTrans)
  587.     {
  588.         //UPWNGameGlobals::PrintOnscreenString("TRANS VIA METHOD 2!");
  589.         ArmStateNextHandleTransition(0.0f);
  590.     }
  591.    
  592. }
  593.  
  594. void APWNWeapon::ArmAnimEndedNotify(UAnimMontage* montage, bool bInterrupted)
  595. {
  596.     //UPWNGameGlobals::PrintOnscreenString("Anim Ended: " + montage->GetName());
  597. }
  598.  
  599. void APWNWeapon::ArmStateNextHandleTransition(float startPosPct)
  600. {
  601.     switch (ArmStateNext)
  602.     {
  603.         case EWeaponStateEnum::WEAPONSTATE_Equipping:          
  604.             ArmState_Equipping_Start(startPosPct);
  605.             break;
  606.         case EWeaponStateEnum::WEAPONSTATE_Idling:
  607.             ArmState_Idling_Start(startPosPct);
  608.             break;
  609.         case EWeaponStateEnum::WEAPONSTATE_AttackPreparing:
  610.             ArmState_AttackPreparing_Start(startPosPct);
  611.             break;
  612.         case EWeaponStateEnum::WEAPONSTATE_PreAttacking:
  613.             ArmState_PreAttacking_Start(startPosPct);
  614.             break;
  615.         case EWeaponStateEnum::WEAPONSTATE_Attacking:
  616.             ArmState_Attacking_Start(startPosPct);
  617.             break;
  618.         case EWeaponStateEnum::WEAPONSTATE_PostAttacking:
  619.             ArmState_PostAttacking_Start(startPosPct);
  620.             break;
  621.         case EWeaponStateEnum::WEAPONSTATE_AttackReturning:
  622.             ArmState_AttackReturning_Start(startPosPct);
  623.             break;
  624.         case EWeaponStateEnum::WEAPONSTATE_ReloadPreparing:
  625.             ArmState_ReloadPreparing_Start(startPosPct);
  626.             break;
  627.         case EWeaponStateEnum::WEAPONSTATE_Reloading:
  628.             ArmState_Reloading_Start(startPosPct);
  629.             break;
  630.         case EWeaponStateEnum::WEAPONSTATE_ReloadReturning:
  631.             ArmState_ReloadReturning_Start(startPosPct);
  632.             break;
  633.         case EWeaponStateEnum::WEAPONSTATE_PuttingDown:
  634.             ArmState_PuttingDown_Start(startPosPct);
  635.             break;
  636.         case EWeaponStateEnum::WEAPONSTATE_AttackRebounding:
  637.             ArmState_AttackRebounding_Start(startPosPct);
  638.             break;
  639.         case EWeaponStateEnum::WEAPONSTATE_AttackRebounded:
  640.             ArmState_AttackRebounded_Start(startPosPct);
  641.             break;
  642.         case EWeaponStateEnum::WEAPONSTATE_AttackReboundReturning:
  643.             ArmState_AttackReboundReturning_Start(startPosPct);
  644.             break;
  645.         case EWeaponStateEnum::WEAPONSTATE_Inactive:
  646.             ArmState_Inactive_Start(startPosPct);
  647.             break;
  648.         default:           
  649.             break;
  650.     }
  651.  
  652.     ArmStateCurrentTimeSpent = 0.0f;
  653. }
  654.  
  655. void APWNWeapon::ArmStateCheckSkipToNext()
  656. {
  657.     if (ArmStateNextTimeLeft < 0.0f)
  658.     {
  659.         ArmStateCurrent = ArmStateNext;
  660.         ArmStateNext = (EWeaponStateEnum::EWeaponState)((uint8)ArmStateNext + 1);
  661.         ArmStateNextTimeLeft = 0.0f;
  662.     }
  663. }
  664.  
  665. void APWNWeapon::ArmState_Equipping_Start(float startPosPct)
  666. {
  667.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_Equipping; 
  668.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_Idling;
  669.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  670.     ArmStateCheckSkipToNext();
  671. }
  672.  
  673. void APWNWeapon::ArmState_Idling_Start(float startPosPct)
  674. {
  675.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_Idling;
  676.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_Idling;
  677.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  678.     // We do NOT check for state skipping here, as idling has no auto next state
  679. }
  680.  
  681. void APWNWeapon::ArmState_AttackPreparing_Start(float startPosPct)
  682. {
  683.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_AttackPreparing;
  684.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_PreAttacking;
  685.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  686.     ArmStateCheckSkipToNext();
  687. }
  688.  
  689. //
  690. void APWNWeapon::ArmState_PreAttacking_Start(float startPosPct)
  691. {
  692.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_PreAttacking;
  693.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_Attacking;
  694.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  695.     ArmStateCheckSkipToNext();
  696. }
  697.  
  698. void APWNWeapon::ArmState_Attacking_Start(float startPosPct)
  699. {
  700.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_Attacking;
  701.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_PostAttacking;
  702.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  703.     ArmStateCheckSkipToNext();
  704. }
  705.  
  706. void APWNWeapon::ArmState_PostAttacking_Start(float startPosPct)
  707. {
  708.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_PostAttacking;
  709.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_AttackReturning;
  710.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  711.     ArmStateCheckSkipToNext();
  712. }
  713.  
  714. void APWNWeapon::ArmState_AttackReturning_Start(float startPosPct)
  715. {
  716.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_AttackReturning;
  717.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_Idling;
  718.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  719.     // We do NOT check for state skipping here, as this is the last state in our attack sequence.
  720. }
  721.  
  722. void APWNWeapon::ArmState_AttackRebounding_Start(float startPosPct)
  723. {  
  724.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_AttackRebounding;
  725.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_AttackRebounded;
  726.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  727.     ArmStateCheckSkipToNext();
  728. }
  729.  
  730. void APWNWeapon::ArmState_AttackRebounded_Start(float startPosPct)
  731. {  
  732.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_AttackRebounded;
  733.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_AttackReboundReturning;
  734.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  735.     ArmStateCheckSkipToNext();
  736. }
  737.  
  738. void APWNWeapon::ArmState_AttackReboundReturning_Start(float startPosPct)
  739. {  
  740.     ArmStateCurrent = EWeaponStateEnum::WEAPONSTATE_AttackReboundReturning;
  741.     ArmStateNext = EWeaponStateEnum::WEAPONSTATE_Idling;
  742.     ArmStateNextTimeLeft = PlayArmAnim(ArmStateCurrent, 1.0f, startPosPct);
  743.     ArmStateCheckSkipToNext();
  744. }
  745.  
  746. /********************/
  747. /*** Other states ***/
  748. /********************/
  749. void APWNWeapon::ArmState_ReloadPreparing_Start(float startPosPct){}
  750. void APWNWeapon::ArmState_Reloading_Start(float startPosPct){}
  751. void APWNWeapon::ArmState_ReloadReturning_Start(float startPosPct){}
  752. void APWNWeapon::ArmState_PuttingDown_Start(float startPosPct){}
  753. void APWNWeapon::ArmState_Inactive_Start(float startPosPct){}
  754. ///**************/
  755.  
  756. UPWNSerialiser* APWNWeapon::Serialise()
  757. {
  758.     // Create my serialiser - if I'm NOT a parent class in inheritance
  759.     UPWNSerialiser* mySaveData = NewObject<UPWNSerialiser>(this, UPWNSerialiser::StaticClass());
  760.  
  761.     // Save my basic data
  762.     // No need to store location and rotation as those are set by character when spawning
  763.     mySaveData->AddNumericValue(TEXT("ArmStateCurrent"), uint8(ArmStateCurrent));
  764.     mySaveData->AddNumericValue(TEXT("ArmStateNext"), uint8(ArmStateNext));
  765.     mySaveData->AddNumericValue(TEXT("ArmStateNextTimeLeft"), ArmStateNextTimeLeft);
  766.     mySaveData->AddNumericValue(TEXT("ArmStateCurrentTimeSpent"), ArmStateCurrentTimeSpent);
  767.    
  768.     // Current anim progress
  769.     float armCurrMontagePos = GetActiveMontagePosition(Arm);
  770.     mySaveData->AddNumericValue(TEXT("ArmAnimCurrentPosition"), (armCurrMontagePos >= 0.0f) ? armCurrMontagePos : 0.0f);
  771.  
  772.     return mySaveData;
  773. }
  774.  
  775. void APWNWeapon::DeSerialise(UPWNSerialiser* mySavedData)
  776. {
  777.     // Arm current state
  778.     uint8 armStateCurrent;
  779.     mySavedData->LoadNumericValue(TEXT("ArmStateCurrent"), armStateCurrent);
  780.     ArmStateNext = (EWeaponStateEnum::EWeaponState)armStateCurrent;
  781.  
  782.     // Arm current anim
  783.     float armAnimCurrPos;
  784.     mySavedData->LoadNumericValue(TEXT("ArmAnimCurrentPosition"), armAnimCurrPos);
  785.     ArmStateNextHandleTransition(armAnimCurrPos);
  786. }
RAW Paste Data