crossbow.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. enum XBAnimState
  2. {
  3. uncocked = 0, ///< default weapon state, closed and discharged
  4. cocked = 1,
  5. };
  6. enum XBStableStateID
  7. {
  8. UNKNOWN = 0,
  9. UncockedEmpty = 1,
  10. CockedEmpty = 2,
  11. Loaded = 3,
  12. }
  13. class XBUncockedEmpty extends WeaponStableState
  14. {
  15. override void OnEntry (WeaponEventBase e) { if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " { Uncocked Empty UE"); } m_weapon.SetCharged(false); super.OnEntry(e); }
  16. override void OnExit (WeaponEventBase e) { super.OnExit(e); if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " } Uncocked Empty UE"); } }
  17. override int GetCurrentStateID () { return XBStableStateID.UncockedEmpty; }
  18. override bool HasBullet () { return false; }
  19. override bool HasMagazine () { return false; }
  20. override bool IsJammed () { return false; }
  21. override bool IsRepairEnabled () { return true; }
  22. override void InitMuzzleArray () { m_muzzleHasBullet = {MuzzleState.E}; }
  23. };
  24. class XBCockedEmpty extends WeaponStableState
  25. {
  26. override void OnEntry (WeaponEventBase e) { if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " { Cocked Empty CE"); } m_weapon.SetCharged(true); super.OnEntry(e); }
  27. override void OnExit (WeaponEventBase e) { super.OnExit(e); if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " } Cocked Empty CE"); } }
  28. override int GetCurrentStateID () { return XBStableStateID.CockedEmpty; }
  29. override bool HasBullet () { return false; }
  30. override bool HasMagazine () { return false; }
  31. override bool IsJammed () { return false; }
  32. override bool IsRepairEnabled () { return true; }
  33. override void InitMuzzleArray () { m_muzzleHasBullet = {MuzzleState.E}; }
  34. };
  35. class XBLoaded extends WeaponStableState
  36. {
  37. override void OnEntry (WeaponEventBase e) { if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " { Loaded L"); } m_weapon.SetCharged(true); super.OnEntry(e); }
  38. override void OnExit (WeaponEventBase e) { super.OnExit(e); if (LogManager.IsWeaponLogEnable()) { wpnPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " } Loaded L"); } }
  39. override int GetCurrentStateID () { return XBStableStateID.Loaded; }
  40. override bool HasBullet () { return true; }
  41. override bool HasMagazine () { return false; }
  42. override bool IsJammed () { return false; }
  43. override bool IsRepairEnabled () { return true; }
  44. override void InitMuzzleArray () { m_muzzleHasBullet = {MuzzleState.L}; }
  45. };
  46. /**@class Crossbow_Base
  47. * @brief base for Crossbow
  48. * @NOTE name copies config base class
  49. **/
  50. class Crossbow_Base : Archery_Base
  51. {
  52. void Crossbow_Base();
  53. override RecoilBase SpawnRecoilObject()
  54. {
  55. return new CrossbowRecoil(this);
  56. }
  57. override void InitStateMachine()
  58. {
  59. // setup abilities
  60. m_abilities.Insert(new AbilityRecord(WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_OPENED));
  61. m_abilities.Insert(new AbilityRecord(WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_SPECIAL));
  62. m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_CROSSBOW_OPENED));
  63. m_abilities.Insert(new AbilityRecord(WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_CROSSBOW_CLOSED));
  64. m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_NORMAL));
  65. m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_UNCOCKED));
  66. m_abilities.Insert(new AbilityRecord(WeaponActions.FIRE, WeaponActionFireTypes.FIRE_COCKED));
  67. // setup state machine
  68. // basic weapon states
  69. WeaponStableState U = new XBUncockedEmpty(this, NULL, XBAnimState.uncocked);
  70. WeaponStableState C = new XBCockedEmpty(this, NULL, XBAnimState.cocked);
  71. WeaponStableState L = new XBLoaded(this, NULL, XBAnimState.cocked);
  72. // unstable (intermediate) states
  73. WeaponChargingStretch Mech_U = new WeaponChargingStretch(this, NULL, WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_OPENED);
  74. WeaponEjectBullet Mech_L = new WeaponEjectBullet(this, NULL, WeaponActions.MECHANISM, WeaponActionMechanismTypes.MECHANISM_SPECIAL);
  75. WeaponChambering Chamber_U = new WeaponChambering(this, NULL, WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_CROSSBOW_OPENED);
  76. WeaponChambering Chamber_C = new WeaponChambering(this, NULL, WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_CROSSBOW_CLOSED);
  77. //CrossbowReChambering Chamber_L = new CrossbowReChambering(this, NULL, WeaponActions.CHAMBERING, WeaponActionChamberingTypes.CHAMBERING_ONEBULLET_CLOSED);
  78. WeaponStateBase Trigger_U = new WeaponDryFire(this, NULL, WeaponActions.FIRE, WeaponActionFireTypes.FIRE_UNCOCKED);
  79. WeaponStateBase Trigger_C = new WeaponDryFire(this, NULL, WeaponActions.FIRE, WeaponActionFireTypes.FIRE_COCKED);
  80. WeaponStateBase Trigger_L = new WeaponFireLast(this, NULL, WeaponActions.FIRE, WeaponActionFireTypes.FIRE_NORMAL);
  81. WeaponStateBase Unjam_J = new WeaponUnjamming(this, NULL, WeaponActions.UNJAMMING, WeaponActionUnjammingTypes.UNJAMMING_START);
  82. // events
  83. WeaponEventBase __M__ = new WeaponEventMechanism;
  84. WeaponEventBase __T__ = new WeaponEventTrigger;
  85. WeaponEventBase __TJ_ = new WeaponEventTriggerToJam;
  86. WeaponEventBase __L__ = new WeaponEventLoad1Bullet;
  87. WeaponEventBase __U__ = new WeaponEventUnjam;
  88. WeaponEventBase _fin_ = new WeaponEventHumanCommandActionFinished;
  89. WeaponEventBase _abt_ = new WeaponEventHumanCommandActionAborted;
  90. WeaponEventBase _dto_ = new WeaponEventDryFireTimeout;
  91. m_fsm = new WeaponFSM();
  92. //Charging
  93. m_fsm.AddTransition(new WeaponTransition( C, __M__, C));
  94. m_fsm.AddTransition(new WeaponTransition( U, __M__, Mech_U));
  95. m_fsm.AddTransition(new WeaponTransition( Mech_U, _fin_, U, null, new WeaponGuardWeaponDischarged(this)));
  96. m_fsm.AddTransition(new WeaponTransition( Mech_U, _fin_, C ));
  97. m_fsm.AddTransition(new WeaponTransition( Mech_U, _abt_, U, null, new WeaponGuardWeaponDischarged(this)));
  98. m_fsm.AddTransition(new WeaponTransition( Mech_U, _abt_, C ));
  99. m_fsm.AddTransition(new WeaponTransition( L, __M__, Mech_L));
  100. m_fsm.AddTransition(new WeaponTransition( Mech_L, _fin_, C, null, new WeaponGuardChamberEmpty(this)));
  101. m_fsm.AddTransition(new WeaponTransition( Mech_L, _fin_, L));
  102. m_fsm.AddTransition(new WeaponTransition( Mech_L, _abt_, C, null, new WeaponGuardChamberEmpty(this)));
  103. m_fsm.AddTransition(new WeaponTransition( Mech_L, _abt_, L));
  104. //Chamber bolt
  105. m_fsm.AddTransition(new WeaponTransition( U, __L__, Chamber_U));
  106. m_fsm.AddTransition(new WeaponTransition( Chamber_U, _fin_, L, null, new WeaponGuardChamberFull(this)));
  107. m_fsm.AddTransition(new WeaponTransition( Chamber_U, _fin_, C, null, new WeaponGuardWeaponCharged(this)));
  108. m_fsm.AddTransition(new WeaponTransition( Chamber_U, _fin_, U));
  109. m_fsm.AddTransition(new WeaponTransition( Chamber_U, _abt_, L, null, new WeaponGuardChamberFull(this)));
  110. m_fsm.AddTransition(new WeaponTransition( Chamber_U, _abt_, C, null, new WeaponGuardWeaponCharged(this)));
  111. m_fsm.AddTransition(new WeaponTransition( Chamber_U, _abt_, U));
  112. m_fsm.AddTransition(new WeaponTransition( C, __L__, Chamber_C));
  113. m_fsm.AddTransition(new WeaponTransition( Chamber_C, _fin_, L, null, new WeaponGuardChamberFull(this)));
  114. m_fsm.AddTransition(new WeaponTransition( Chamber_C, _fin_, C));
  115. m_fsm.AddTransition(new WeaponTransition( Chamber_C, _abt_, L, null, new WeaponGuardChamberFull(this)));
  116. m_fsm.AddTransition(new WeaponTransition( Chamber_C, _abt_, C));
  117. m_fsm.AddTransition(new WeaponTransition( C, __T__, Trigger_C));
  118. m_fsm.AddTransition(new WeaponTransition( Trigger_C, _fin_, U));
  119. m_fsm.AddTransition(new WeaponTransition( Trigger_C, _abt_, U));
  120. m_fsm.AddTransition(new WeaponTransition( Trigger_C, _dto_, U));
  121. m_fsm.AddTransition(new WeaponTransition( Trigger_C, _abt_, U));
  122. m_fsm.AddTransition(new WeaponTransition( U, __T__, Trigger_U));
  123. m_fsm.AddTransition(new WeaponTransition( Trigger_U, _fin_, U));
  124. m_fsm.AddTransition(new WeaponTransition( Trigger_U, _abt_, U));
  125. m_fsm.AddTransition(new WeaponTransition( Trigger_U, _dto_, U));
  126. m_fsm.AddTransition(new WeaponTransition( Trigger_U, _abt_, U));
  127. m_fsm.AddTransition(new WeaponTransition( L, __T__, Trigger_L));
  128. m_fsm.AddTransition(new WeaponTransition( Trigger_L, _fin_, U));
  129. m_fsm.AddTransition(new WeaponTransition( Trigger_L, _abt_, U));
  130. m_fsm.AddTransition(new WeaponTransition( Trigger_L, _dto_, U));
  131. m_fsm.AddTransition(new WeaponTransition( Trigger_L, _abt_, U));
  132. SelectionBulletHide();
  133. EffectBulletHide(0);
  134. SetInitialState(U);
  135. m_fsm.Start();
  136. }
  137. override float GetChanceToJam()
  138. {
  139. return 0.0;
  140. }
  141. override void OnDebugSpawnEx(DebugSpawnParams params)
  142. {
  143. //super.OnDebugSpawn();
  144. GetInventory().CreateInInventory( "ACOGOptic_6x" );
  145. EntityAI entity;
  146. GameInventory inv = null;
  147. if (params.m_Player)
  148. {
  149. inv = params.m_Player.GetInventory();
  150. }
  151. SpawnInInventoryOrGroundPos("Ammo_HuntingBolt", inv, GetPosition());
  152. SpawnInInventoryOrGroundPos("Ammo_ImprovisedBolt_1", inv, GetPosition());
  153. SpawnInInventoryOrGroundPos("Ammo_ImprovisedBolt_2", inv, GetPosition());
  154. SpawnInInventoryOrGroundPos("ACOGOptic", inv, GetPosition());
  155. entity = SpawnInInventoryOrGroundPos("M68Optic", inv, GetPosition());
  156. entity.GetInventory().CreateInInventory( "Battery9V" );
  157. entity = SpawnInInventoryOrGroundPos("M4_T3NRDSOptic", inv, GetPosition());
  158. entity.GetInventory().CreateInInventory( "Battery9V" );
  159. entity = SpawnInInventoryOrGroundPos("ReflexOptic", inv, GetPosition());
  160. entity.GetInventory().CreateInInventory( "Battery9V" );
  161. entity = SpawnInInventoryOrGroundPos("StarlightOptic", inv, GetPosition());
  162. entity.GetInventory().CreateInInventory( "Battery9V" );
  163. }
  164. override bool CanBeUsedForSuicide()
  165. {
  166. float ammoDamage;
  167. string ammoTypeName;
  168. GetCartridgeInfo(GetCurrentMuzzle(), ammoDamage, ammoTypeName);
  169. if (ammoTypeName == "Bullet_CupidsBolt")
  170. return false;
  171. return super.CanBeUsedForSuicide();
  172. }
  173. }
  174. class Crossbow : Crossbow_Base {}
  175. class Crossbow_Autumn : Crossbow_Base {}
  176. class Crossbow_Summer : Crossbow_Base {}
  177. class Crossbow_Black : Crossbow_Base {}
  178. class Crossbow_Wood : Crossbow_Base {}