sks.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. enum SKSAnimState
  2. {
  3. DEFAULT = 0, ///< default weapon state, closed and discharged
  4. OPENED = 1,
  5. JAMMED = 2,
  6. };
  7. enum SKSStableStateID
  8. {
  9. UNKNOWN = 0,
  10. SKS_CLO_BU0 = 1,
  11. SKS_CLO_BU1 = 2,
  12. SKS_OPN_BU0 = 3,
  13. SKS_JAM_BU1 = 4
  14. }
  15. class SKS_CLO_BU0 extends WeaponStableState
  16. {
  17. override void OnEntry (WeaponEventBase e) { if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " { close nobull"); } super.OnEntry(e); }
  18. override void OnExit (WeaponEventBase e) { super.OnExit(e); if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " } close nobull"); } }
  19. override int GetCurrentStateID () { return SKSStableStateID.SKS_CLO_BU0; }
  20. override bool HasBullet () { return false; }
  21. override bool HasMagazine () { return false; }
  22. override bool IsJammed () { return false; }
  23. override bool IsRepairEnabled () { return true; }
  24. override void InitMuzzleArray () { m_muzzleHasBullet = {MuzzleState.E}; }
  25. };
  26. class SKS_CLO_BU1 extends WeaponStableState
  27. {
  28. override void OnEntry (WeaponEventBase e) { if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " { close bullet"); } super.OnEntry(e); }
  29. override void OnExit (WeaponEventBase e) { super.OnExit(e); if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " } close bullet"); } }
  30. override int GetCurrentStateID () { return SKSStableStateID.SKS_CLO_BU1; }
  31. override bool HasBullet () { return true; }
  32. override bool HasMagazine () { return false; }
  33. override bool IsJammed () { return false; }
  34. override bool IsRepairEnabled () { return true; }
  35. override void InitMuzzleArray () { m_muzzleHasBullet = {MuzzleState.L}; }
  36. };
  37. class SKS_OPN_BU0 extends WeaponStableState
  38. {
  39. override void OnEntry (WeaponEventBase e) { if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " { open nobull"); } m_weapon.SetWeaponOpen(true); super.OnEntry(e); }
  40. override void OnExit (WeaponEventBase e) { super.OnExit(e); if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " } open nobull"); } }
  41. override int GetCurrentStateID () { return SKSStableStateID.SKS_OPN_BU0; }
  42. override bool HasBullet () { return false; }
  43. override bool HasMagazine () { return false; }
  44. override bool IsJammed () { return false; }
  45. override bool IsBoltOpen () { return true; }
  46. override bool IsRepairEnabled () { return true; }
  47. override void InitMuzzleArray () { m_muzzleHasBullet = {MuzzleState.E}; }
  48. };
  49. class SKS_JAM_BU1 extends WeaponStateJammed
  50. {
  51. override void OnEntry (WeaponEventBase e) { if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " { jammed bullet"); } super.OnEntry(e); }
  52. override void OnExit (WeaponEventBase e) { super.OnExit(e); if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " } jammed bullet"); } }
  53. override int GetCurrentStateID () { return SKSStableStateID.SKS_JAM_BU1; }
  54. override bool HasBullet () { return true; }
  55. override bool HasMagazine () { return false; }
  56. override bool IsJammed () { return true; }
  57. override bool IsBoltOpen () { return true; }
  58. override bool IsRepairEnabled () { return true; }
  59. override void InitMuzzleArray () { m_muzzleHasBullet = {MuzzleState.F}; }
  60. };
  61. /**@class Rifle_Base
  62. * @brief base for rifles
  63. * @NOTE name copies config base class
  64. **/
  65. class SKS_Base extends Rifle_Base
  66. {
  67. ref WeaponStableState C0;
  68. ref WeaponStableState C1;
  69. ref WeaponStableState L0;
  70. ref WeaponStableState JF;
  71. override RecoilBase SpawnRecoilObject()
  72. {
  73. return new SKSRecoil(this);
  74. }
  75. override void InitStateMachine()
  76. {
  77. m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_CLOSED_KEEP));
  78. m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_CLOSED));
  79. m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_OPENED));
  80. m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_ENDLOOPABLE));
  81. m_abilities.Insert(new AbilityRecord(WeaponActions.RELOAD_CLIP, 0));
  82. m_abilities.Insert(new AbilityRecord(WeaponActions.MECHANISM, GetWeaponSpecificCommand(WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_CLOSED)));
  83. m_abilities.Insert(new AbilityRecord(WeaponActions.MECHANISM, GetWeaponSpecificCommand(WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_OPENED)));//????
  84. m_abilities.Insert(new AbilityRecord(WeaponActions.UNJAMMING, GetWeaponSpecificCommand(WeaponActions.UNJAMMING, WeaponActionUnjammingTypes.UNJAMMING_START)));
  85. m_abilities.Insert(new AbilityRecord(WeaponActions.UNJAMMING, GetWeaponSpecificCommand(WeaponActions.UNJAMMING, WeaponActionUnjammingTypes.UNJAMMING_END)));
  86. m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, GetWeaponSpecificCommand(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_NORMAL)));
  87. m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, GetWeaponSpecificCommand(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_LAST)));
  88. m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, GetWeaponSpecificCommand(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_JAM)));
  89. m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, GetWeaponSpecificCommand(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_DRY)));
  90. //m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_UNCOCKED));
  91. // setup state machine
  92. // basic weapon states
  93. // close-locked-jammed | nobullet-bullet | nomag-mag
  94. // regexp: [CLJ][01][01]
  95. C0 = new SKS_CLO_BU0(this, NULL, SKSAnimState.DEFAULT);
  96. C1 = new SKS_CLO_BU1(this, NULL, SKSAnimState.DEFAULT);
  97. L0 = new SKS_OPN_BU0(this, NULL, SKSAnimState.OPENED);
  98. JF = new SKS_JAM_BU1(this, NULL, SKSAnimState.JAMMED);
  99. // unstable (intermediate) states
  100. WeaponChargingInnerMag Mech_C0 = new WeaponChargingInnerMag(this, NULL, WeaponActions.MECHANISM, GetWeaponSpecificCommand(WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_CLOSED));
  101. WeaponChargingInnerMag Mech_L0 = new WeaponChargingInnerMag(this, NULL, WeaponActions.MECHANISM, GetWeaponSpecificCommand(WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_OPENED));
  102. WeaponChargingInnerMag Mech_C1 = new WeaponChargingInnerMag(this, NULL, WeaponActions.MECHANISM, GetWeaponSpecificCommand(WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_CLOSED));
  103. //Fire
  104. WeaponStateBase Trigger_C0 = new WeaponDryFire(this, NULL, WeaponActions.FIRE, GetWeaponSpecificCommand(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_DRY)); // cock without clip
  105. WeaponFireAndChamberFromInnerMagazine Trigger_C1 = new WeaponFireAndChamberFromInnerMagazine(this, NULL, WeaponActions.FIRE, GetWeaponSpecificCommand(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_NORMAL) );
  106. WeaponStateBase Trigger_C1L = new WeaponFireLast(this, NULL, WeaponActions.FIRE, GetWeaponSpecificCommand(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_LAST));
  107. WeaponStateBase Trigger_L0 = new WeaponDryFire(this, NULL, WeaponActions.FIRE, GetWeaponSpecificCommand(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_DRY));
  108. WeaponStateBase Trigger_JF = new WeaponDryFire(this, NULL, WeaponActions.FIRE, GetWeaponSpecificCommand(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_DRY));
  109. WeaponStateBase Trigger_C1J = new WeaponFireToJam(this, NULL, WeaponActions.FIRE, WeaponActionFireTypes.FIRE_JAM);
  110. //Unjam
  111. WeaponStateBase Unjam_JF = new WeaponUnjamming(this, NULL, WeaponActions.UNJAMMING, GetWeaponSpecificCommand(WeaponActions.UNJAMMING, WeaponActionUnjammingTypes.UNJAMMING_START));
  112. //Chambering
  113. LoopedChambering Chamber_C0 = new LoopedChambering(this, NULL, WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_CLOSED, WeaponActionChamberingTypes.CHAMBERING_ENDLOOPABLE);
  114. LoopedChambering Chamber_C1 = new LoopedChambering(this, NULL, WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_CLOSED_KEEP, WeaponActionChamberingTypes.CHAMBERING_ENDLOOPABLE);
  115. LoopedChambering Chamber_L0 = new LoopedChambering(this, NULL, WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_STARTLOOPABLE_OPENED, WeaponActionChamberingTypes.CHAMBERING_ENDLOOPABLE);
  116. //WeaponStateBase chmMag = new WeaponChamberFromAttMag(this, NULL, WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_CLOSED);
  117. // events
  118. WeaponEventBase __M__ = new WeaponEventMechanism;
  119. WeaponEventBase __T__ = new WeaponEventTrigger;
  120. WeaponEventBase __TJ_ = new WeaponEventTriggerToJam;
  121. WeaponEventBase __U__ = new WeaponEventUnjam;
  122. WeaponEventBase __L__ = new WeaponEventLoad1Bullet;
  123. WeaponEventBase _fin_ = new WeaponEventHumanCommandActionFinished;
  124. WeaponEventBase _abt_ = new WeaponEventHumanCommandActionAborted;
  125. WeaponEventBase _rto_ = new WeaponEventReloadTimeout;
  126. WeaponEventBase _dto_ = new WeaponEventDryFireTimeout;
  127. m_fsm = new WeaponFSM();
  128. // order: Discharged-Charged | nobullet-bullet | nomag-mag
  129. // charging
  130. m_fsm.AddTransition(new WeaponTransition( C0, __M__, Mech_C1)); // charge from dischg nobullet nomag
  131. m_fsm.AddTransition(new WeaponTransition( C1, __M__, Mech_C1)); // charge from bullet nomag
  132. m_fsm.AddTransition(new WeaponTransition( Mech_C1, _fin_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this) ));
  133. m_fsm.AddTransition(new WeaponTransition( Mech_C1, _fin_, C1));
  134. m_fsm.AddTransition(new WeaponTransition( Mech_C1, _abt_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this) ));
  135. m_fsm.AddTransition(new WeaponTransition( Mech_C1, _abt_, C1));
  136. m_fsm.AddTransition(new WeaponTransition( L0, __M__, Mech_L0)); // charge from dischg nobullet nomag
  137. m_fsm.AddTransition(new WeaponTransition( Mech_L0, _fin_, L0, NULL, new WeaponGuardWeaponOpen(this)));
  138. m_fsm.AddTransition(new WeaponTransition( Mech_L0, _fin_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this) ));
  139. m_fsm.AddTransition(new WeaponTransition( Mech_L0, _fin_, C1));
  140. m_fsm.AddTransition(new WeaponTransition( Mech_L0, _abt_, L0, NULL, new WeaponGuardWeaponOpen(this)));
  141. m_fsm.AddTransition(new WeaponTransition( Mech_L0, _abt_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this) ));
  142. m_fsm.AddTransition(new WeaponTransition( Mech_L0, _abt_, C1));
  143. /*m_start = new WeaponCharging_Start(m_weapon, this, m_action, m_actionType);
  144. m_onBE = new WeaponEjectBullet_Cartridge_W4T(m_weapon, this);
  145. m_onBEFireOut = new WeaponEjectCasing_W4T(m_weapon, this);
  146. m_hideB = new BulletHide_W4T(m_weapon, this);
  147. m_onCK = new WeaponCharging_CK(m_weapon, this);
  148. m_chamber = new WeaponChamberFromInnerMag_W4T(m_weapon, this);*/
  149. // fire
  150. m_fsm.AddTransition(new WeaponTransition( C0, __T__, Trigger_C0));
  151. m_fsm.AddTransition(new WeaponTransition( Trigger_C0, _fin_, C0));
  152. m_fsm.AddTransition(new WeaponTransition( Trigger_C0, _dto_, C0));
  153. m_fsm.AddTransition(new WeaponTransition( Trigger_C0, _abt_, C0));
  154. m_fsm.AddTransition(new WeaponTransition( C1, __T__, Trigger_C1, NULL, new WeaponGuardHasAmmoInnerMagazine(this)));
  155. m_fsm.AddTransition(new WeaponTransition( Trigger_C1, _fin_, C1));
  156. m_fsm.AddTransition(new WeaponTransition( Trigger_C1, _rto_, C1));
  157. m_fsm.AddTransition(new WeaponTransition( Trigger_C1, _abt_, C1));
  158. m_fsm.AddTransition(new WeaponTransition( C1, __T__, Trigger_C1L));
  159. m_fsm.AddTransition(new WeaponTransition( Trigger_C1L, _fin_, L0));
  160. m_fsm.AddTransition(new WeaponTransition( Trigger_C1L, _rto_, L0));
  161. m_fsm.AddTransition(new WeaponTransition( Trigger_C1L, _abt_, L0));
  162. m_fsm.AddTransition(new WeaponTransition( C1, __TJ_, Trigger_C1J));
  163. m_fsm.AddTransition(new WeaponTransition( Trigger_C1J, _fin_, JF ));
  164. m_fsm.AddTransition(new WeaponTransition( Trigger_C1J, _rto_, JF ));
  165. m_fsm.AddTransition(new WeaponTransition( Trigger_C1J, _abt_, JF ));
  166. m_fsm.AddTransition(new WeaponTransition( L0, __T__, Trigger_L0));
  167. m_fsm.AddTransition(new WeaponTransition( Trigger_L0, _fin_, L0));
  168. m_fsm.AddTransition(new WeaponTransition( Trigger_L0, _dto_, L0));
  169. m_fsm.AddTransition(new WeaponTransition( Trigger_L0, _abt_, L0));
  170. m_fsm.AddTransition(new WeaponTransition( JF, __T__, Trigger_JF)); // opened fire.uncocked w mag
  171. m_fsm.AddTransition(new WeaponTransition( Trigger_JF, _fin_, JF));
  172. m_fsm.AddTransition(new WeaponTransition( Trigger_JF, _dto_, JF));
  173. m_fsm.AddTransition(new WeaponTransition( Trigger_JF, _abt_, JF));
  174. // load cartridge
  175. m_fsm.AddTransition(new WeaponTransition( C0, __L__, Chamber_C0));
  176. m_fsm.AddTransition(new WeaponTransition( Chamber_C0, _fin_, L0, NULL, new WeaponGuardWeaponOpen(this)));
  177. m_fsm.AddTransition(new WeaponTransition( Chamber_C0, _fin_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this)));
  178. m_fsm.AddTransition(new WeaponTransition( Chamber_C0, _fin_, C1));
  179. m_fsm.AddTransition(new WeaponTransition( Chamber_C0, _abt_, L0, NULL, new WeaponGuardWeaponOpen(this)));
  180. m_fsm.AddTransition(new WeaponTransition( Chamber_C0, _abt_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this)));
  181. m_fsm.AddTransition(new WeaponTransition( Chamber_C0, _abt_, C1));
  182. m_fsm.AddTransition(new WeaponTransition( C1, __L__, Chamber_C1, NULL, new GuardNot(new WeaponGuardInnerMagazineFullShareChamber(this))));
  183. m_fsm.AddTransition(new WeaponTransition( Chamber_C1, _fin_, C1));
  184. m_fsm.AddTransition(new WeaponTransition( Chamber_C1, _abt_, C1));
  185. m_fsm.AddTransition(new WeaponTransition( L0, __L__, Chamber_L0, NULL, new GuardNot(new WeaponGuardInnerMagazineFullShareChamber(this))));
  186. m_fsm.AddTransition(new WeaponTransition( Chamber_L0, _fin_, L0, NULL, new WeaponGuardWeaponOpen(this)));
  187. m_fsm.AddTransition(new WeaponTransition( Chamber_L0, _fin_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this)));
  188. m_fsm.AddTransition(new WeaponTransition( Chamber_L0, _fin_, C1));
  189. m_fsm.AddTransition(new WeaponTransition( Chamber_L0, _abt_, L0, NULL, new WeaponGuardWeaponOpen(this)));
  190. m_fsm.AddTransition(new WeaponTransition( Chamber_L0, _abt_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this)));
  191. m_fsm.AddTransition(new WeaponTransition( Chamber_L0, _abt_, C1));
  192. // unjam
  193. m_fsm.AddTransition(new WeaponTransition( JF, __U__, Unjam_JF)); // unjam nomag
  194. m_fsm.AddTransition(new WeaponTransition( Unjam_JF, _fin_, JF, NULL, new WeaponGuardJammed(this)));
  195. m_fsm.AddTransition(new WeaponTransition( Unjam_JF, _fin_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this)));
  196. m_fsm.AddTransition(new WeaponTransition( Unjam_JF, _fin_, C1));
  197. m_fsm.AddTransition(new WeaponTransition( Unjam_JF, _abt_, JF, NULL, new WeaponGuardJammed(this)));
  198. m_fsm.AddTransition(new WeaponTransition( Unjam_JF, _abt_, C0, NULL, new WeaponGuardCurrentChamberEmpty(this)));
  199. m_fsm.AddTransition(new WeaponTransition( Unjam_JF, _abt_, C1));
  200. SetInitialState(C0);
  201. SelectionBulletHide();
  202. HideMagazine();
  203. m_fsm.Start();
  204. }
  205. override bool CanEnterIronsights()
  206. {
  207. ItemOptics optic = GetAttachedOptics();
  208. if (optic && PUScopeOptic.Cast(optic))
  209. return true;
  210. return super.CanEnterIronsights();
  211. }
  212. override void SetActions()
  213. {
  214. AddAction(FirearmActionLoadMultiBulletQuick);
  215. super.SetActions();
  216. AddAction(FirearmActionLoadMultiBullet);
  217. }
  218. //Debug menu Spawn Ground Special
  219. override void OnDebugSpawn()
  220. {
  221. super.OnDebugSpawn();
  222. GameInventory inventory = GetInventory();
  223. inventory.CreateInInventory( "PUScopeOptic" );
  224. inventory.CreateInInventory( "SKS_Bayonet" );
  225. }
  226. };