mirror of https://github.com/PrimeDecomp/prime.git
More CPlayerGun matches
This commit is contained in:
parent
9712ece8fe
commit
ec34055dbb
|
@ -2978,7 +2978,7 @@ lbl_8003CB1C:
|
||||||
/* 8003CB2C 00039A8C 38 05 FF FE */ addi r0, r5, -2
|
/* 8003CB2C 00039A8C 38 05 FF FE */ addi r0, r5, -2
|
||||||
/* 8003CB30 00039A90 7C 00 00 34 */ cntlzw r0, r0
|
/* 8003CB30 00039A90 7C 00 00 34 */ cntlzw r0, r0
|
||||||
/* 8003CB34 00039A94 54 05 D9 7E */ srwi r5, r0, 5
|
/* 8003CB34 00039A94 54 05 D9 7E */ srwi r5, r0, 5
|
||||||
/* 8003CB38 00039A98 48 00 28 09 */ bl Reset__10CPlayerGunFR13CStateManager
|
/* 8003CB38 00039A98 48 00 28 09 */ bl Reset__10CPlayerGunFR13CStateManagerb
|
||||||
/* 8003CB3C 00039A9C 80 01 00 14 */ lwz r0, 0x14(r1)
|
/* 8003CB3C 00039A9C 80 01 00 14 */ lwz r0, 0x14(r1)
|
||||||
/* 8003CB40 00039AA0 83 E1 00 0C */ lwz r31, 0xc(r1)
|
/* 8003CB40 00039AA0 83 E1 00 0C */ lwz r31, 0xc(r1)
|
||||||
/* 8003CB44 00039AA4 83 C1 00 08 */ lwz r30, 8(r1)
|
/* 8003CB44 00039AA4 83 C1 00 08 */ lwz r30, 8(r1)
|
||||||
|
@ -5654,7 +5654,7 @@ lbl_8003F100:
|
||||||
/* 8003F15C 0003C0BC 7F E3 FB 78 */ mr r3, r31
|
/* 8003F15C 0003C0BC 7F E3 FB 78 */ mr r3, r31
|
||||||
/* 8003F160 0003C0C0 7F 84 E3 78 */ mr r4, r28
|
/* 8003F160 0003C0C0 7F 84 E3 78 */ mr r4, r28
|
||||||
/* 8003F164 0003C0C4 38 A0 00 00 */ li r5, 0
|
/* 8003F164 0003C0C4 38 A0 00 00 */ li r5, 0
|
||||||
/* 8003F168 0003C0C8 48 00 01 D9 */ bl Reset__10CPlayerGunFR13CStateManager
|
/* 8003F168 0003C0C8 48 00 01 D9 */ bl Reset__10CPlayerGunFR13CStateManagerb
|
||||||
/* 8003F16C 0003C0CC 57 C0 06 3F */ clrlwi. r0, r30, 0x18
|
/* 8003F16C 0003C0CC 57 C0 06 3F */ clrlwi. r0, r30, 0x18
|
||||||
/* 8003F170 0003C0D0 41 82 00 28 */ beq lbl_8003F198
|
/* 8003F170 0003C0D0 41 82 00 28 */ beq lbl_8003F198
|
||||||
/* 8003F174 0003C0D4 A9 02 C5 F8 */ lha r8, kMaxPriority__11CSfxManager@sda21(r2)
|
/* 8003F174 0003C0D4 A9 02 C5 F8 */ lha r8, kMaxPriority__11CSfxManager@sda21(r2)
|
||||||
|
@ -5785,8 +5785,8 @@ lbl_8003F2E0:
|
||||||
/* 8003F338 0003C298 38 21 00 20 */ addi r1, r1, 0x20
|
/* 8003F338 0003C298 38 21 00 20 */ addi r1, r1, 0x20
|
||||||
/* 8003F33C 0003C29C 4E 80 00 20 */ blr
|
/* 8003F33C 0003C29C 4E 80 00 20 */ blr
|
||||||
|
|
||||||
.global Reset__10CPlayerGunFR13CStateManager
|
.global Reset__10CPlayerGunFR13CStateManagerb
|
||||||
Reset__10CPlayerGunFR13CStateManager:
|
Reset__10CPlayerGunFR13CStateManagerb:
|
||||||
/* 8003F340 0003C2A0 94 21 FF E0 */ stwu r1, -0x20(r1)
|
/* 8003F340 0003C2A0 94 21 FF E0 */ stwu r1, -0x20(r1)
|
||||||
/* 8003F344 0003C2A4 7C 08 02 A6 */ mflr r0
|
/* 8003F344 0003C2A4 7C 08 02 A6 */ mflr r0
|
||||||
/* 8003F348 0003C2A8 90 01 00 24 */ stw r0, 0x24(r1)
|
/* 8003F348 0003C2A8 90 01 00 24 */ stw r0, 0x24(r1)
|
||||||
|
@ -6056,7 +6056,7 @@ lbl_8003F714:
|
||||||
/* 8003F71C 0003C67C 7F C3 F3 78 */ mr r3, r30
|
/* 8003F71C 0003C67C 7F C3 F3 78 */ mr r3, r30
|
||||||
/* 8003F720 0003C680 7F E4 FB 78 */ mr r4, r31
|
/* 8003F720 0003C680 7F E4 FB 78 */ mr r4, r31
|
||||||
/* 8003F724 0003C684 38 A0 00 00 */ li r5, 0
|
/* 8003F724 0003C684 38 A0 00 00 */ li r5, 0
|
||||||
/* 8003F728 0003C688 4B FF FC 19 */ bl Reset__10CPlayerGunFR13CStateManager
|
/* 8003F728 0003C688 4B FF FC 19 */ bl Reset__10CPlayerGunFR13CStateManagerb
|
||||||
lbl_8003F72C:
|
lbl_8003F72C:
|
||||||
/* 8003F72C 0003C68C 80 1E 02 E0 */ lwz r0, 0x2e0(r30)
|
/* 8003F72C 0003C68C 80 1E 02 E0 */ lwz r0, 0x2e0(r30)
|
||||||
/* 8003F730 0003C690 28 00 00 00 */ cmplwi r0, 0
|
/* 8003F730 0003C690 28 00 00 00 */ cmplwi r0, 0
|
||||||
|
@ -7113,7 +7113,7 @@ ResetNormal__10CPlayerGunFR13CStateManager:
|
||||||
/* 80040638 0003D598 90 01 00 14 */ stw r0, 0x14(r1)
|
/* 80040638 0003D598 90 01 00 14 */ stw r0, 0x14(r1)
|
||||||
/* 8004063C 0003D59C 93 E1 00 0C */ stw r31, 0xc(r1)
|
/* 8004063C 0003D59C 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||||
/* 80040640 0003D5A0 7C 7F 1B 78 */ mr r31, r3
|
/* 80040640 0003D5A0 7C 7F 1B 78 */ mr r31, r3
|
||||||
/* 80040644 0003D5A4 4B FF EC FD */ bl Reset__10CPlayerGunFR13CStateManager
|
/* 80040644 0003D5A4 4B FF EC FD */ bl Reset__10CPlayerGunFR13CStateManagerb
|
||||||
/* 80040648 0003D5A8 88 1F 08 32 */ lbz r0, 0x832(r31)
|
/* 80040648 0003D5A8 88 1F 08 32 */ lbz r0, 0x832(r31)
|
||||||
/* 8004064C 0003D5AC 38 60 00 00 */ li r3, 0
|
/* 8004064C 0003D5AC 38 60 00 00 */ li r3, 0
|
||||||
/* 80040650 0003D5B0 50 60 1F 38 */ rlwimi r0, r3, 3, 0x1c, 0x1c
|
/* 80040650 0003D5B0 50 60 1F 38 */ rlwimi r0, r3, 3, 0x1c, 0x1c
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
static u16 TranslateSFXID(u16);
|
static u16 TranslateSFXID(u16);
|
||||||
|
|
||||||
static void PitchBend(CSfxHandle handle, int pitch);
|
static void PitchBend(CSfxHandle handle, int pitch);
|
||||||
|
|
||||||
|
static CSfxHandle SfxStart(u16 id, u8 vol, u8 pan, bool useAcoustics, s16 prio, bool looped, s32 areaId);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -122,7 +122,7 @@ public:
|
||||||
void ActivateCombo(CStateManager&);
|
void ActivateCombo(CStateManager&);
|
||||||
void EnableChargeFx(CPlayerState::EChargeStage, CStateManager&);
|
void EnableChargeFx(CPlayerState::EChargeStage, CStateManager&);
|
||||||
void UpdateChargeState(float, CStateManager&);
|
void UpdateChargeState(float, CStateManager&);
|
||||||
void Reset(CStateManager&);
|
void Reset(CStateManager& mgr, bool);
|
||||||
void ResetCharge(CStateManager&, bool);
|
void ResetCharge(CStateManager&, bool);
|
||||||
void ResetBeamParams(CStateManager&, const CPlayerState&, bool);
|
void ResetBeamParams(CStateManager&, const CPlayerState&, bool);
|
||||||
void ChangeWeapon(const CPlayerState&, CStateManager&);
|
void ChangeWeapon(const CPlayerState&, CStateManager&);
|
||||||
|
@ -177,6 +177,9 @@ public:
|
||||||
|
|
||||||
static float GetTractorBeamFactor() { return skTractorBeamFactor; }
|
static float GetTractorBeamFactor() { return skTractorBeamFactor; }
|
||||||
|
|
||||||
|
s32 GetStateFlags() const { return x2f8_stateFlags; }
|
||||||
|
void SetStateFlags(s32 flags) { x2f8_stateFlags = flags; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CGunMorph {
|
class CGunMorph {
|
||||||
public:
|
public:
|
||||||
|
@ -275,7 +278,7 @@ private:
|
||||||
uint x2f0_pressedFireButtonStates;
|
uint x2f0_pressedFireButtonStates;
|
||||||
uint x2f4_fireButtonStates;
|
uint x2f4_fireButtonStates;
|
||||||
// 0x1: beam mode, 0x2: missile mode, 0x4: missile ready, 0x8: morphing, 0x10: combo fire
|
// 0x1: beam mode, 0x2: missile mode, 0x4: missile ready, 0x8: morphing, 0x10: combo fire
|
||||||
uint x2f8_stateFlags;
|
s32 x2f8_stateFlags;
|
||||||
uint x2fc_fidgetAnimBits;
|
uint x2fc_fidgetAnimBits;
|
||||||
uint x300_remainingMissiles;
|
uint x300_remainingMissiles;
|
||||||
uint x304_;
|
uint x304_;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "MetroidPrime/CWorld.hpp"
|
#include "MetroidPrime/CWorld.hpp"
|
||||||
#include "MetroidPrime/CWorldShadow.hpp"
|
#include "MetroidPrime/CWorldShadow.hpp"
|
||||||
#include "MetroidPrime/Player/CGrappleArm.hpp"
|
#include "MetroidPrime/Player/CGrappleArm.hpp"
|
||||||
|
#include "MetroidPrime/Player/CPlayer.hpp"
|
||||||
#include "MetroidPrime/Tweaks/CTweakGunRes.hpp"
|
#include "MetroidPrime/Tweaks/CTweakGunRes.hpp"
|
||||||
#include "MetroidPrime/Tweaks/CTweakPlayerGun.hpp"
|
#include "MetroidPrime/Tweaks/CTweakPlayerGun.hpp"
|
||||||
#include "MetroidPrime/Weapons/CAuxWeapon.hpp"
|
#include "MetroidPrime/Weapons/CAuxWeapon.hpp"
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
#include "MetroidPrime/Weapons/GunController/CGunMotion.hpp"
|
#include "MetroidPrime/Weapons/GunController/CGunMotion.hpp"
|
||||||
#include "MetroidPrime/Weapons/WeaponTypes.hpp"
|
#include "MetroidPrime/Weapons/WeaponTypes.hpp"
|
||||||
|
|
||||||
|
#include "Kyoto/Audio/CSfxManager.hpp"
|
||||||
#include "Kyoto/Graphics/CModelFlags.hpp"
|
#include "Kyoto/Graphics/CModelFlags.hpp"
|
||||||
#include "Kyoto/Math/CMath.hpp"
|
#include "Kyoto/Math/CMath.hpp"
|
||||||
#include "Kyoto/Particles/CElementGen.hpp"
|
#include "Kyoto/Particles/CElementGen.hpp"
|
||||||
|
@ -354,15 +356,81 @@ void CPlayerGun::Update(float, float, float, CStateManager&) {}
|
||||||
|
|
||||||
void CPlayerGun::ProcessInput(const CFinalInput&, CStateManager&) {}
|
void CPlayerGun::ProcessInput(const CFinalInput&, CStateManager&) {}
|
||||||
|
|
||||||
void CPlayerGun::ProcessChargeState(int, int, CStateManager&, float) {}
|
void CPlayerGun::ProcessChargeState(int releasedStates, int pressedStates, CStateManager& mgr,
|
||||||
|
float dt) {
|
||||||
|
if ((releasedStates & 0x1) != 0) {
|
||||||
|
ResetCharged(dt, mgr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((pressedStates & 0x1) != 0) {
|
||||||
|
if (x32c_chargePhase == kCP_NotCharging && (pressedStates & 0x1) != 0 &&
|
||||||
|
x348_chargeCooldownTimer == 0.f && x832_28_readyForShot == 1) {
|
||||||
|
UpdateNormalShotCycle(dt, mgr);
|
||||||
|
x32c_chargePhase = kCP_ChargeRequested;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const CPlayerState* state = mgr.GetPlayerState();
|
||||||
|
if (state->HasPowerUp(CPlayerState::kIT_Missiles) && (pressedStates & 0x2) != 0) {
|
||||||
|
if (x32c_chargePhase >= kCP_FxGrown) {
|
||||||
|
if (state->HasPowerUp(skBeamComboArr[size_t(x310_currentBeam)]))
|
||||||
|
ActivateCombo(mgr);
|
||||||
|
} else if (x32c_chargePhase == kCP_NotCharging) {
|
||||||
|
FireSecondary(dt, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerGun::ResetNormal(CStateManager&) {}
|
void CPlayerGun::ResetNormal(CStateManager& mgr) {
|
||||||
|
Reset(mgr, false);
|
||||||
|
x832_28_readyForShot = false;
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerGun::ResetCharged(float, CStateManager&) {}
|
void CPlayerGun::ResetCharged(float dt, CStateManager& mgr) {
|
||||||
|
if (x832_26_comboFiring == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerGun::ProcessNormalState(int, int, CStateManager&, float) {}
|
if (x32c_chargePhase >= kCP_FxGrowing) {
|
||||||
|
x833_30_canShowAuxMuzzleEffect = false;
|
||||||
|
UpdateNormalShotCycle(dt, mgr);
|
||||||
|
x832_24_coolingCharge = true;
|
||||||
|
CancelCharge(mgr, true);
|
||||||
|
} else if (x32c_chargePhase != kCP_NotCharging) {
|
||||||
|
x320_currentAuxBeam = x310_currentBeam;
|
||||||
|
x833_30_canShowAuxMuzzleEffect = true;
|
||||||
|
x32c_chargePhase = kCP_ChargeDone;
|
||||||
|
}
|
||||||
|
StopChargeSound(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
bool CPlayerGun::ExitMissile() { return false; }
|
void CPlayerGun::ProcessNormalState(int releasedStates, int pressedStates, CStateManager& mgr,
|
||||||
|
float dt) {
|
||||||
|
if ((releasedStates & 0x1) != 0) {
|
||||||
|
ResetNormal(mgr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pressedStates & 0x1) != 0 && x348_chargeCooldownTimer == 0.f &&
|
||||||
|
x832_28_readyForShot == true) {
|
||||||
|
UpdateNormalShotCycle(dt, mgr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((pressedStates & 0x2) != 0) {
|
||||||
|
FireSecondary(dt, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPlayerGun::ExitMissile() {
|
||||||
|
if ((x2f8_stateFlags & 0x1) != 0x1) {
|
||||||
|
if ((x2f8_stateFlags & 0x10) != 0x10 && x338_nextState != kNS_ExitMissile) {
|
||||||
|
x338_nextState = kNS_ExitMissile;
|
||||||
|
PlayAnim(NWeaponTypes::kGAT_FromMissile, false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerGun::UpdateNormalShotCycle(float, CStateManager&) {}
|
void CPlayerGun::UpdateNormalShotCycle(float, CStateManager&) {}
|
||||||
|
|
||||||
|
@ -376,11 +444,76 @@ void CPlayerGun::EnableChargeFx(CPlayerState::EChargeStage, CStateManager&) {}
|
||||||
|
|
||||||
void CPlayerGun::UpdateChargeState(float, CStateManager&) {}
|
void CPlayerGun::UpdateChargeState(float, CStateManager&) {}
|
||||||
|
|
||||||
void CPlayerGun::Reset(CStateManager&) {}
|
void CPlayerGun::Reset(CStateManager& mgr, bool b1) {
|
||||||
|
x72c_currentBeam->Reset(mgr);
|
||||||
|
x832_25_chargeEffectVisible = false;
|
||||||
|
x832_24_coolingCharge = false;
|
||||||
|
x833_26_ = false;
|
||||||
|
x348_chargeCooldownTimer = 0.f;
|
||||||
|
SetGunLightActive(false, mgr);
|
||||||
|
if ((x2f8_stateFlags & 0x10) != 0x10) {
|
||||||
|
if (!b1 && (x2f8_stateFlags & 0x2) != 0x2) {
|
||||||
|
if ((x2f8_stateFlags & 0x8) != 0x8) {
|
||||||
|
x2f8_stateFlags |= 0x1;
|
||||||
|
x2f8_stateFlags &= ~0x16;
|
||||||
|
}
|
||||||
|
x318_comboAmmoIdx = 0;
|
||||||
|
x31c_missileMode = kMM_Inactive;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x2f8_stateFlags &= ~0x7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerGun::ResetCharge(CStateManager&, bool) {}
|
void CPlayerGun::ResetCharge(CStateManager& mgr, bool resetBeam) {
|
||||||
|
if (x32c_chargePhase != kCP_NotCharging)
|
||||||
|
StopChargeSound(mgr);
|
||||||
|
|
||||||
void CPlayerGun::ResetBeamParams(CStateManager&, const CPlayerState&, bool) {}
|
if ((x2f8_stateFlags & 0x8) != 0x8 && (x2f8_stateFlags & 0x10) != 0x10) {
|
||||||
|
bool doResetBeam =
|
||||||
|
mgr.GetPlayer()->GetMorphballTransitionState() == CPlayer::kMS_Morphed || resetBeam;
|
||||||
|
if (x832_27_chargeAnimStarted || doResetBeam)
|
||||||
|
PlayAnim(NWeaponTypes::kGAT_BasePosition, false);
|
||||||
|
if (doResetBeam)
|
||||||
|
x72c_currentBeam->EnableSecondaryFx(CGunWeapon::kSFT_None);
|
||||||
|
if ((x2f8_stateFlags & 0x2) != 0x2 || x330_chargeState != kCS_Normal) {
|
||||||
|
if ((x2f8_stateFlags & 0x8) != 0x8) {
|
||||||
|
x2f8_stateFlags |= 0x1;
|
||||||
|
x2f8_stateFlags &= ~0x16;
|
||||||
|
}
|
||||||
|
x318_comboAmmoIdx = 0;
|
||||||
|
x31c_missileMode = kMM_Inactive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x32c_chargePhase = kCP_NotCharging;
|
||||||
|
x330_chargeState = kCS_Normal;
|
||||||
|
x320_currentAuxBeam = x310_currentBeam;
|
||||||
|
x833_30_canShowAuxMuzzleEffect = true;
|
||||||
|
x832_27_chargeAnimStarted = false;
|
||||||
|
x832_26_comboFiring = false;
|
||||||
|
x344_comboXferTimer = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SFXwpn_morph_out_wipe 1774
|
||||||
|
|
||||||
|
void CPlayerGun::ResetBeamParams(CStateManager& mgr, const CPlayerState& playerState,
|
||||||
|
bool playSelectionSfx) {
|
||||||
|
StopContinuousBeam(mgr, true);
|
||||||
|
if (playerState.ItemEnabled(CPlayerState::kIT_ChargeBeam)) {
|
||||||
|
ResetCharge(mgr, false);
|
||||||
|
}
|
||||||
|
const CAnimPlaybackParms parms(skBeamAnimIds[size_t(x314_nextBeam)], -1, 1.f, true);
|
||||||
|
x6e0_rightHandModel.AnimationData()->SetAnimation(parms, false);
|
||||||
|
Reset(mgr, false);
|
||||||
|
if (playSelectionSfx) {
|
||||||
|
CSfxManager::SfxStart(SFXwpn_morph_out_wipe, 0x7f, 0x40, true, CSfxManager::kMaxPriority, false,
|
||||||
|
CSfxManager::kAllAreas);
|
||||||
|
}
|
||||||
|
x2ec_lastFireButtonStates &= ~0x1;
|
||||||
|
x320_currentAuxBeam = x310_currentBeam;
|
||||||
|
x833_30_canShowAuxMuzzleEffect = true;
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerGun::ChangeWeapon(const CPlayerState&, CStateManager&) {}
|
void CPlayerGun::ChangeWeapon(const CPlayerState&, CStateManager&) {}
|
||||||
|
|
||||||
|
@ -417,7 +550,23 @@ CPlayerGun::CGunMorph::EMorphEvent CPlayerGun::CGunMorph::Update(float, float, f
|
||||||
|
|
||||||
void CPlayerGun::UpdateWeaponFire(float, CPlayerState&, CStateManager&) {}
|
void CPlayerGun::UpdateWeaponFire(float, CPlayerState&, CStateManager&) {}
|
||||||
|
|
||||||
void CPlayerGun::ResetIdle(CStateManager&) {}
|
void CPlayerGun::ResetIdle(CStateManager& mgr) {
|
||||||
|
CFidget::EState fidgetState = x3a4_fidget.GetState();
|
||||||
|
x370_gunMotionSpeedMult = 1.f;
|
||||||
|
x550_camBob.SetState(CPlayerCameraBob::kCBS_GunFireNoBob, mgr);
|
||||||
|
if (fidgetState != CFidget::kS_NoFidget) {
|
||||||
|
if (fidgetState == CFidget::kS_Loading) {
|
||||||
|
UnLoadFidget();
|
||||||
|
}
|
||||||
|
ReturnArmAndGunToDefault(mgr, true);
|
||||||
|
}
|
||||||
|
x3a4_fidget.ResetAll();
|
||||||
|
ReturnToRestPose();
|
||||||
|
if (x324_idleState != kIS_NotIdle)
|
||||||
|
x324_idleState = kIS_NotIdle;
|
||||||
|
if (!x740_grappleArm->GetActive())
|
||||||
|
x834_26_animPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerGun::UpdateGunIdle(bool, float, float, CStateManager&) {}
|
void CPlayerGun::UpdateGunIdle(bool, float, float, CStateManager&) {}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue