WeaponSet.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // WeaponSet.h
  24. #pragma once
  25. #ifndef _WeaponSet_H_
  26. #define _WeaponSet_H_
  27. #include "Lib/BaseType.h"
  28. #include "Common/GameType.h"
  29. #include "Common/KindOf.h"
  30. #include "Common/ModelState.h"
  31. #include "Common/SparseMatchFinder.h"
  32. #include "Common/Snapshot.h"
  33. //-------------------------------------------------------------------------------------------------
  34. class INI;
  35. class Object;
  36. class Weapon;
  37. class WeaponTemplate;
  38. enum CommandSourceType;
  39. enum DamageType;
  40. // for WeaponSetType. Part of detangling.
  41. #include "GameLogic/WeaponSetType.h"
  42. //-------------------------------------------------------------------------------------------------
  43. // for WeaponSetFlags. Part of detangling.
  44. #include "GameLogic/WeaponSetFlags.h"
  45. #ifdef DEFINE_WEAPONSLOTTYPE_NAMES
  46. static char *TheWeaponSlotTypeNames[] =
  47. {
  48. "PRIMARY",
  49. "SECONDARY",
  50. "TERTIARY",
  51. NULL
  52. };
  53. static const LookupListRec TheWeaponSlotTypeNamesLookupList[] =
  54. {
  55. { "PRIMARY", PRIMARY_WEAPON },
  56. { "SECONDARY", SECONDARY_WEAPON },
  57. { "TERTIARY", TERTIARY_WEAPON },
  58. { NULL, 0 }// keep this last!
  59. };
  60. #endif
  61. //-------------------------------------------------------------------------------------------------
  62. #ifdef DEFINE_WEAPONCONDITIONMAP
  63. static const ModelConditionFlagType TheWeaponSetTypeToModelConditionTypeMap[WEAPONSET_COUNT] =
  64. {
  65. MODELCONDITION_WEAPONSET_VETERAN,
  66. MODELCONDITION_WEAPONSET_ELITE,
  67. MODELCONDITION_WEAPONSET_HERO,
  68. MODELCONDITION_WEAPONSET_PLAYER_UPGRADE,
  69. MODELCONDITION_WEAPONSET_CRATEUPGRADE_ONE,
  70. MODELCONDITION_WEAPONSET_CRATEUPGRADE_TWO
  71. };
  72. #endif
  73. //-------------------------------------------------------------------------------------------------
  74. enum WeaponSetConditionType
  75. {
  76. WSF_INVALID = -1,
  77. WSF_NONE = 0,
  78. WSF_FIRING,
  79. WSF_BETWEEN,
  80. WSF_RELOADING,
  81. WSF_PREATTACK,
  82. WSF_COUNT
  83. };
  84. //-------------------------------------------------------------------------------------------------
  85. class WeaponTemplateSet
  86. {
  87. private:
  88. const ThingTemplate* m_thingTemplate; // needed for save/load
  89. WeaponSetFlags m_types;
  90. const WeaponTemplate* m_template[WEAPONSLOT_COUNT];
  91. UnsignedInt m_autoChooseMask[WEAPONSLOT_COUNT];
  92. KindOfMaskType m_preferredAgainst[WEAPONSLOT_COUNT];
  93. Bool m_isReloadTimeShared;
  94. Bool m_isWeaponLockSharedAcrossSets; ///< A weapon set so similar that it is safe to hold locks across
  95. static void parseWeapon(INI* ini, void *instance, void *store, const void* userData);
  96. static void parseAutoChoose(INI* ini, void *instance, void *store, const void* userData);
  97. static void parsePreferredAgainst(INI* ini, void *instance, void *store, const void* userData);
  98. public:
  99. inline WeaponTemplateSet()
  100. {
  101. clear();
  102. }
  103. const ThingTemplate* friend_getThingTemplate() const { return m_thingTemplate; } // only for WeaponSet::xfer
  104. const WeaponSetFlags& friend_getWeaponSetFlags() const { return m_types; } // only for WeaponSet::xfer
  105. void clear();
  106. void parseWeaponTemplateSet( INI* ini, const ThingTemplate* tt );
  107. Bool testWeaponSetFlag( WeaponSetType wst ) const;
  108. Bool isSharedReloadTime( void ) const { return m_isReloadTimeShared; }
  109. Bool isWeaponLockSharedAcrossSets() const {return m_isWeaponLockSharedAcrossSets; }
  110. Bool hasAnyWeapons() const;
  111. inline const WeaponTemplate* getNth(WeaponSlotType n) const { return m_template[n]; }
  112. inline UnsignedInt getNthCommandSourceMask(WeaponSlotType n) const { return m_autoChooseMask[n]; }
  113. inline const KindOfMaskType& getNthPreferredAgainstMask(WeaponSlotType n) const { return m_preferredAgainst[n]; }
  114. inline Int getConditionsYesCount() const { return 1; }
  115. inline const WeaponSetFlags& getNthConditionsYes(Int i) const { return m_types; }
  116. #if defined(_DEBUG) || defined(_INTERNAL)
  117. inline AsciiString getDescription() const { return AsciiString("ArmorTemplateSet"); }
  118. #endif
  119. };
  120. //-------------------------------------------------------------------------------------------------
  121. typedef std::vector<WeaponTemplateSet> WeaponTemplateSetVector;
  122. //-------------------------------------------------------------------------------------------------
  123. typedef SparseMatchFinder<WeaponTemplateSet, WeaponSetFlags> WeaponTemplateSetFinder;
  124. //-------------------------------------------------------------------------------------------------
  125. enum WeaponChoiceCriteria
  126. {
  127. PREFER_MOST_DAMAGE, ///< choose the weapon that will do the most damage
  128. PREFER_LONGEST_RANGE ///< choose the weapon with the longest range (that will do nonzero damage)
  129. };
  130. //-------------------------------------------------------------------------------------------------
  131. enum WeaponLockType
  132. {
  133. NOT_LOCKED, ///< Weapon is not locked
  134. LOCKED_TEMPORARILY, ///< Weapon is locked until clip is empty, or current "attack" state exits
  135. LOCKED_PERMANENTLY ///< Weapon is locked until explicitly unlocked or lock is changed to another weapon
  136. };
  137. //-------------------------------------------------------------------------------------------------
  138. enum CanAttackResult
  139. {
  140. //Worst scenario to best scenario -- These must be done this way now!
  141. ATTACKRESULT_NOT_POSSIBLE, //Can't possibly attack target.
  142. ATTACKRESULT_INVALID_SHOT, //Not a clear shot
  143. ATTACKRESULT_POSSIBLE_AFTER_MOVING, //I can attack, but after moving closer.
  144. ATTACKRESULT_POSSIBLE, //I can attack now.
  145. };
  146. //-------------------------------------------------------------------------------------------------
  147. class WeaponSet : public Snapshot
  148. {
  149. private:
  150. const WeaponTemplateSet* m_curWeaponTemplateSet;
  151. Weapon* m_weapons[WEAPONSLOT_COUNT];
  152. WeaponSlotType m_curWeapon;
  153. WeaponLockType m_curWeaponLockedStatus;
  154. UnsignedInt m_filledWeaponSlotMask;
  155. Int m_totalAntiMask; ///< anti mask of all current weapons
  156. UnsignedInt m_totalDamageTypeMask; ///< damagetype mask of all current weapons
  157. Bool m_hasPitchLimit;
  158. Bool m_hasDamageWeapon;
  159. Bool isAnyWithinTargetPitch(const Object* obj, const Object* victim) const;
  160. protected:
  161. // snapshot methods
  162. virtual void crc( Xfer *xfer );
  163. virtual void xfer( Xfer *xfer );
  164. virtual void loadPostProcess( void );
  165. public:
  166. WeaponSet();
  167. ~WeaponSet();
  168. void updateWeaponSet(const Object* obj);
  169. void reloadAllAmmo(const Object *obj, Bool now);
  170. Bool isOutOfAmmo() const;
  171. Bool hasAnyWeapon() const { return m_filledWeaponSlotMask != 0; }
  172. Bool hasAnyDamageWeapon() const { return m_hasDamageWeapon; }
  173. Bool hasWeaponToDealDamageType(DamageType typeToDeal) const { return (m_totalDamageTypeMask & (1 << typeToDeal)) != 0; }
  174. Bool hasSingleDamageType(DamageType typeToDeal) const { return m_totalDamageTypeMask == (1 << typeToDeal); }
  175. Bool isCurWeaponLocked() const { return m_curWeaponLockedStatus != NOT_LOCKED; }
  176. Weapon* getCurWeapon() { return m_weapons[m_curWeapon]; }
  177. const Weapon* getCurWeapon() const { return m_weapons[m_curWeapon]; }
  178. WeaponSlotType getCurWeaponSlot() const { return m_curWeapon; }
  179. Weapon* findWaypointFollowingCapableWeapon();
  180. const Weapon* findAmmoPipShowingWeapon() const;
  181. Bool setWeaponLock( WeaponSlotType weaponSlot, WeaponLockType lockType );
  182. void releaseWeaponLock(WeaponLockType lockType);
  183. Bool isSharedReloadTime() const;
  184. //When an AIAttackState is over, it needs to clean up any weapons that might be in leech range mode
  185. //or else those weapons will have unlimited range!
  186. void clearLeechRangeModeForAllWeapons();
  187. /**
  188. Determines if the unit has any weapon that could conceivably
  189. harm the victim. this does not take range, ammo, etc. into
  190. account, but immutable weapon properties, such as "can you
  191. target airborne victims".
  192. */
  193. CanAttackResult getAbleToAttackSpecificObject( AbleToAttackType t, const Object* obj, const Object* victim, CommandSourceType commandSource ) const;
  194. //When calling this function, all conditions must be validated to the point where we have decided that we wish to attack the object (faction checks, etc).
  195. //Now, we are determining if the attack itself is able to be performed!
  196. CanAttackResult getAbleToUseWeaponAgainstTarget( AbleToAttackType attackType, const Object *source, const Object *victim, const Coord3D *pos, CommandSourceType commandSource ) const;
  197. /**
  198. Selects the best weapon for the given target, and sets it as the current weapon.
  199. If there is no weapon that can damage the target, false is returned (and the current-weapon is unchanged).
  200. Note that this DOES take weapon attack range into account.
  201. */
  202. Bool chooseBestWeaponForTarget(const Object* obj, const Object* victim, WeaponChoiceCriteria criteria, CommandSourceType cmdSource);
  203. Weapon* getWeaponInWeaponSlot(WeaponSlotType wslot) const;
  204. static ModelConditionFlags getModelConditionForWeaponSlot(WeaponSlotType wslot, WeaponSetConditionType a);
  205. };
  206. #endif // _WeaponSet_H_