WeaponReplacingMagAndChamberNext.c
class DetachOldMagazineclass OldMagazineHideclass SwapOldAndNewMagazineclass AttachNewMagazineclass AttachNewMagazine_W4Tclass WeaponReplacingMagAndChamberNextclass WeaponReplacingMagAndChamberNextOpenBoltCharged
/**@class DetachOldMagazine
* @brief detaches old magazine from weapon and stores it in left hand (LH)
**/
class DetachOldMagazine extends WeaponStateBase
{
Magazine m_oldMagazine; /// magazine that will be detached
ref InventoryLocation m_newDst;
void DetachOldMagazine (Weapon_Base w = NULL, WeaponStateBase parent = NULL)
{
m_oldMagazine = NULL;
m_newDst = NULL;
}
override void OnEntry (WeaponEventBase e)
{
super.OnEntry(e);
}
override void OnAbort (WeaponEventBase e)
{
super.OnAbort(e);
m_oldMagazine = NULL;
m_newDst = NULL;
}
override void OnExit (WeaponEventBase e)
{
if (m_oldMagazine)
{
InventoryLocation il = new InventoryLocation();
e.m_player.GetInventory().FindFreeLocationFor( m_oldMagazine , FindInventoryLocationType.CARGO, il );
if (!m_newDst || !m_newDst.IsValid() || m_newDst.GetType() == InventoryLocationType.GROUND)
{
if (DayZPlayerUtils.HandleDropMagazine(e.m_player, m_oldMagazine))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, ok - no inventory space for old magazine - dropped to ground"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, error - cannot drop magazine from left hand after not found inventory space for old magazine");
}
else
{
InventoryLocation oldSrc = new InventoryLocation();
m_oldMagazine.GetInventory().GetCurrentInventoryLocation(oldSrc);
if (GameInventory.LocationSyncMoveEntity(oldSrc, m_newDst))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, ok - old magazine removed from wpn (LHand->inv)"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, error - cannot remove old mag from wpn");
}
}
m_weapon.HideMagazine();
m_oldMagazine = NULL;
m_newDst = null;
super.OnExit(e);
}
override bool SaveCurrentFSMState (ParamsWriteContext ctx)
{
if (!super.SaveCurrentFSMState(ctx))
return false;
if (!ctx.Write(m_oldMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.SaveCurrentFSMState: cannot write m_oldMagazine for weapon=" + m_weapon);
return false;
}
if (!OptionalLocationWriteToContext(m_newDst, ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.SaveCurrentFSMState: cannot write m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
override bool LoadCurrentFSMState (ParamsReadContext ctx, int version)
{
if (!super.LoadCurrentFSMState(ctx, version))
return false;
if (!ctx.Read(m_oldMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.LoadCurrentFSMState: cannot read m_oldMagazine for weapon=" + m_weapon);
return false;
}
if (!OptionalLocationReadFromContext(m_newDst, ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.LoadCurrentFSMState: cannot read m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
};
/**@class OldMagazineHide
* @brief hides old magazine, but keep it in LH
* @note on abort, old magazine is dropped to ground
**/
class OldMagazineHide : MagazineHide
{
};
/**@class SwapOldAndNewMagazine
* @brief old magazine to inventory, new to left hand
*
* stores old magazine in left hand somewhere in inventory (or drop to ground if necessary)
* and moves new magazine to left hand.
* on abort new magazine is dropped to ground.
**/
class SwapOldAndNewMagazine extends WeaponStateBase
{
Magazine m_newMagazine; /// magazine that will be dropped on abort
ref InventoryLocation m_newDst;
override void OnEntry (WeaponEventBase e)
{
super.OnEntry(e);
if( e )
{
if (!m_newMagazine || !m_newDst || !m_newDst.IsValid())
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " SwapOldAndNewMagazine, error - m_newMagazine(" + m_newMagazine + ") or destination(" + InventoryLocation.DumpToStringNullSafe(m_newDst) + ") is not set ");
}
else
{
e.m_player.GetInventory().ClearInventoryReservationEx( m_newMagazine , m_newDst );
m_weapon.ShowMagazine();
InventoryLocation lhand = new InventoryLocation();
lhand.SetAttachment(e.m_player, m_newMagazine, InventorySlots.LEFTHAND);
if (GameInventory.LocationSyncMoveEntity(lhand, m_newDst))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " SwapOldAndNewMagazine, ok - new magazine removed from inv (LHand->Att)"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " SwapOldAndNewMagazine, error - cannot remove new mag from LHand");
}
}
}
override void OnAbort (WeaponEventBase e)
{
//m_weapon.HideMagazine();
m_newMagazine = NULL;
m_newDst = NULL;
super.OnAbort(e);
}
override void OnExit (WeaponEventBase e)
{
m_newMagazine = NULL;
m_newDst = NULL;
super.OnExit(e);
}
override bool SaveCurrentFSMState (ParamsWriteContext ctx)
{
if (!super.SaveCurrentFSMState(ctx))
return false;
if (!ctx.Write(m_newMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " SwapOldAndNewMagazine.SaveCurrentFSMState: cannot write m_newMagazine for weapon=" + m_weapon);
return false;
}
if (!OptionalLocationWriteToContext(m_newDst, ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " SwapOldAndNewMagazine.SaveCurrentFSMState: cannot write m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
override bool LoadCurrentFSMState (ParamsReadContext ctx, int version)
{
if (!super.LoadCurrentFSMState(ctx, version))
return false;
if (!ctx.Read(m_newMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " SwapOldAndNewMagazine.LoadCurrentFSMState: cannot read m_newMagazine for weapon=" + m_weapon);
return false;
}
if (!OptionalLocationReadFromContext(m_newDst, ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " SwapOldAndNewMagazine.LoadCurrentFSMState: cannot read m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
};
/**@class AttachNewMagazine
* @brief attach mag in LH into weapon
**/
class AttachNewMagazine extends WeaponStateBase
{
Magazine m_newMagazine; /// new magazine from inventory that will be attached
ref InventoryLocation m_newDst;
void AttachNewMagazine (Weapon_Base w = NULL, WeaponStateBase parent = NULL)
{
m_newMagazine = NULL;
m_newDst = NULL;
}
override bool IsWaitingForActionFinish ()
{
return true;
}
override void OnEntry (WeaponEventBase e)
{
super.OnEntry(e);
if (e)
{
if (m_newMagazine && m_newDst)
{
InventoryLocation il = new InventoryLocation();
if (m_newMagazine.GetInventory().GetCurrentInventoryLocation(il))
{
InventoryLocation lhand = new InventoryLocation();
lhand.SetAttachment(e.m_player, m_newMagazine, InventorySlots.LEFTHAND);
if (GameInventory.LocationSyncMoveEntity(il, m_newDst))
{
m_weapon.ShowMagazine();
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " AttachNewMagazine, ok - attached new magazine (LHand->dst)"); }
}
else
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " AttachNewMagazine, error - cannot attach new magazine!"); }
}
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " AttachNewMagazine, error - cannot get curr location");
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " AttachNewMagazine, error - no magazines configured for replace (m_new=NULL)");
}
}
override void OnAbort (WeaponEventBase e)
{
if (m_newMagazine && m_newDst)
{
if (DayZPlayerUtils.HandleDropMagazine(e.m_player, m_newMagazine))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponDetachingMag_Store, ok - aborting, detached magazine dropped to ground"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponDetachingMag_Store, error - cannot abort detaching of magazine");
m_weapon.HideMagazine(); // force hide on abort
}
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " AttachNewMagazine, aborting, but attached new magazine already in place"); }
m_newMagazine = NULL;
m_newDst = NULL;
super.OnAbort(e);
}
override void OnExit (WeaponEventBase e)
{
m_newMagazine = NULL;
m_newDst = NULL;
super.OnExit(e);
}
override bool SaveCurrentFSMState (ParamsWriteContext ctx)
{
if (!super.SaveCurrentFSMState(ctx))
return false;
if (!ctx.Write(m_newMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " AttachNewMagazine.SaveCurrentFSMState: cannot write m_newMagazine for weapon=" + m_weapon);
return false;
}
if (!OptionalLocationWriteToContext(m_newDst, ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " AttachNewMagazine.SaveCurrentFSMState: cannot write m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
override bool LoadCurrentFSMState (ParamsReadContext ctx, int version)
{
if (!super.LoadCurrentFSMState(ctx, version))
return false;
if (!ctx.Read(m_newMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " AttachNewMagazine.LoadCurrentFSMState: cannot read m_newMagazine for weapon=" + m_weapon);
return false;
}
if (!OptionalLocationReadFromContext(m_newDst, ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " AttachNewMagazine.LoadCurrentFSMState: cannot read m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
};
class AttachNewMagazine_W4T extends WeaponStateBase
{
override bool IsWaitingForActionFinish () { return true; }
};
/**@class WeaponReplacingMagAndChamberNext
* @brief replace current magazine with new one
*
* replace magazine, i.e. eject curr magazine from weapon, attach another (store the old one)
* and chamber next bullet from magazine (if possible)
**/
class WeaponReplacingMagAndChamberNext extends WeaponStateBase
{
WeaponActions m_action;
int m_actionType;
ref WeaponStartAction m_start;
ref DetachOldMagazine m_detach;
ref OldMagazineHide m_hideOld;
ref SwapOldAndNewMagazine m_swapMags;
ref AttachNewMagazine_W4T m_attach;
ref WeaponChamberFromAttMag_W4T m_chamber;
ref WeaponCharging_CK m_onCK;
ref WeaponEjectCasing m_eject;
// substates configuration
Magazine m_oldMagazine; /// magazine that will be detached
Magazine m_newMagazine; /// magazine that will be attached
ref InventoryLocation m_newDst;
void WeaponReplacingMagAndChamberNext (Weapon_Base w = NULL, WeaponStateBase parent = NULL, WeaponActions action = WeaponActions.NONE, int actionType = -1)
{
m_action = action;
m_actionType = actionType;
m_newMagazine = NULL;
// setup nested state machine
m_start = new WeaponStartAction(m_weapon, this, m_action, m_actionType);
m_eject = new WeaponEjectCasing(m_weapon,this);
m_detach = new DetachOldMagazine(m_weapon, this);
m_hideOld = new OldMagazineHide(m_weapon, this);
m_swapMags = new SwapOldAndNewMagazine(m_weapon, this);
m_attach = new AttachNewMagazine_W4T(m_weapon, this);
m_chamber = new WeaponChamberFromAttMag_W4T(m_weapon, this);
m_onCK = new WeaponCharging_CK(m_weapon, this);
// events
WeaponEventBase __so_ = new WeaponEventAnimSliderOpen;
WeaponEventBase __md_ = new WeaponEventAnimMagazineDetached;
WeaponEventBase __mh_ = new WeaponEventAnimMagazineHide;
WeaponEventBase __ms_ = new WeaponEventAnimMagazineShow;
WeaponEventBase __ma_ = new WeaponEventAnimMagazineAttached;
WeaponEventBase __ck_ = new WeaponEventAnimCocked;
WeaponEventBase _fin_ = new WeaponEventHumanCommandActionFinished;
m_fsm = new WeaponFSM(this); // @NOTE: set owner of the submachine fsm
m_fsm.AddTransition(new WeaponTransition( m_start, __md_, m_detach));
m_fsm.AddTransition(new WeaponTransition( m_start, __so_, m_eject));
m_fsm.AddTransition(new WeaponTransition( m_eject, __md_, m_detach));
m_fsm.AddTransition(new WeaponTransition( m_detach, __mh_, m_hideOld));
m_fsm.AddTransition(new WeaponTransition( m_hideOld, __ms_, m_swapMags));
m_fsm.AddTransition(new WeaponTransition(m_swapMags, __ma_, m_attach));
m_fsm.AddTransition(new WeaponTransition( m_attach, __ck_, m_chamber, NULL, new GuardAnd(new WeaponGuardCurrentChamberEmpty(m_weapon), new WeaponGuardHasAmmo(m_weapon))));
m_fsm.AddTransition(new WeaponTransition( m_attach, __ck_, m_onCK));
m_fsm.AddTransition(new WeaponTransition( m_attach, _fin_, NULL));
m_fsm.AddTransition(new WeaponTransition( m_chamber, _fin_, NULL));
m_fsm.AddTransition(new WeaponTransition( m_onCK, _fin_, NULL));
// Safety exits
m_fsm.AddTransition(new WeaponTransition(m_swapMags, _fin_, null));
m_fsm.AddTransition(new WeaponTransition(m_hideOld, _fin_, null));
m_fsm.AddTransition(new WeaponTransition(m_detach, _fin_, null));
m_fsm.AddTransition(new WeaponTransition(m_eject, _fin_, null));
m_fsm.AddTransition(new WeaponTransition(m_start, _fin_, null));
m_fsm.SetInitialState(m_start);
}
override void OnEntry (WeaponEventBase e)
{
if (e != NULL)
{
WeaponEventSwapMagazine se;
if (Class.CastTo(se, e))
{
int mi = m_weapon.GetCurrentMuzzle();
m_oldMagazine = m_weapon.GetMagazine(mi);
m_newMagazine = se.m_magazine;
m_newDst = se.m_dst;
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNext, m_oldMagazine= " + m_oldMagazine + " m_newMagazine= " + m_newMagazine + " m_oldMagazineDst= " + typename.EnumToString(InventoryLocationType, se.m_dst.GetType())); }
InventoryLocation oldSrc = new InventoryLocation();
InventoryLocation newSrc = new InventoryLocation();
if (!m_newMagazine.GetInventory().GetCurrentInventoryLocation(newSrc))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNext cannot get curr inv loc of NEW mag=" + Object.GetDebugName(m_newMagazine));
}
if (!m_oldMagazine.GetInventory().GetCurrentInventoryLocation(oldSrc))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNext cannot get curr inv loc of OLD mag=" + Object.GetDebugName(m_oldMagazine));
}
// move to LH
InventoryLocation lhand = new InventoryLocation();
lhand.SetAttachment(e.m_player, m_newMagazine, InventorySlots.LEFTHAND);
if (GameInventory.LocationSyncMoveEntity(newSrc, lhand))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory, ok - new magazine removed from inv (inv->LHand)"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory, error - cannot new remove mag from inv");
m_detach.m_oldMagazine = m_oldMagazine;
m_detach.m_newDst = m_newDst;
m_swapMags.m_newMagazine = m_newMagazine;
oldSrc.SetItem(m_newMagazine);
m_swapMags.m_newDst = oldSrc;
}
}
super.OnEntry(e);
}
override void OnExit (WeaponEventBase e)
{
super.OnExit(e);
EntityAI leftHandItem = e.m_player.GetInventory().FindAttachment(InventorySlots.LEFTHAND);
Magazine mag = Magazine.Cast(leftHandItem);
if(mag)
{
if (m_newMagazine)
e.m_player.GetInventory().ClearInventoryReservationEx( m_newMagazine , null );
if (m_oldMagazine)
e.m_player.GetInventory().ClearInventoryReservationEx( m_oldMagazine , null );
InventoryLocation il = new InventoryLocation();
e.m_player.GetInventory().FindFreeLocationFor(mag, FindInventoryLocationType.CARGO, il);
if (!il.IsValid())
{
if (DayZPlayerUtils.HandleDropMagazine(e.m_player, mag))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, ok - no inventory space for old magazine - dropped to ground - exit"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, error - cannot drop magazine from left hand after not found inventory space for old magazine - exit");
}
else
{
InventoryLocation oldSrc = new InventoryLocation();
mag.GetInventory().GetCurrentInventoryLocation(oldSrc);
if (GameInventory.LocationSyncMoveEntity(oldSrc, il))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, ok - old magazine removed from wpn (LHand->inv) - exit"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, error - cannot remove old mag from wpn - exit");
}
}
m_oldMagazine = NULL;
m_newMagazine = NULL;
m_newDst = NULL;
}
override void OnAbort(WeaponEventBase e)
{
super.OnAbort(e);
EntityAI leftHandItem = e.m_player.GetInventory().FindAttachment(InventorySlots.LEFTHAND);
Magazine mag = Magazine.Cast(leftHandItem);
if (mag)
{
if (m_newMagazine)
e.m_player.GetInventory().ClearInventoryReservationEx( m_newMagazine , null );
if (m_oldMagazine)
e.m_player.GetInventory().ClearInventoryReservationEx( m_oldMagazine , null );
InventoryLocation il = new InventoryLocation();
e.m_player.GetInventory().FindFreeLocationFor(mag, FindInventoryLocationType.CARGO, il);
if (!il.IsValid())
{
if (DayZPlayerUtils.HandleDropMagazine(e.m_player, mag))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, ok - no inventory space for old magazine - dropped to ground - abort"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, error - cannot drop magazine from left hand after not found inventory space for old magazine - abort");
}
else
{
InventoryLocation oldSrc = new InventoryLocation();
mag.GetInventory().GetCurrentInventoryLocation(oldSrc);
if (GameInventory.LocationSyncMoveEntity(oldSrc, il))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, ok - old magazine removed from wpn (LHand->inv) - abort"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine, error - cannot remove old mag from wpn - abort");
}
}
}
override bool SaveCurrentFSMState (ParamsWriteContext ctx)
{
if (!super.SaveCurrentFSMState(ctx))
return false;
if (!ctx.Write(m_newMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.SaveCurrentFSMState: cannot write m_newMagazine for weapon=" + m_weapon);
return false;
}
if (!ctx.Write(m_oldMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.SaveCurrentFSMState: cannot write m_oldMagazine for weapon=" + m_weapon);
return false;
}
if (!m_newDst.WriteToContext(ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.SaveCurrentFSMState: cannot write m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
override bool LoadCurrentFSMState (ParamsReadContext ctx, int version)
{
if (!super.LoadCurrentFSMState(ctx, version))
return false;
if (!ctx.Read(m_newMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.LoadCurrentFSMState: cannot read m_newMagazine for weapon=" + m_weapon);
return false;
}
if (!ctx.Read(m_oldMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.LoadCurrentFSMState: cannot read m_oldMagazine for weapon=" + m_weapon);
return false;
}
m_newDst = new InventoryLocation;
if (!m_newDst.ReadFromContext(ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " DetachOldMagazine.LoadCurrentFSMState: cannot read m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
};
/**@class WeaponReplacingMagAndChamberNextOpenBoltCharged
* @brief replace current magazine with new one for weapon charged with open position bolt
*
* replace magazine, i.e. eject curr magazine from weapon, attach another (store the old one)
* and chamber next bullet from magazine (if possible), make sure bullet is chambered at correct time
**/
class WeaponReplacingMagAndChamberNextOpenBoltCharged extends WeaponStateBase
{
WeaponActions m_action;
int m_actionType;
ref WeaponStartAction m_start;
ref WeaponDetachingMag_StoreRemoveChamberBullet m_detach;
ref OldMagazineHide m_hideOld;
ref SwapOldAndNewMagazine m_swapMags;
ref AttachNewMagazine_W4T m_attach;
ref WeaponChamberFromAttMagOpenbolt_W4T m_chamber;
ref WeaponChargingOpenBolt_CK m_onCK;
// substates configuration
Magazine m_oldMagazine; /// magazine that will be detached
Magazine m_newMagazine; /// magazine that will be attached
ref InventoryLocation m_newDst;
void WeaponReplacingMagAndChamberNextOpenBoltCharged (Weapon_Base w = NULL, WeaponStateBase parent = NULL, WeaponActions action = WeaponActions.NONE, int actionType = -1)
{
m_action = action;
m_actionType = actionType;
m_newMagazine = NULL;
// setup nested state machine
m_start = new WeaponStartAction(m_weapon, this, m_action, m_actionType);
m_detach = new WeaponDetachingMag_StoreRemoveChamberBullet(m_weapon, this);
m_hideOld = new OldMagazineHide(m_weapon, this);
m_swapMags = new SwapOldAndNewMagazine(m_weapon, this);
m_attach = new AttachNewMagazine_W4T(m_weapon, this);
m_chamber = new WeaponChamberFromAttMagOpenbolt_W4T(m_weapon, this);
m_onCK = new WeaponChargingOpenBolt_CK(m_weapon, this);
// events
WeaponEventBase __so_ = new WeaponEventAnimSliderOpen;
WeaponEventBase __md_ = new WeaponEventAnimMagazineDetached;
WeaponEventBase __mh_ = new WeaponEventAnimMagazineHide;
WeaponEventBase __ms_ = new WeaponEventAnimMagazineShow;
WeaponEventBase __ma_ = new WeaponEventAnimMagazineAttached;
WeaponEventBase __ck_ = new WeaponEventAnimCocked;
WeaponEventBase _fin_ = new WeaponEventHumanCommandActionFinished;
m_fsm = new WeaponFSM(this); // @NOTE: set owner of the submachine fsm
m_fsm.AddTransition(new WeaponTransition( m_start, __md_, m_detach));
m_fsm.AddTransition(new WeaponTransition( m_detach, __mh_, m_hideOld));
m_fsm.AddTransition(new WeaponTransition( m_hideOld, __ms_, m_swapMags));
m_fsm.AddTransition(new WeaponTransition( m_swapMags, __ma_, m_chamber, NULL, new GuardAnd(new WeaponGuardWeaponCharged(m_weapon), new WeaponGuardHasAmmo(m_weapon))));
m_fsm.AddTransition(new WeaponTransition( m_swapMags, __ma_, m_attach));
m_fsm.AddTransition(new WeaponTransition( m_attach, __ck_, m_chamber, NULL, new WeaponGuardHasAmmo(m_weapon)));
m_fsm.AddTransition(new WeaponTransition( m_attach, __ck_, m_onCK));
m_fsm.AddTransition(new WeaponTransition( m_attach, _fin_, NULL));
m_fsm.AddTransition(new WeaponTransition( m_chamber, _fin_, NULL));
m_fsm.AddTransition(new WeaponTransition( m_onCK, _fin_, NULL));
// Safety exits
m_fsm.AddTransition(new WeaponTransition(m_swapMags, _fin_, null));
m_fsm.AddTransition(new WeaponTransition(m_hideOld, _fin_, null));
m_fsm.AddTransition(new WeaponTransition(m_detach, _fin_, null));
m_fsm.AddTransition(new WeaponTransition(m_start, _fin_, null));
m_fsm.SetInitialState(m_start);
}
override void OnEntry (WeaponEventBase e)
{
if (e != NULL)
{
WeaponEventSwapMagazine se;
if (Class.CastTo(se, e))
{
int mi = m_weapon.GetCurrentMuzzle();
m_oldMagazine = m_weapon.GetMagazine(mi);
m_newMagazine = se.m_magazine;
m_newDst = se.m_dst;
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, m_oldMagazine= " + m_oldMagazine + " m_newMagazine= " + m_newMagazine + " m_oldMagazineDst= " + typename.EnumToString(InventoryLocationType, se.m_dst.GetType())); }
InventoryLocation oldSrc = new InventoryLocation();
InventoryLocation newSrc = new InventoryLocation();
if (!m_newMagazine.GetInventory().GetCurrentInventoryLocation(newSrc))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged cannot get curr inv loc of NEW mag=" + Object.GetDebugName(m_newMagazine));
}
if (!m_oldMagazine.GetInventory().GetCurrentInventoryLocation(oldSrc))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged cannot get curr inv loc of OLD mag=" + Object.GetDebugName(m_oldMagazine));
}
// move to LH
InventoryLocation lhand = new InventoryLocation();
lhand.SetAttachment(e.m_player, m_newMagazine, InventorySlots.LEFTHAND);
if (GameInventory.LocationSyncMoveEntity(newSrc, lhand))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, ok - new magazine removed from inv (inv->LHand)"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, error - cannot new remove mag from inv");
m_detach.m_magazine = m_oldMagazine;
m_detach.m_dst = m_newDst;
m_swapMags.m_newMagazine = m_newMagazine;
oldSrc.SetItem(m_newMagazine);
m_swapMags.m_newDst = oldSrc;
}
}
super.OnEntry(e);
}
override void OnExit (WeaponEventBase e)
{
super.OnExit(e);
EntityAI leftHandItem = e.m_player.GetInventory().FindAttachment(InventorySlots.LEFTHAND);
Magazine mag = Magazine.Cast(leftHandItem);
if(mag)
{
if (m_newMagazine)
e.m_player.GetInventory().ClearInventoryReservationEx( m_newMagazine , null );
if (m_oldMagazine)
e.m_player.GetInventory().ClearInventoryReservationEx( m_oldMagazine , null );
InventoryLocation il = new InventoryLocation();
e.m_player.GetInventory().FindFreeLocationFor(mag, FindInventoryLocationType.CARGO, il);
if (!il.IsValid())
{
if (DayZPlayerUtils.HandleDropMagazine(e.m_player, mag))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, ok - no inventory space for old magazine - dropped to ground - exit"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, error - cannot drop magazine from left hand after not found inventory space for old magazine - exit");
}
else
{
InventoryLocation oldSrc = new InventoryLocation();
mag.GetInventory().GetCurrentInventoryLocation(oldSrc);
if (GameInventory.LocationSyncMoveEntity(oldSrc, il))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, ok - old magazine removed from wpn (LHand->inv) - exit"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, error - cannot remove old mag from wpn - exit");
}
}
m_oldMagazine = NULL;
m_newMagazine = NULL;
m_newDst = NULL;
}
override void OnAbort(WeaponEventBase e)
{
super.OnAbort(e);
EntityAI leftHandItem = e.m_player.GetInventory().FindAttachment(InventorySlots.LEFTHAND);
Magazine mag = Magazine.Cast(leftHandItem);
if (mag)
{
if (m_newMagazine)
e.m_player.GetInventory().ClearInventoryReservationEx( m_newMagazine , null );
if (m_oldMagazine)
e.m_player.GetInventory().ClearInventoryReservationEx( m_oldMagazine , null );
InventoryLocation il = new InventoryLocation();
e.m_player.GetInventory().FindFreeLocationFor(mag, FindInventoryLocationType.CARGO, il);
if (!il.IsValid())
{
if (DayZPlayerUtils.HandleDropMagazine(e.m_player, mag))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, ok - no inventory space for old magazine - dropped to ground - abort"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, error - cannot drop magazine from left hand after not found inventory space for old magazine - abort");
}
else
{
InventoryLocation oldSrc = new InventoryLocation();
mag.GetInventory().GetCurrentInventoryLocation(oldSrc);
if (GameInventory.LocationSyncMoveEntity(oldSrc, il))
{
if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, ok - old magazine removed from wpn (LHand->inv) - abort"); }
}
else
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged, error - cannot remove old mag from wpn - abort");
}
}
}
override bool SaveCurrentFSMState (ParamsWriteContext ctx)
{
if (!super.SaveCurrentFSMState(ctx))
return false;
if (!ctx.Write(m_newMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged.SaveCurrentFSMState: cannot write m_newMagazine for weapon=" + m_weapon);
return false;
}
if (!ctx.Write(m_oldMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged.SaveCurrentFSMState: cannot write m_oldMagazine for weapon=" + m_weapon);
return false;
}
if (!m_newDst.WriteToContext(ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged.SaveCurrentFSMState: cannot write m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
override bool LoadCurrentFSMState (ParamsReadContext ctx, int version)
{
if (!super.LoadCurrentFSMState(ctx, version))
return false;
if (!ctx.Read(m_newMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged.LoadCurrentFSMState: cannot read m_newMagazine for weapon=" + m_weapon);
return false;
}
if (!ctx.Read(m_oldMagazine))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged.LoadCurrentFSMState: cannot read m_oldMagazine for weapon=" + m_weapon);
return false;
}
m_newDst = new InventoryLocation;
if (!m_newDst.ReadFromContext(ctx))
{
Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponReplacingMagAndChamberNextOpenBoltCharged.LoadCurrentFSMState: cannot read m_newDst for weapon=" + m_weapon);
return false;
}
return true;
}
};