diff --git a/Config/DefaultInput.ini b/Config/DefaultInput.ini index 282be6b..f96b4be 100644 --- a/Config/DefaultInput.ini +++ b/Config/DefaultInput.ini @@ -15,6 +15,7 @@ bUseMouseForTouch=False +ActionMappings=(ActionName="PreviousWeapon",Key=MouseScrollDown,bShift=False,bCtrl=False,bAlt=False,bCmd=False) +ActionMappings=(ActionName="LastWeapon",Key=Q,bShift=False,bCtrl=False,bAlt=False,bCmd=False) +ActionMappings=(ActionName="ChangeFiremode",Key=B,bShift=False,bCtrl=False,bAlt=False,bCmd=False) ++ActionMappings=(ActionName="Reload",Key=R,bShift=False,bCtrl=False,bAlt=False,bCmd=False) +AxisMappings=(AxisName="MoveForward",Key=W,Scale=1.000000) +AxisMappings=(AxisName="MoveForward",Key=S,Scale=-1.000000) +AxisMappings=(AxisName="MoveForward",Key=Up,Scale=1.000000) diff --git a/Content/Blueprints/AmmoCounter.uasset b/Content/Blueprints/AmmoCounter.uasset new file mode 100644 index 0000000..2d518c5 Binary files /dev/null and b/Content/Blueprints/AmmoCounter.uasset differ diff --git a/Content/Blueprints/EmpiresCharacter.uasset b/Content/Blueprints/EmpiresCharacter.uasset index b539cb4..9e124f9 100644 Binary files a/Content/Blueprints/EmpiresCharacter.uasset and b/Content/Blueprints/EmpiresCharacter.uasset differ diff --git a/Content/Blueprints/Weapons/BE_Heavy_Rifle.uasset b/Content/Blueprints/Weapons/BE_Heavy_Rifle.uasset index 9d18f43..ba6c095 100644 Binary files a/Content/Blueprints/Weapons/BE_Heavy_Rifle.uasset and b/Content/Blueprints/Weapons/BE_Heavy_Rifle.uasset differ diff --git a/Content/Blueprints/Weapons/BE_Rifle.uasset b/Content/Blueprints/Weapons/BE_Rifle.uasset index 60c0691..e3527af 100644 Binary files a/Content/Blueprints/Weapons/BE_Rifle.uasset and b/Content/Blueprints/Weapons/BE_Rifle.uasset differ diff --git a/Source/Empires2/Private/Empires2Character.cpp b/Source/Empires2/Private/Empires2Character.cpp index 413cbf7..b6280d9 100644 --- a/Source/Empires2/Private/Empires2Character.cpp +++ b/Source/Empires2/Private/Empires2Character.cpp @@ -83,6 +83,7 @@ void AEmpires2Character::SetupPlayerInputComponent(class UInputComponent* InputC InputComponent->BindAction("PreviousWeapon", IE_Pressed, this, &AEmpires2Character::SelectPreviousWeapon); InputComponent->BindAction("LastWeapon", IE_Pressed, this, &AEmpires2Character::SelectLastWeapon); InputComponent->BindAction("ChangeFiremode", EInputEvent::IE_Pressed, this, &AEmpires2Character::ChangeFiremode); + InputComponent->BindAction("Reload", EInputEvent::IE_Pressed, this, &AEmpires2Character::ReloadWeapon); //Movement @@ -237,7 +238,15 @@ void AEmpires2Character::SelectLastWeapon() void AEmpires2Character::ChangeFiremode() { UBaseInfantryWeapon* Weapon = GetActiveWeapon(); - if (Weapon == nullptr) return; //No weapon? Don't bother chaning firemode + if (Weapon == nullptr) return; //No weapon? Don't bother changing firemode Weapon->NextFiremode(); +} + +void AEmpires2Character::ReloadWeapon() +{ + UBaseInfantryWeapon* Weapon = GetActiveWeapon(); + if (Weapon == nullptr) return; //No weapon? Don't bother reloading + + Weapon->Reload(); } \ No newline at end of file diff --git a/Source/Empires2/Private/Weapons/BaseEmpiresWeapon.cpp b/Source/Empires2/Private/Weapons/BaseEmpiresWeapon.cpp index 24e730b..c9e6587 100644 --- a/Source/Empires2/Private/Weapons/BaseEmpiresWeapon.cpp +++ b/Source/Empires2/Private/Weapons/BaseEmpiresWeapon.cpp @@ -13,7 +13,7 @@ UBaseEmpiresWeapon::UBaseEmpiresWeapon(const class FPostConstructInitializePrope GunOffset = FVector(100.0f, 30.0f, 10.0f); ActiveFiremode = 0; - + bReloading = false; } //////////////////////GENERAL @@ -97,13 +97,24 @@ bool UBaseEmpiresWeapon::CanFire() { UBaseFiremode* firemode = GetActiveFiremode(); if (firemode == nullptr) return false; //No active firemode + if (bReloading) return false; //Can't fire when we are reloading + if (GetCurrentAmmoPool().AmmoInClip <= 0) return false; //If we have no ammo, we can't fire + //TODO: Check if the firemode is capable of firing + return true; } void UBaseEmpiresWeapon::BeginFire() { + if (!CanFire()) return; //Don't Fire if we can't fire + if (GetCurrentAmmoPool().AmmoInClip <= 0) //If we are out of ammo, attempt to reload + { + Reload(); + return; + } + UBaseFiremode* firemode = GetActiveFiremode(); check(firemode); firemode->BeginFire(); @@ -155,12 +166,30 @@ void UBaseEmpiresWeapon::FireShot() if (GetAmmoInClip() <= 0) { EndFire(); - //Reload(); + Reload(); } } ///////////////////////////////////// FIREMODES +FWeaponData UBaseEmpiresWeapon::GetActiveFiremodeData() +{ + + return FiremodeData[ActiveFiremode]; +} + + +UBaseFiremode* UBaseEmpiresWeapon::GetActiveFiremode() +{ + return Firemodes[ActiveFiremode]; +} + + +FAmmoPool UBaseEmpiresWeapon::GetCurrentAmmoPool() +{ + return AmmoPools[FiremodeData[ActiveFiremode].AmmoPoolIndex]; +} + void UBaseEmpiresWeapon::NextFiremode() { @@ -221,10 +250,9 @@ FAmmoPool UBaseEmpiresWeapon::GetAmmoPool(int32 FromAmmoPool) void UBaseEmpiresWeapon::ConsumeAmmo(int32 HowMuch, int32 FromAmmoPool) { - FAmmoPool AmmoPool = GetAmmoPool(FromAmmoPool); + int32 AmmoPoolidx = FromAmmoPool == CurrentAmmopool ? GetActiveFiremodeData().AmmoPoolIndex : FromAmmoPool; - AmmoPool.AmmoInClip -= HowMuch; - AmmoPool.CurrentAmmo -= HowMuch; + AmmoPools[AmmoPoolidx].AmmoInClip -= HowMuch; } int32 UBaseEmpiresWeapon::GetAmmoInClip(int32 FromAmmoPool) @@ -249,7 +277,48 @@ void UBaseEmpiresWeapon::AddAmmo(int32 Ammount, int32 ToAmmoPool) } } -void UBaseEmpiresWeapon::Reload(int32 AmmoPool) +void UBaseEmpiresWeapon::Reload() { + if (GetTotalAmmo() <= 0) return; //We don't have any ammo to reload + + SCREENLOG(TEXT("Starting Reload")); + + //Get the current reload animation + UAnimMontage* ReloadAnim = GetActiveWeaponAnimationSet().ReloadAnimation; + float ReloadTime = GetAmmoPool().ReloadTime; + if (ReloadAnim == nullptr) + { + PlayAnimation(ReloadAnim); + } + + GetWorld()->GetTimerManager().SetTimer(this, &UBaseEmpiresWeapon::DoReload, ReloadTime, false); + + bReloading = true; } + +void UBaseEmpiresWeapon::DoReload() +{ + SCREENLOG(TEXT("Ending Reload")); + + int Idx = GetActiveFiremodeData().AmmoPoolIndex; + + + if (AmmoPools[Idx].CurrentAmmo < AmmoPools[Idx].ClipSize) //We don't have enough ammo to fill out a full clip + { + AmmoPools[Idx].AmmoInClip = AmmoPools[Idx].CurrentAmmo; //So set the ammo to whatever is left + AmmoPools[Idx].CurrentAmmo = 0; + } + else //Otherwise, max out our clip + { + //Figure out how many bullets we need + int32 bulletsNeeded = AmmoPools[Idx].ClipSize - AmmoPools[Idx].AmmoInClip; + + //Max out the clip size + AmmoPools[Idx].AmmoInClip = AmmoPools[Idx].ClipSize; + //And take the diff from the pool + AmmoPools[Idx].CurrentAmmo -= bulletsNeeded; + } + bReloading = false; + +} \ No newline at end of file diff --git a/Source/Empires2/Public/Empires2.h b/Source/Empires2/Public/Empires2.h index 40c167d..643205b 100644 --- a/Source/Empires2/Public/Empires2.h +++ b/Source/Empires2/Public/Empires2.h @@ -11,7 +11,7 @@ DECLARE_LOG_CATEGORY_EXTERN(EmpiresGameplay, Display, All); DECLARE_LOG_CATEGORY_EXTERN(EmpiresNetwork, Log, All); -#define SCREENLOG(text, ...) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::White, FString::Printf__VA(text, ##__VA_ARGS__)) +#define SCREENLOG(text, ...) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::White, FString::Printf__VA(TEXT("[%s:%d] %s"), TEXT(__FUNCTION__), __LINE__, *FString::Printf__VA(text, ##__VA_ARGS__))) #endif diff --git a/Source/Empires2/Public/Empires2Character.h b/Source/Empires2/Public/Empires2Character.h index eedcb5c..793a3b3 100644 --- a/Source/Empires2/Public/Empires2Character.h +++ b/Source/Empires2/Public/Empires2Character.h @@ -70,14 +70,17 @@ class AEmpires2Character : public ACharacter void DrawWeapon(UBaseInfantryWeapon* Weapon); void SwitchToWeapon(EInfantryInventorySlots::Type Weapon); + UFUNCTION(BlueprintCallable, Category = Weapon) UBaseInfantryWeapon* GetActiveWeapon(); - /* Weapon Input Events*/ + /* Weapon Input Events */ void SelectNextWeapon(); void SelectPreviousWeapon(); void SelectLastWeapon(); - void ChangeFiremode(); + void ReloadWeapon(); + /* End Weapon Input Events */ + protected: EInfantryInventorySlots::Type SelectedWeapon; diff --git a/Source/Empires2/Public/Weapon/BaseEmpiresWeapon.h b/Source/Empires2/Public/Weapon/BaseEmpiresWeapon.h index 411cf44..6ebee84 100644 --- a/Source/Empires2/Public/Weapon/BaseEmpiresWeapon.h +++ b/Source/Empires2/Public/Weapon/BaseEmpiresWeapon.h @@ -76,10 +76,16 @@ struct FAmmoPool int32 MaxAmmo; UPROPERTY(EditDefaultsOnly, Category = General) int32 ClipSize; + UPROPERTY(EditDefaultsOnly, Category = General) + float ReloadTime; + UPROPERTY(EditDefaultsOnly, Category = Ammo) TSubclassOf ProjectileClass; + + UPROPERTY(BlueprintReadWrite, Category=Ammo) int32 CurrentAmmo; + UPROPERTY(BlueprintReadWrite, Category = Ammo) int32 AmmoInClip; FAmmoPool() @@ -98,23 +104,26 @@ struct FWeaponAnimationSet { GENERATED_USTRUCT_BODY() public: - /** Sound to play each time we fire */ - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Display) - class USoundBase* FireSound; - + /** AnimMontage to play each time we fire */ UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Display) - class UAnimMontage* FireAnimation; - - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Display) - USoundBase* ChangeFiremodeSound; + class UAnimMontage* FireAnimation; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Display) UAnimMontage* ChangeFiremodeAnimation; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Display) UAnimMontage* ReloadAnimation; + + /** Sound to play each time we fire */ + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Sound) + class USoundBase* FireSound; + + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Sound) + USoundBase* ChangeFiremodeSound; + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Sound) + USoundBase* ReloadSound; }; /** @@ -207,22 +216,14 @@ class EMPIRES2_API UBaseEmpiresWeapon : public UObject UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Firemodes) TArray AmmoPools; + UFUNCTION(BlueprintCallable, Category = Firemode) + virtual FWeaponData GetActiveFiremodeData(); - virtual FWeaponData GetActiveFiremodeData() - { - - return FiremodeData[ActiveFiremode]; - } + UFUNCTION(BlueprintCallable, Category = Firemode) + virtual UBaseFiremode* GetActiveFiremode(); - virtual UBaseFiremode* GetActiveFiremode() - { - return Firemodes[ActiveFiremode]; - } - - virtual FAmmoPool GetCurrentAmmoPool() - { - return AmmoPools[FiremodeData[ActiveFiremode].AmmoPoolIndex]; - } + UFUNCTION(BlueprintCallable, Category = Firemode) + virtual FAmmoPool GetCurrentAmmoPool(); void NextFiremode(); @@ -241,16 +242,23 @@ class EMPIRES2_API UBaseEmpiresWeapon : public UObject public: virtual void ConsumeAmmo(int32 HowMuch = 1, int32 FromAmmoPool = CurrentAmmopool ); + //UFUNCTION(BlueprintCallable, Category = Firemode) //TODO: Figure out how to do default params with UFUNCTIONS virtual int32 GetAmmoInClip(int32 FromAmmoPool = CurrentAmmopool); + //UFUNCTION(BlueprintCallable, Category = Firemode) virtual int32 GetTotalAmmo(int32 FromAmmoPool = CurrentAmmopool); virtual void AddAmmo(int32 Ammount, int32 ToAmmoPool = CurrentAmmopool); - virtual void Reload(int32 AmmoPool = CurrentAmmopool); + virtual void Reload(); + + virtual void DoReload(); protected: - FAmmoPool GetAmmoPool(int32 FromAmmoPool); + FAmmoPool GetAmmoPool(int32 FromAmmoPool = CurrentAmmopool); + + bool bReloading; + };