Magnum.c
class Magnum_Static_Stateclass Magnum_Baseclass Magnumclass SawedoffMagnumclass Magnum_Cylinderclass Magnum_Ejectorenum MagnumAnimStateenum MagnumStableStateID
const float MAGNUM_ROTATION_POSITION_M1 = -0.167;
const float MAGNUM_ROTATION_POSITION_0 = 0.0;
const float MAGNUM_ROTATION_POSITION_1 = 0.167;
const float MAGNUM_ROTATION_POSITION_2 = 0.334;
const float MAGNUM_ROTATION_POSITION_3 = 0.500;
const float MAGNUM_ROTATION_POSITION_4 = 0.668;
const float MAGNUM_ROTATION_POSITION_5 = 0.835;
const float MAGNUM_ROTATION_POSITION_6 = 1.0;
enum MagnumAnimState
{
DEFAULT = 0, ///< default weapon state
};
enum MagnumStableStateID
{
UNKNOWN = 0,
DEFAULT = 1,
}
class Magnum_Static_State extends WeaponStableState
{
bool init = false;
override void OnEntry(WeaponEventBase e)
{
if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnstate] { Magnum stable state"); }
super.OnEntry(e);
if (init)
{
Magnum_Base magnum;
if (CastTo(magnum, m_weapon))
{
magnum.SyncCylinderRotation();
//magnum.SyncSelectionStateFromState();
}
}
init = true;
}
override void OnExit (WeaponEventBase e) { super.OnExit(e); if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnstate] } Magnum stable state"); } }
override int GetCurrentStateID () { return MagnumStableStateID.DEFAULT; }
override bool HasBullet() { return m_weapon.IsChamberFull(m_weapon.GetCurrentMuzzle()); }
override bool HasMagazine() { return false; }
override bool IsJammed() { return m_weapon.IsJammed(); }
override bool IsSingleState() { return true; }
};
class Magnum_Base extends Weapon_Base
{
ref WeaponStableState C;
int m_LastMuzzleloaded;
int m_ActiveMuzzle;
const string ATT_SLOT_CYLINDER = "RevolverCylinder";
const string ATT_SLOT_EJECTOR = "RevolverEjector";
override void SetActions()
{
AddAction(FirearmActionLoadMultiBulletQuick);
super.SetActions();
AddAction(FirearmActionLoadMultiBullet);
}
override RecoilBase SpawnRecoilObject()
{
return new MagnumRecoil(this);
}
void Magnum_Base ()
{
m_LastMuzzleloaded = 0;
m_ActiveMuzzle = 0;
/*m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionTypes.CHAMBERING_STARTLOOPABLE_CLOSED));
m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionTypes.CHAMBERING_ENDLOOPABLE));
m_abilities.Insert(new AbilityRecord(WeaponActions.MECHANISM, WeaponActionTypes.MECHANISM_CLOSED));
m_abilities.Insert(new AbilityRecord(WeaponActions.MECHANISM, WeaponActionTypes.MECHANISM_SPECIAL));
m_abilities.Insert(new AbilityRecord(WeaponActions.UNJAMMING, WeaponActionTypes.UNJAMMING_START));
m_abilities.Insert(new AbilityRecord(WeaponActions.UNJAMMING, WeaponActionTypes.UNJAMMING_END));
m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, WeaponActionTypes.FIRE_NORMAL));
m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, WeaponActionTypes.FIRE_COCKED));*/
}
override void InitStateMachine ()
{
m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_CLOSED));
m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_CLOSED_KEEP));
m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_ENDLOOPABLE));
m_abilities.Insert(new AbilityRecord(WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_CLOSED));
m_abilities.Insert(new AbilityRecord(WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_SPECIAL));
m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_NORMAL));
m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_COCKED));
m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_UNCOCKED));
// setup state machine
// basic weapon state
C = new Magnum_Static_State(this, NULL, MagnumAnimState.DEFAULT);
WeaponMagnumChambering Chamber = new WeaponMagnumChambering(this, NULL, WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_CLOSED_KEEP,WeaponActionChamberingTypes.CHAMBERING_ENDLOOPABLE);
WeaponMagnumChambering Chamber_E = new WeaponMagnumChambering(this, NULL, WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_CLOSED,WeaponActionChamberingTypes.CHAMBERING_ENDLOOPABLE);
//WeaponMagnumChambering Chamber_CC00 = new WeaponMagnumChambering(this, NULL, WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_END);
WeaponCharging Mech = new WeaponCharging(this, NULL, WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_CLOSED);
WeaponStateBase Trigger_normal = new WeaponFireMagnum(this, NULL, WeaponActions.FIRE, WeaponActionFireTypes.FIRE_NORMAL);
WeaponStateBase Trigger_dry = new WeaponFireMagnum(this, NULL, WeaponActions.FIRE, WeaponActionFireTypes.FIRE_COCKED);
// events
WeaponEventBase __L__ = new WeaponEventLoad1Bullet;
WeaponEventBase _fin_ = new WeaponEventHumanCommandActionFinished;
WeaponEventBase _abt_ = new WeaponEventHumanCommandActionAborted;
WeaponEventBase __M__ = new WeaponEventMechanism;
WeaponEventBase __T__ = new WeaponEventTrigger;
WeaponEventBase _rto_ = new WeaponEventReloadTimeout;
WeaponEventBase _dto_ = new WeaponEventDryFireTimeout;
m_fsm = new WeaponFSM();
m_fsm.AddTransition(new WeaponTransition( C, __L__, Chamber, null, new WeaponGuardAnyChamberFiredOut(this))); // chamber from closed charged
m_fsm.AddTransition(new WeaponTransition( Chamber, _fin_, C));
m_fsm.AddTransition(new WeaponTransition( Chamber, _abt_, C));
m_fsm.AddTransition(new WeaponTransition( C, __L__, Chamber_E)); // chamber from closed charged
m_fsm.AddTransition(new WeaponTransition( Chamber_E, _fin_, C));
m_fsm.AddTransition(new WeaponTransition( Chamber_E, _abt_, C));
m_fsm.AddTransition(new WeaponTransition( C, __M__, Mech)); // charge from closed
m_fsm.AddTransition(new WeaponTransition( Mech, _fin_, C));
m_fsm.AddTransition(new WeaponTransition( Mech, _abt_, C));
m_fsm.AddTransition(new WeaponTransition( C, __T__, Trigger_normal, null, new GuardAnd (new WeaponGuardCurrentChamberFull(this), new GuardNot(new WeaponGuardCurrentChamberFiredOut(this))) )); // fire.cocked
m_fsm.AddTransition(new WeaponTransition( Trigger_normal, _fin_, C));
m_fsm.AddTransition(new WeaponTransition( Trigger_normal, _dto_, C));
m_fsm.AddTransition(new WeaponTransition( Trigger_normal, _abt_, C));
m_fsm.AddTransition(new WeaponTransition( C, __T__, Trigger_dry)); // fire.cocked
m_fsm.AddTransition(new WeaponTransition( Trigger_dry, _fin_, C));
m_fsm.AddTransition(new WeaponTransition( Trigger_dry, _dto_, C));
m_fsm.AddTransition(new WeaponTransition( Trigger_dry, _abt_, C));
SetInitialState(C);
SelectionBulletHide();
SetCurrentMuzzle(0);
//HideMagazine();
m_fsm.Start();
}
override bool CanChamberBullet(int muzzleIndex, Magazine mag)
{
if ( CanChamberFromMag(muzzleIndex, mag) )
{
if (IsChamberEmpty(muzzleIndex))
return true;
if (IsChamberFiredOut(muzzleIndex))
return true;
}
return false;
}
override void AssembleGun()
{
super.AssembleGun();
if ( !FindAttachmentBySlotName(ATT_SLOT_EJECTOR) )
{
GetInventory().CreateAttachment("Magnum_Ejector");
}
if ( !FindAttachmentBySlotName(ATT_SLOT_CYLINDER) )
{
GetInventory().CreateAttachment("Magnum_Cylinder");
}
ForceSyncSelectionState();
SyncCylinderRotation();
}
static float GetCylinderRotation(int muzzleIndex)
{
switch (muzzleIndex)
{
case 0:
return MAGNUM_ROTATION_POSITION_0;
case 1:
return MAGNUM_ROTATION_POSITION_5;
case 2:
return MAGNUM_ROTATION_POSITION_4;
case 3:
return MAGNUM_ROTATION_POSITION_3;
case 4:
return MAGNUM_ROTATION_POSITION_2;
case 5:
return MAGNUM_ROTATION_POSITION_1;
}
ErrorEx(string.Format("Invalid muzzle index: %1", muzzleIndex));
return MAGNUM_ROTATION_POSITION_0;
}
void SetCylinderRotationAnimationPhase(float rot, bool reset = false)
{
Magnum_Cylinder cylinder = Magnum_Cylinder.Cast(GetAttachmentByType(Magnum_Cylinder));
Magnum_Ejector ejector = Magnum_Ejector.Cast(GetAttachmentByType(Magnum_Ejector));
if (cylinder && ejector)
{
float anim_phase = cylinder.GetAnimationPhase("Rotate_Cylinder");
if ( Math.AbsFloat(anim_phase - rot) > 0.1 )
{
if (reset)
{
cylinder.ResetAnimationPhase("Rotate_Cylinder", rot );
ejector.ResetAnimationPhase("Rotate_Ejector", rot );
}
else if (rot == MAGNUM_ROTATION_POSITION_0)
{
cylinder.ResetAnimationPhase("Rotate_Cylinder", MAGNUM_ROTATION_POSITION_M1 );
ejector.ResetAnimationPhase("Rotate_Ejector", MAGNUM_ROTATION_POSITION_M1 );
}
cylinder.SetAnimationPhase("Rotate_Cylinder", rot );
ejector.SetAnimationPhase("Rotate_Ejector", rot );
}
}
}
void SyncCylinderRotation(bool reset = true)
{
SetCylinderRotationAnimationPhase(GetCylinderRotation(GetCurrentMuzzle()), reset);
}
override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
{
super.EEHealthLevelChanged(oldLevel,newLevel,zone);
if (g_Game.IsClient())
return;
SetAttachmentsHealth();
}
//sets health of cylinder and ejector objects
void SetAttachmentsHealth()
{
EntityAI entity;
ItemBase attachment;
for (int i = 0; i < GetInventory().AttachmentCount(); i++)
{
entity = GetInventory().GetAttachmentFromIndex(i);
if ( Class.CastTo(attachment,entity) )
{
attachment.SetHealth01("","Health",GetHealth01());
}
}
}
override void OnFire(int muzzle_index)
{
super.OnFire(muzzle_index);
Magnum_Cylinder cylinder = Magnum_Cylinder.Cast(GetAttachmentByType(Magnum_Cylinder));
if (cylinder)
{
string bullet_nose = "bullet_nose";
if (muzzle_index > 0)
bullet_nose = string.Format("bullet_nose_" + (muzzle_index + 1));
cylinder.HideSelection(bullet_nose);
}
}
override bool IsShowingChamberedBullet()
{
return false;
}
override bool CanEjectBullet()
{
for (int i = 0; i < GetMuzzleCount(); i++)
{
if (IsChamberFull(i))
return true;
}
return false;
}
override void ShowBullet(int muzzleIndex)
{
Magnum_Cylinder cylinder = Magnum_Cylinder.Cast(GetAttachmentByType(Magnum_Cylinder));
if (cylinder)
{
string bullet = "bullet";
if (muzzleIndex > 0)
bullet = string.Format("bullet_" + (muzzleIndex + 1));
cylinder.ShowSelection(bullet);
if (!IsChamberFiredOut(muzzleIndex))
{
string bullet_nose = "bullet_nose";
if (muzzleIndex > 0)
bullet_nose = string.Format("bullet_nose_" + (muzzleIndex + 1));
cylinder.ShowSelection(bullet_nose);
}
}
}
override void HideBullet(int muzzleIndex)
{
super.HideBullet(muzzleIndex);
Magnum_Cylinder cylinder = Magnum_Cylinder.Cast(GetAttachmentByType(Magnum_Cylinder));
if (cylinder)
{
string bullet = "bullet";
if (muzzleIndex > 0)
bullet = string.Format("bullet_" + (muzzleIndex + 1));
cylinder.HideSelection(bullet);
string bullet_nose = "bullet_nose";
if (muzzleIndex > 0)
bullet_nose = string.Format("bullet_nose_" + (muzzleIndex + 1));
cylinder.HideSelection(bullet_nose);
}
}
//Debug menu Spawn Ground Special
override void OnDebugSpawn()
{
super.OnDebugSpawn();
EntityAI entity;
if ( Class.CastTo(entity, this) )
{
entity.SpawnEntityOnGroundPos("Ammo_357", entity.GetPosition());
}
}
};
class Magnum extends Magnum_Base
{
override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
{
outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "", FadeColors.LIGHT_GREY));
outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SPIN, "Spin", FadeColors.LIGHT_GREY));
outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
super.GetDebugActions(outputList);
}
override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
{
if (g_Game.IsServer())
{
if (action_id == EActions.SPIN)
{
const float animPhaseOffset = 0.167;
Magnum_Cylinder cylinder = Magnum_Cylinder.Cast(GetAttachmentByType(Magnum_Cylinder));
Magnum_Ejector ejector = Magnum_Ejector.Cast(GetAttachmentByType(Magnum_Ejector));
if (cylinder)
{
float animPhase = cylinder.GetAnimationPhase("Rotate_Cylinder");
if (animPhase + animPhaseOffset > 1.0)
{
animPhase -= 1.0;
cylinder.ResetAnimationPhase("Rotate_Cylinder", animPhase);
ejector.ResetAnimationPhase("Rotate_Ejector", animPhase);
}
cylinder.SetAnimationPhase("Rotate_Cylinder", animPhase);
ejector.ResetAnimationPhase("Rotate_Ejector", animPhase);
}
}
}
return super.OnAction(action_id, player, ctx);
}
}
class SawedoffMagnum extends Magnum_Base {};
class Magnum_Cylinder extends DummyItem {};
class Magnum_Ejector extends DummyItem {};