g_local.h 108 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649
  1. // Copyright (c) ZeniMax Media Inc.
  2. // Licensed under the GNU General Public License 2.0.
  3. // g_local.h -- local definitions for game module
  4. #pragma once
  5. #include "bg_local.h"
  6. // the "gameversion" client command will print this plus compile date
  7. constexpr const char *GAMEVERSION = "baseq2";
  8. //==================================================================
  9. constexpr vec3_t PLAYER_MINS = { -16, -16, -24 };
  10. constexpr vec3_t PLAYER_MAXS = { 16, 16, 32 };
  11. #include <charconv>
  12. template<typename T>
  13. constexpr bool is_char_ptr_v = std::is_convertible_v<T, const char*>;
  14. template<typename T>
  15. constexpr bool is_valid_loc_embed_v = !std::is_null_pointer_v<T> && (std::is_floating_point_v<std::remove_reference_t<T>> || std::is_integral_v<std::remove_reference_t<T>> || is_char_ptr_v<T>);
  16. struct local_game_import_t : game_import_t
  17. {
  18. inline local_game_import_t() = default;
  19. inline local_game_import_t(const game_import_t &imports) :
  20. game_import_t(imports)
  21. {
  22. }
  23. private:
  24. // shared buffer for wrappers below
  25. static char print_buffer[0x10000];
  26. public:
  27. #ifdef USE_CPP20_FORMAT
  28. template<typename... Args>
  29. inline void Com_PrintFmt(std::format_string<Args...> format_str, Args &&... args)
  30. #else
  31. #define Com_PrintFmt(str, ...) \
  32. Com_PrintFmt_(FMT_STRING(str), __VA_ARGS__)
  33. template<typename S, typename... Args>
  34. inline void Com_PrintFmt_(const S &format_str, Args &&... args)
  35. #endif
  36. {
  37. G_FmtTo_(print_buffer, format_str, std::forward<Args>(args)...);
  38. Com_Print(print_buffer);
  39. }
  40. #ifdef USE_CPP20_FORMAT
  41. template<typename... Args>
  42. inline void Com_ErrorFmt(std::format_string<Args...> format_str, Args &&... args)
  43. #else
  44. #define Com_ErrorFmt(str, ...) \
  45. Com_ErrorFmt_(FMT_STRING(str), __VA_ARGS__)
  46. template<typename S, typename... Args>
  47. inline void Com_ErrorFmt_(const S &format_str, Args &&... args)
  48. #endif
  49. {
  50. G_FmtTo_(print_buffer, format_str, std::forward<Args>(args)...);
  51. Com_Error(print_buffer);
  52. }
  53. private:
  54. // localized print functions
  55. template<typename T>
  56. inline void loc_embed(T input, char* buffer, const char*& output)
  57. {
  58. if constexpr (std::is_floating_point_v<T> || std::is_integral_v<T>)
  59. {
  60. auto result = std::to_chars(buffer, buffer + MAX_INFO_STRING - 1, input);
  61. *result.ptr = '\0';
  62. output = buffer;
  63. }
  64. else if constexpr (is_char_ptr_v<T>)
  65. {
  66. if (!input)
  67. Com_Error("null const char ptr passed to loc");
  68. output = input;
  69. }
  70. else
  71. Com_Error("invalid loc argument");
  72. }
  73. static std::array<char[MAX_INFO_STRING], MAX_LOCALIZATION_ARGS> buffers;
  74. static std::array<const char*, MAX_LOCALIZATION_ARGS> buffer_ptrs;
  75. public:
  76. template<typename... Args>
  77. inline void LocClient_Print(edict_t* e, print_type_t level, const char* base, Args&& ...args)
  78. {
  79. static_assert(sizeof...(args) < MAX_LOCALIZATION_ARGS, "too many arguments to gi.LocClient_Print");
  80. static_assert(((is_valid_loc_embed_v<Args>) && ...), "invalid argument passed to gi.LocClient_Print");
  81. size_t n = 0;
  82. ((loc_embed(args, buffers[n], buffer_ptrs[n]), ++n), ...);
  83. Loc_Print(e, level, base, &buffer_ptrs.front(), sizeof...(args));
  84. }
  85. template<typename... Args>
  86. inline void LocBroadcast_Print(print_type_t level, const char* base, Args&& ...args)
  87. {
  88. static_assert(sizeof...(args) < MAX_LOCALIZATION_ARGS, "too many arguments to gi.LocBroadcast_Print");
  89. static_assert(((is_valid_loc_embed_v<Args>) && ...), "invalid argument passed to gi.LocBroadcast_Print");
  90. size_t n = 0;
  91. ((loc_embed(args, buffers[n], buffer_ptrs[n]), ++n), ...);
  92. Loc_Print(nullptr, (print_type_t)(level | print_type_t::PRINT_BROADCAST), base, &buffer_ptrs.front(), sizeof...(args));
  93. }
  94. template<typename... Args>
  95. inline void LocCenter_Print(edict_t* e, const char* base, Args&& ...args)
  96. {
  97. static_assert(sizeof...(args) < MAX_LOCALIZATION_ARGS, "too many arguments to gi.LocCenter_Print");
  98. static_assert(((is_valid_loc_embed_v<Args>) && ...), "invalid argument passed to gi.LocCenter_Print");
  99. size_t n = 0;
  100. ((loc_embed(args, buffers[n], buffer_ptrs[n]), ++n), ...);
  101. Loc_Print(e, PRINT_CENTER, base, &buffer_ptrs.front(), sizeof...(args));
  102. }
  103. // collision detection
  104. [[nodiscard]] inline trace_t trace(const vec3_t &start, const vec3_t &mins, const vec3_t &maxs, const vec3_t &end, const edict_t *passent, contents_t contentmask)
  105. {
  106. return game_import_t::trace(start, &mins, &maxs, end, passent, contentmask);
  107. }
  108. [[nodiscard]] inline trace_t traceline(const vec3_t &start, const vec3_t &end, const edict_t *passent, contents_t contentmask)
  109. {
  110. return game_import_t::trace(start, nullptr, nullptr, end, passent, contentmask);
  111. }
  112. // [Paril-KEX] clip the box against the specified entity
  113. [[nodiscard]] inline trace_t clip(edict_t *entity, const vec3_t &start, const vec3_t &mins, const vec3_t &maxs, const vec3_t &end, contents_t contentmask)
  114. {
  115. return game_import_t::clip(entity, start, &mins, &maxs, end, contentmask);
  116. }
  117. [[nodiscard]] inline trace_t clip(edict_t *entity, const vec3_t &start, const vec3_t &end, contents_t contentmask)
  118. {
  119. return game_import_t::clip(entity, start, nullptr, nullptr, end, contentmask);
  120. }
  121. void unicast(edict_t *ent, bool reliable, uint32_t dupe_key = 0)
  122. {
  123. game_import_t::unicast(ent, reliable, dupe_key);
  124. }
  125. void local_sound(edict_t *target, const vec3_t &origin, edict_t *ent, soundchan_t channel, int soundindex, float volume, float attenuation, float timeofs, uint32_t dupe_key = 0)
  126. {
  127. game_import_t::local_sound(target, &origin, ent, channel, soundindex, volume, attenuation, timeofs, dupe_key);
  128. }
  129. void local_sound(edict_t *target, edict_t *ent, soundchan_t channel, int soundindex, float volume, float attenuation, float timeofs, uint32_t dupe_key = 0)
  130. {
  131. game_import_t::local_sound(target, nullptr, ent, channel, soundindex, volume, attenuation, timeofs, dupe_key);
  132. }
  133. void local_sound(const vec3_t &origin, edict_t *ent, soundchan_t channel, int soundindex, float volume, float attenuation, float timeofs, uint32_t dupe_key = 0)
  134. {
  135. game_import_t::local_sound(ent, &origin, ent, channel, soundindex, volume, attenuation, timeofs, dupe_key);
  136. }
  137. void local_sound(edict_t *ent, soundchan_t channel, int soundindex, float volume, float attenuation, float timeofs, uint32_t dupe_key = 0)
  138. {
  139. game_import_t::local_sound(ent, nullptr, ent, channel, soundindex, volume, attenuation, timeofs, dupe_key);
  140. }
  141. };
  142. extern local_game_import_t gi;
  143. // edict->spawnflags
  144. // these are set with checkboxes on each entity in the map editor.
  145. // the following 8 are reserved and should never be used by any entity.
  146. // (power cubes in coop use these after spawning as well)
  147. struct spawnflags_t
  148. {
  149. uint32_t value;
  150. explicit constexpr spawnflags_t(uint32_t v) :
  151. value(v)
  152. {
  153. }
  154. explicit operator uint32_t() const
  155. {
  156. return value;
  157. }
  158. // has any flags at all (!!a)
  159. constexpr bool any() const { return !!value; }
  160. // has any of the given flags (!!(a & b))
  161. constexpr bool has(const spawnflags_t &flags) const { return !!(value & flags.value); }
  162. // has all of the given flags ((a & b) == b)
  163. constexpr bool has_all(const spawnflags_t &flags) const { return (value & flags.value) == flags.value; }
  164. constexpr bool operator!() const { return !value; }
  165. constexpr bool operator==(const spawnflags_t &flags) const
  166. {
  167. return value == flags.value;
  168. }
  169. constexpr bool operator!=(const spawnflags_t &flags) const
  170. {
  171. return value != flags.value;
  172. }
  173. constexpr spawnflags_t operator~() const
  174. {
  175. return spawnflags_t(~value);
  176. }
  177. constexpr spawnflags_t operator|(const spawnflags_t &v2) const
  178. {
  179. return spawnflags_t(value | v2.value);
  180. }
  181. constexpr spawnflags_t operator&(const spawnflags_t &v2) const
  182. {
  183. return spawnflags_t(value & v2.value);
  184. }
  185. constexpr spawnflags_t operator^(const spawnflags_t &v2) const
  186. {
  187. return spawnflags_t(value ^ v2.value);
  188. }
  189. constexpr spawnflags_t &operator|=(const spawnflags_t &v2)
  190. {
  191. value |= v2.value;
  192. return *this;
  193. }
  194. constexpr spawnflags_t &operator&=(const spawnflags_t &v2)
  195. {
  196. value &= v2.value;
  197. return *this;
  198. }
  199. constexpr spawnflags_t &operator^=(const spawnflags_t &v2)
  200. {
  201. value ^= v2.value;
  202. return *this;
  203. }
  204. };
  205. // these spawnflags affect every entity. note that items are a bit special
  206. // because these 8 bits are instead used for power cube bits.
  207. constexpr spawnflags_t SPAWNFLAG_NONE = spawnflags_t(0);
  208. constexpr spawnflags_t SPAWNFLAG_NOT_EASY = spawnflags_t(0x00000100),
  209. SPAWNFLAG_NOT_MEDIUM = spawnflags_t(0x00000200),
  210. SPAWNFLAG_NOT_HARD = spawnflags_t(0x00000400),
  211. SPAWNFLAG_NOT_DEATHMATCH = spawnflags_t(0x00000800),
  212. SPAWNFLAG_NOT_COOP = spawnflags_t(0x00001000),
  213. SPAWNFLAG_RESERVED1 = spawnflags_t(0x00002000),
  214. SPAWNFLAG_COOP_ONLY = spawnflags_t(0x00004000),
  215. SPAWNFLAG_RESERVED2 = spawnflags_t(0x00008000);
  216. constexpr spawnflags_t SPAWNFLAG_EDITOR_MASK = (SPAWNFLAG_NOT_EASY | SPAWNFLAG_NOT_MEDIUM | SPAWNFLAG_NOT_HARD | SPAWNFLAG_NOT_DEATHMATCH |
  217. SPAWNFLAG_NOT_COOP | SPAWNFLAG_RESERVED1 | SPAWNFLAG_COOP_ONLY | SPAWNFLAG_RESERVED2);
  218. // use this for global spawnflags
  219. constexpr spawnflags_t operator "" _spawnflag(unsigned long long int v)
  220. {
  221. if (v & SPAWNFLAG_EDITOR_MASK.value)
  222. throw std::invalid_argument("attempting to use reserved spawnflag");
  223. return static_cast<spawnflags_t>(static_cast<uint32_t>(v));
  224. }
  225. // use this for global spawnflags
  226. constexpr spawnflags_t operator "" _spawnflag_bit(unsigned long long int v)
  227. {
  228. v = 1ull << v;
  229. if (v & SPAWNFLAG_EDITOR_MASK.value)
  230. throw std::invalid_argument("attempting to use reserved spawnflag");
  231. return static_cast<spawnflags_t>(static_cast<uint32_t>(v));
  232. }
  233. // stores a level time; most newer engines use int64_t for
  234. // time storage, but seconds are handy for compatibility
  235. // with Quake and older mods.
  236. struct gtime_t
  237. {
  238. private:
  239. // times always start at zero, just to prevent memory issues
  240. int64_t _ms = 0;
  241. // internal; use _sec/_ms/_min or gtime_t::from_sec(n)/gtime_t::from_ms(n)/gtime_t::from_min(n)
  242. constexpr explicit gtime_t(const int64_t &ms) : _ms(ms)
  243. {
  244. }
  245. public:
  246. constexpr gtime_t() = default;
  247. constexpr gtime_t(const gtime_t &) = default;
  248. constexpr gtime_t &operator=(const gtime_t &) = default;
  249. // constructors are here, explicitly named, so you always
  250. // know what you're getting.
  251. // new time from ms
  252. static constexpr gtime_t from_ms(const int64_t &ms)
  253. {
  254. return gtime_t(ms);
  255. }
  256. // new time from seconds
  257. template<typename T, typename = std::enable_if_t<std::is_floating_point_v<T> || std::is_integral_v<T>>>
  258. static constexpr gtime_t from_sec(const T &s)
  259. {
  260. return gtime_t(static_cast<int64_t>(s * 1000));
  261. }
  262. // new time from minutes
  263. template<typename T, typename = std::enable_if_t<std::is_floating_point_v<T> || std::is_integral_v<T>>>
  264. static constexpr gtime_t from_min(const T &s)
  265. {
  266. return gtime_t(static_cast<int64_t>(s * 60000));
  267. }
  268. // new time from hz
  269. static constexpr gtime_t from_hz(const uint64_t &hz)
  270. {
  271. return from_ms(static_cast<int64_t>((1.0 / hz) * 1000));
  272. }
  273. // get value in minutes (truncated for integers)
  274. template<typename T = float>
  275. constexpr T minutes() const
  276. {
  277. return static_cast<T>(_ms / static_cast<std::conditional_t<std::is_floating_point_v<T>, T, float>>(60000));
  278. }
  279. // get value in seconds (truncated for integers)
  280. template<typename T = float>
  281. constexpr T seconds() const
  282. {
  283. return static_cast<T>(_ms / static_cast<std::conditional_t<std::is_floating_point_v<T>, T, float>>(1000));
  284. }
  285. // get value in milliseconds
  286. constexpr const int64_t &milliseconds() const
  287. {
  288. return _ms;
  289. }
  290. int64_t frames() const
  291. {
  292. return _ms / gi.frame_time_ms;
  293. }
  294. // check if non-zero
  295. constexpr explicit operator bool() const
  296. {
  297. return !!_ms;
  298. }
  299. // invert time
  300. constexpr gtime_t operator-() const
  301. {
  302. return gtime_t(-_ms);
  303. }
  304. // operations with other times as input
  305. constexpr gtime_t operator+(const gtime_t &r) const
  306. {
  307. return gtime_t(_ms + r._ms);
  308. }
  309. constexpr gtime_t operator-(const gtime_t &r) const
  310. {
  311. return gtime_t(_ms - r._ms);
  312. }
  313. constexpr gtime_t &operator+=(const gtime_t &r)
  314. {
  315. return *this = *this + r;
  316. }
  317. constexpr gtime_t &operator-=(const gtime_t &r)
  318. {
  319. return *this = *this - r;
  320. }
  321. // operations with scalars as input
  322. template<typename T, typename = std::enable_if_t<std::is_floating_point_v<T> || std::is_integral_v<T>>>
  323. constexpr gtime_t operator*(const T &r) const
  324. {
  325. return gtime_t::from_ms(static_cast<int64_t>(_ms * r));
  326. }
  327. template<typename T, typename = std::enable_if_t<std::is_floating_point_v<T> || std::is_integral_v<T>>>
  328. constexpr gtime_t operator/(const T &r) const
  329. {
  330. return gtime_t::from_ms(static_cast<int64_t>(_ms / r));
  331. }
  332. template<typename T, typename = std::enable_if_t<std::is_floating_point_v<T> || std::is_integral_v<T>>>
  333. constexpr gtime_t &operator*=(const T &r)
  334. {
  335. return *this = *this * r;
  336. }
  337. template<typename T, typename = std::enable_if_t<std::is_floating_point_v<T> || std::is_integral_v<T>>>
  338. constexpr gtime_t &operator/=(const T &r)
  339. {
  340. return *this = *this / r;
  341. }
  342. // comparisons with gtime_ts
  343. constexpr bool operator==(const gtime_t &time) const
  344. {
  345. return _ms == time._ms;
  346. }
  347. constexpr bool operator!=(const gtime_t &time) const
  348. {
  349. return _ms != time._ms;
  350. }
  351. constexpr bool operator<(const gtime_t &time) const
  352. {
  353. return _ms < time._ms;
  354. }
  355. constexpr bool operator>(const gtime_t &time) const
  356. {
  357. return _ms > time._ms;
  358. }
  359. constexpr bool operator<=(const gtime_t &time) const
  360. {
  361. return _ms <= time._ms;
  362. }
  363. constexpr bool operator>=(const gtime_t &time) const
  364. {
  365. return _ms >= time._ms;
  366. }
  367. };
  368. // user literals, allowing you to specify times
  369. // as 128_sec and 128_ms
  370. constexpr gtime_t operator"" _min(long double s)
  371. {
  372. return gtime_t::from_min(s);
  373. }
  374. constexpr gtime_t operator"" _min(unsigned long long int s)
  375. {
  376. return gtime_t::from_min(s);
  377. }
  378. constexpr gtime_t operator"" _sec(long double s)
  379. {
  380. return gtime_t::from_sec(s);
  381. }
  382. constexpr gtime_t operator"" _sec(unsigned long long int s)
  383. {
  384. return gtime_t::from_sec(s);
  385. }
  386. constexpr gtime_t operator"" _ms(long double s)
  387. {
  388. return gtime_t::from_ms(static_cast<int64_t>(s));
  389. }
  390. constexpr gtime_t operator"" _ms(unsigned long long int s)
  391. {
  392. return gtime_t::from_ms(static_cast<int64_t>(s));
  393. }
  394. constexpr gtime_t operator"" _hz(unsigned long long int s)
  395. {
  396. return gtime_t::from_ms(static_cast<int64_t>((1.0 / s) * 1000));
  397. }
  398. #define SERVER_TICK_RATE gi.tick_rate // in hz
  399. extern gtime_t FRAME_TIME_S;
  400. extern gtime_t FRAME_TIME_MS;
  401. // view pitching times
  402. inline gtime_t DAMAGE_TIME_SLACK()
  403. {
  404. return (100_ms - FRAME_TIME_MS);
  405. }
  406. inline gtime_t DAMAGE_TIME()
  407. {
  408. return 500_ms + DAMAGE_TIME_SLACK();
  409. }
  410. inline gtime_t FALL_TIME()
  411. {
  412. return 300_ms + DAMAGE_TIME_SLACK();
  413. }
  414. // every save_data_list_t has a tag
  415. // which is used for integrity checks.
  416. enum save_data_tag_t
  417. {
  418. SAVE_DATA_MMOVE,
  419. SAVE_FUNC_MONSTERINFO_STAND,
  420. SAVE_FUNC_MONSTERINFO_IDLE,
  421. SAVE_FUNC_MONSTERINFO_SEARCH,
  422. SAVE_FUNC_MONSTERINFO_WALK,
  423. SAVE_FUNC_MONSTERINFO_RUN,
  424. SAVE_FUNC_MONSTERINFO_DODGE,
  425. SAVE_FUNC_MONSTERINFO_ATTACK,
  426. SAVE_FUNC_MONSTERINFO_MELEE,
  427. SAVE_FUNC_MONSTERINFO_SIGHT,
  428. SAVE_FUNC_MONSTERINFO_CHECKATTACK,
  429. SAVE_FUNC_MONSTERINFO_SETSKIN,
  430. SAVE_FUNC_MONSTERINFO_BLOCKED,
  431. SAVE_FUNC_MONSTERINFO_DUCK,
  432. SAVE_FUNC_MONSTERINFO_UNDUCK,
  433. SAVE_FUNC_MONSTERINFO_SIDESTEP,
  434. SAVE_FUNC_MONSTERINFO_PHYSCHANGED,
  435. SAVE_FUNC_MOVEINFO_ENDFUNC,
  436. SAVE_FUNC_MOVEINFO_BLOCKED,
  437. SAVE_FUNC_PRETHINK,
  438. SAVE_FUNC_THINK,
  439. SAVE_FUNC_TOUCH,
  440. SAVE_FUNC_USE,
  441. SAVE_FUNC_PAIN,
  442. SAVE_FUNC_DIE
  443. };
  444. // forward-linked list, storing data for
  445. // saving pointers. every save_data_ptr has an
  446. // instance of this; there's one head instance of this
  447. // in g_save.cpp.
  448. struct save_data_list_t
  449. {
  450. const char *name; // name of savable object; persisted in the JSON file
  451. save_data_tag_t tag;
  452. const void *ptr; // pointer to raw data
  453. const save_data_list_t *next; // next in list
  454. save_data_list_t(const char *name, save_data_tag_t tag, const void *ptr);
  455. static const save_data_list_t *fetch(const void *link_ptr, save_data_tag_t tag);
  456. };
  457. #include <functional>
  458. // save data wrapper, which holds a pointer to a T
  459. // and the tag value for integrity. this is how you
  460. // store a savable pointer of data safely.
  461. template<typename T, size_t Tag>
  462. struct save_data_t
  463. {
  464. using value_type = typename std::conditional<std::is_pointer<T>::value &&
  465. std::is_function<typename std::remove_pointer<T>::type>::value,
  466. T,
  467. const T *>::type;
  468. private:
  469. value_type value;
  470. const save_data_list_t *list;
  471. public:
  472. constexpr save_data_t() :
  473. value(nullptr),
  474. list(nullptr)
  475. {
  476. }
  477. constexpr save_data_t(nullptr_t) :
  478. save_data_t()
  479. {
  480. }
  481. constexpr save_data_t(const save_data_list_t *list_in) :
  482. value(list_in->ptr),
  483. list(list_in)
  484. {
  485. }
  486. inline save_data_t(value_type ptr_in) :
  487. value(ptr_in),
  488. list(ptr_in ? save_data_list_t::fetch(reinterpret_cast<const void *>(ptr_in), static_cast<save_data_tag_t>(Tag)) : nullptr)
  489. {
  490. }
  491. inline save_data_t(const save_data_t<T, Tag> &ref_in) :
  492. save_data_t(ref_in.value)
  493. {
  494. }
  495. inline save_data_t &operator=(value_type ptr_in)
  496. {
  497. if (value != ptr_in)
  498. {
  499. value = ptr_in;
  500. list = value ? save_data_list_t::fetch(reinterpret_cast<const void *>(ptr_in), static_cast<save_data_tag_t>(Tag)) : nullptr;
  501. }
  502. return *this;
  503. }
  504. constexpr const value_type pointer() const { return value; }
  505. constexpr const save_data_list_t *save_list() const { return list; }
  506. constexpr const char *name() const { return value ? list->name : "null"; }
  507. constexpr const value_type operator->() const { return value; }
  508. constexpr explicit operator bool() const { return value; }
  509. constexpr bool operator==(value_type ptr_in) const { return value == ptr_in; }
  510. constexpr bool operator!=(value_type ptr_in) const { return value != ptr_in; }
  511. constexpr bool operator==(const save_data_t<T, Tag> *ptr_in) const { return value == ptr_in->value; }
  512. constexpr bool operator==(const save_data_t<T, Tag> &ref_in) const { return value == ref_in.value; }
  513. constexpr bool operator!=(const save_data_t<T, Tag> *ptr_in) const { return value != ptr_in->value; }
  514. constexpr bool operator!=(const save_data_t<T, Tag> &ref_in) const { return value != ref_in.value; }
  515. // invoke wrapper, for function-likes
  516. template<typename... Args>
  517. inline auto operator()(Args&& ...args) const
  518. {
  519. static_assert(std::is_invocable_v<std::remove_pointer_t<T>, Args...>, "bad invoke args");
  520. return std::invoke(value, std::forward<Args>(args)...);
  521. }
  522. };
  523. // memory tags to allow dynamic memory to be cleaned up
  524. enum
  525. {
  526. TAG_GAME = 765, // clear when unloading the dll
  527. TAG_LEVEL = 766 // clear when loading a new level
  528. };
  529. constexpr float MELEE_DISTANCE = 50;
  530. constexpr size_t BODY_QUEUE_SIZE = 8;
  531. // null trace used when touches don't need a trace
  532. constexpr trace_t null_trace {};
  533. enum weaponstate_t
  534. {
  535. WEAPON_READY,
  536. WEAPON_ACTIVATING,
  537. WEAPON_DROPPING,
  538. WEAPON_FIRING
  539. };
  540. // gib flags
  541. enum gib_type_t
  542. {
  543. GIB_NONE = 0, // no flags (organic)
  544. GIB_METALLIC = 1, // bouncier
  545. GIB_ACID = 2, // acidic (gekk)
  546. GIB_HEAD = 4, // head gib; the input entity will transform into this
  547. GIB_DEBRIS = 8, // explode outwards rather than in velocity, no blood
  548. GIB_SKINNED = 16, // use skinnum
  549. GIB_UPRIGHT = 32, // stay upright on ground
  550. };
  551. MAKE_ENUM_BITFLAGS(gib_type_t);
  552. // monster ai flags
  553. enum monster_ai_flags_t : uint64_t
  554. {
  555. AI_NONE = 0,
  556. AI_STAND_GROUND = bit_v<0>,
  557. AI_TEMP_STAND_GROUND = bit_v<1>,
  558. AI_SOUND_TARGET = bit_v<2>,
  559. AI_LOST_SIGHT = bit_v<3>,
  560. AI_PURSUIT_LAST_SEEN = bit_v<4>,
  561. AI_PURSUE_NEXT = bit_v<5>,
  562. AI_PURSUE_TEMP = bit_v<6>,
  563. AI_HOLD_FRAME = bit_v<7>,
  564. AI_GOOD_GUY = bit_v<8>,
  565. AI_BRUTAL = bit_v<9>,
  566. AI_NOSTEP = bit_v<10>,
  567. AI_DUCKED = bit_v<11>,
  568. AI_COMBAT_POINT = bit_v<12>,
  569. AI_MEDIC = bit_v<13>,
  570. AI_RESURRECTING = bit_v<14>,
  571. // ROGUE
  572. AI_MANUAL_STEERING = bit_v<15>,
  573. AI_TARGET_ANGER = bit_v<16>,
  574. AI_DODGING = bit_v<17>,
  575. AI_CHARGING = bit_v<18>,
  576. AI_HINT_PATH = bit_v<19>,
  577. AI_IGNORE_SHOTS = bit_v<20>,
  578. // PMM - FIXME - last second added for E3 .. there's probably a better way to do this, but
  579. // this works
  580. AI_DO_NOT_COUNT = bit_v<21>, // set for healed monsters
  581. AI_SPAWNED_CARRIER = bit_v<22>, // both do_not_count and spawned are set for spawned monsters
  582. AI_SPAWNED_MEDIC_C = bit_v<23>, // both do_not_count and spawned are set for spawned monsters
  583. AI_SPAWNED_WIDOW = bit_v<24>, // both do_not_count and spawned are set for spawned monsters
  584. AI_BLOCKED = bit_v<25>, // used by blocked_checkattack: set to say I'm attacking while blocked
  585. // (prevents run-attacks)
  586. // ROGUE
  587. AI_SPAWNED_ALIVE = bit_v<26>, // [Paril-KEX] for spawning dead
  588. AI_SPAWNED_DEAD = bit_v<27>,
  589. AI_HIGH_TICK_RATE = bit_v<28>, // not limited by 10hz actions
  590. AI_NO_PATH_FINDING = bit_v<29>, // don't try nav nodes for path finding
  591. AI_PATHING = bit_v<30>, // using nav nodes currently
  592. AI_STINKY = bit_v<31>, // spawn flies
  593. AI_STUNK = bit_v<32>, // already spawned files
  594. AI_ALTERNATE_FLY = bit_v<33>, // use alternate flying mechanics; see monsterinfo.fly_xxx
  595. AI_TEMP_MELEE_COMBAT = bit_v<34>, // temporarily switch to the melee combat style
  596. AI_FORGET_ENEMY = bit_v<35>, // forget the current enemy
  597. AI_DOUBLE_TROUBLE = bit_v<36>, // JORG only
  598. AI_REACHED_HOLD_COMBAT = bit_v<37>,
  599. AI_THIRD_EYE = bit_v<38>
  600. };
  601. MAKE_ENUM_BITFLAGS(monster_ai_flags_t);
  602. constexpr monster_ai_flags_t AI_SPAWNED_MASK =
  603. AI_SPAWNED_CARRIER | AI_SPAWNED_MEDIC_C | AI_SPAWNED_WIDOW; // mask to catch all three flavors of spawned
  604. // monster attack state
  605. enum monster_attack_state_t
  606. {
  607. AS_NONE,
  608. AS_STRAIGHT,
  609. AS_SLIDING,
  610. AS_MELEE,
  611. AS_MISSILE,
  612. AS_BLIND // PMM - used by boss code to do nasty things even if it can't see you
  613. };
  614. // handedness values
  615. enum handedness_t
  616. {
  617. RIGHT_HANDED,
  618. LEFT_HANDED,
  619. CENTER_HANDED
  620. };
  621. enum class auto_switch_t
  622. {
  623. SMART,
  624. ALWAYS,
  625. ALWAYS_NO_AMMO,
  626. NEVER
  627. };
  628. constexpr uint32_t SFL_CROSS_TRIGGER_MASK = (0xffffffffu & ~SPAWNFLAG_EDITOR_MASK.value);
  629. // noise types for PlayerNoise
  630. enum player_noise_t
  631. {
  632. PNOISE_SELF,
  633. PNOISE_WEAPON,
  634. PNOISE_IMPACT
  635. };
  636. struct gitem_armor_t
  637. {
  638. int32_t base_count;
  639. int32_t max_count;
  640. float normal_protection;
  641. float energy_protection;
  642. };
  643. static constexpr gitem_armor_t jacketarmor_info = { 25, 50, .30f, .00f };
  644. static constexpr gitem_armor_t combatarmor_info = { 50, 100, .60f, .30f };
  645. static constexpr gitem_armor_t bodyarmor_info = { 100, 200, .80f, .60f };
  646. // edict->movetype values
  647. enum movetype_t {
  648. MOVETYPE_NONE, // never moves
  649. MOVETYPE_NOCLIP, // origin and angles change with no interaction
  650. MOVETYPE_PUSH, // no clip to world, push on box contact
  651. MOVETYPE_STOP, // no clip to world, stops on box contact
  652. MOVETYPE_WALK, // gravity
  653. MOVETYPE_STEP, // gravity, special edge handling
  654. MOVETYPE_FLY,
  655. MOVETYPE_TOSS, // gravity
  656. MOVETYPE_FLYMISSILE, // extra size to monsters
  657. MOVETYPE_BOUNCE,
  658. // RAFAEL
  659. MOVETYPE_WALLBOUNCE,
  660. // RAFAEL
  661. // ROGUE
  662. MOVETYPE_NEWTOSS // PGM - for deathball
  663. // ROGUE
  664. };
  665. // edict->flags
  666. enum ent_flags_t : uint64_t {
  667. FL_NONE = 0, // no flags
  668. FL_FLY = bit_v<0>,
  669. FL_SWIM = bit_v<1>, // implied immunity to drowning
  670. FL_IMMUNE_LASER = bit_v<2>,
  671. FL_INWATER = bit_v<3>,
  672. FL_GODMODE = bit_v<4>,
  673. FL_NOTARGET = bit_v<5>,
  674. FL_IMMUNE_SLIME = bit_v<6>,
  675. FL_IMMUNE_LAVA = bit_v<7>,
  676. FL_PARTIALGROUND = bit_v<8>, // not all corners are valid
  677. FL_WATERJUMP = bit_v<9>, // player jumping out of water
  678. FL_TEAMSLAVE = bit_v<10>, // not the first on the team
  679. FL_NO_KNOCKBACK = bit_v<11>,
  680. FL_POWER_ARMOR = bit_v<12>, // power armor (if any) is active
  681. // ROGUE
  682. FL_MECHANICAL = bit_v<13>, // entity is mechanical, use sparks not blood
  683. FL_SAM_RAIMI = bit_v<14>, // entity is in sam raimi cam mode
  684. FL_DISGUISED = bit_v<15>, // entity is in disguise, monsters will not recognize.
  685. FL_NOGIB = bit_v<16>, // player has been vaporized by a nuke, drop no gibs
  686. FL_DAMAGEABLE = bit_v<17>,
  687. FL_STATIONARY = bit_v<18>,
  688. // ROGUE
  689. FL_ALIVE_KNOCKBACK_ONLY = bit_v<19>, // only apply knockback if alive or on same frame as death
  690. FL_NO_DAMAGE_EFFECTS = bit_v<20>,
  691. // [Paril-KEX] gets scaled by coop health scaling
  692. FL_COOP_HEALTH_SCALE = bit_v<21>,
  693. FL_FLASHLIGHT = bit_v<22>, // enable flashlight
  694. FL_KILL_VELOCITY = bit_v<23>, // for berserker slam
  695. FL_NOVISIBLE = bit_v<24>, // super invisibility
  696. FL_DODGE = bit_v<25>, // monster should try to dodge this
  697. FL_TEAMMASTER = bit_v<26>, // is a team master (only here so that entities abusing teammaster/teamchain for stuff don't break)
  698. FL_LOCKED = bit_v<27>, // entity is locked for the purposes of navigation
  699. FL_ALWAYS_TOUCH = bit_v<28>, // always touch, even if we normally wouldn't
  700. FL_NO_STANDING = bit_v<29>, // don't allow "standing" on non-brush entities
  701. FL_WANTS_POWER_ARMOR = bit_v<30>, // for players, auto-shield
  702. FL_RESPAWN = bit_v<31>, // used for item respawning
  703. FL_TRAP = bit_v<32>, // entity is a trap of some kind
  704. FL_TRAP_LASER_FIELD = bit_v<33>, // enough of a special case to get it's own flag...
  705. FL_IMMORTAL = bit_v<34> // never go below 1hp
  706. };
  707. MAKE_ENUM_BITFLAGS( ent_flags_t );
  708. // gitem_t->flags
  709. enum item_flags_t : uint32_t
  710. {
  711. IF_NONE = 0,
  712. IF_WEAPON = bit_v<0>, // use makes active weapon
  713. IF_AMMO = bit_v<1>,
  714. IF_ARMOR = bit_v<2>,
  715. IF_STAY_COOP = bit_v<3>,
  716. IF_KEY = bit_v<4>,
  717. IF_POWERUP = bit_v<5>,
  718. // ROGUE
  719. IF_NOT_GIVEABLE = bit_v<6>, // item can not be given
  720. // ROGUE
  721. IF_HEALTH = bit_v<7>,
  722. // ZOID
  723. IF_TECH = bit_v<8>,
  724. IF_NO_HASTE = bit_v<9>,
  725. // ZOID
  726. IF_NO_INFINITE_AMMO = bit_v<10>, // [Paril-KEX] don't allow infinite ammo to affect
  727. IF_POWERUP_WHEEL = bit_v<11>, // [Paril-KEX] item should be in powerup wheel
  728. IF_POWERUP_ONOFF = bit_v<12>, // [Paril-KEX] for wheel; can't store more than one, show on/off state
  729. IF_NOT_RANDOM = bit_v<13>, // [Paril-KEX] item never shows up in randomizations
  730. IF_ANY = 0xFFFFFFFF
  731. };
  732. MAKE_ENUM_BITFLAGS(item_flags_t);
  733. // health edict_t->style
  734. enum
  735. {
  736. HEALTH_IGNORE_MAX = 1,
  737. HEALTH_TIMED = 2
  738. };
  739. // item IDs; must match itemlist order
  740. enum item_id_t : int32_t {
  741. IT_NULL, // must always be zero
  742. IT_ARMOR_BODY,
  743. IT_ARMOR_COMBAT,
  744. IT_ARMOR_JACKET,
  745. IT_ARMOR_SHARD,
  746. IT_ITEM_POWER_SCREEN,
  747. IT_ITEM_POWER_SHIELD,
  748. IT_WEAPON_GRAPPLE,
  749. IT_WEAPON_BLASTER,
  750. IT_WEAPON_CHAINFIST,
  751. IT_WEAPON_SHOTGUN,
  752. IT_WEAPON_SSHOTGUN,
  753. IT_WEAPON_MACHINEGUN,
  754. IT_WEAPON_ETF_RIFLE,
  755. IT_WEAPON_CHAINGUN,
  756. IT_AMMO_GRENADES,
  757. IT_AMMO_TRAP,
  758. IT_AMMO_TESLA,
  759. IT_WEAPON_GLAUNCHER,
  760. IT_WEAPON_PROXLAUNCHER,
  761. IT_WEAPON_RLAUNCHER,
  762. IT_WEAPON_HYPERBLASTER,
  763. IT_WEAPON_IONRIPPER,
  764. IT_WEAPON_PLASMABEAM,
  765. IT_WEAPON_RAILGUN,
  766. IT_WEAPON_PHALANX,
  767. IT_WEAPON_BFG,
  768. IT_WEAPON_DISRUPTOR,
  769. #if 0
  770. IT_WEAPON_DISINTEGRATOR,
  771. #endif
  772. IT_AMMO_SHELLS,
  773. IT_AMMO_BULLETS,
  774. IT_AMMO_CELLS,
  775. IT_AMMO_ROCKETS,
  776. IT_AMMO_SLUGS,
  777. IT_AMMO_MAGSLUG,
  778. IT_AMMO_FLECHETTES,
  779. IT_AMMO_PROX,
  780. IT_AMMO_NUKE,
  781. IT_AMMO_ROUNDS,
  782. IT_ITEM_QUAD,
  783. IT_ITEM_QUADFIRE,
  784. IT_ITEM_INVULNERABILITY,
  785. IT_ITEM_INVISIBILITY,
  786. IT_ITEM_SILENCER,
  787. IT_ITEM_REBREATHER,
  788. IT_ITEM_ENVIROSUIT,
  789. IT_ITEM_ANCIENT_HEAD,
  790. IT_ITEM_LEGACY_HEAD,
  791. IT_ITEM_ADRENALINE,
  792. IT_ITEM_BANDOLIER,
  793. IT_ITEM_PACK,
  794. IT_ITEM_IR_GOGGLES,
  795. IT_ITEM_DOUBLE,
  796. IT_ITEM_SPHERE_VENGEANCE,
  797. IT_ITEM_SPHERE_HUNTER,
  798. IT_ITEM_SPHERE_DEFENDER,
  799. IT_ITEM_DOPPELGANGER,
  800. IT_ITEM_TAG_TOKEN,
  801. IT_KEY_DATA_CD,
  802. IT_KEY_POWER_CUBE,
  803. IT_KEY_EXPLOSIVE_CHARGES,
  804. IT_KEY_YELLOW,
  805. IT_KEY_POWER_CORE,
  806. IT_KEY_PYRAMID,
  807. IT_KEY_DATA_SPINNER,
  808. IT_KEY_PASS,
  809. IT_KEY_BLUE_KEY,
  810. IT_KEY_RED_KEY,
  811. IT_KEY_GREEN_KEY,
  812. IT_KEY_COMMANDER_HEAD,
  813. IT_KEY_AIRSTRIKE,
  814. IT_KEY_NUKE_CONTAINER,
  815. IT_KEY_NUKE,
  816. IT_HEALTH_SMALL,
  817. IT_HEALTH_MEDIUM,
  818. IT_HEALTH_LARGE,
  819. IT_HEALTH_MEGA,
  820. IT_FLAG1,
  821. IT_FLAG2,
  822. IT_TECH_RESISTANCE,
  823. IT_TECH_STRENGTH,
  824. IT_TECH_HASTE,
  825. IT_TECH_REGENERATION,
  826. IT_ITEM_FLASHLIGHT,
  827. IT_ITEM_COMPASS,
  828. IT_TOTAL
  829. };
  830. struct gitem_t
  831. {
  832. item_id_t id; // matches item list index
  833. const char *classname; // spawning name
  834. bool (*pickup)(edict_t *ent, edict_t *other);
  835. void (*use)(edict_t *ent, gitem_t *item);
  836. void (*drop)(edict_t *ent, gitem_t *item);
  837. void (*weaponthink)(edict_t *ent);
  838. const char *pickup_sound;
  839. const char *world_model;
  840. effects_t world_model_flags;
  841. const char *view_model;
  842. // client side info
  843. const char *icon;
  844. const char *use_name; // for use command, english only
  845. const char *pickup_name; // for printing on pickup
  846. const char *pickup_name_definite; // definite article version for languages that need it
  847. int quantity = 0; // for ammo how much, for weapons how much is used per shot
  848. item_id_t ammo = IT_NULL; // for weapons
  849. item_id_t chain = IT_NULL; // weapon chain root
  850. item_flags_t flags = IF_NONE; // IT_* flags
  851. const char *vwep_model = nullptr; // vwep model string (for weapons)
  852. const gitem_armor_t *armor_info = nullptr;
  853. int tag = 0;
  854. const char *precaches = nullptr; // string of all models, sounds, and images this item will use
  855. int32_t sort_id = 0; // used by some items to control their sorting
  856. int32_t quantity_warn = 5; // when to warn on low ammo
  857. // set in InitItems, don't set by hand
  858. // circular list of chained weapons
  859. gitem_t *chain_next = nullptr;
  860. // set in SP_worldspawn, don't set by hand
  861. // model index for vwep
  862. int32_t vwep_index = 0;
  863. // set in SetItemNames, don't set by hand
  864. // offset into CS_WHEEL_AMMO/CS_WHEEL_WEAPONS/CS_WHEEL_POWERUPS
  865. int32_t ammo_wheel_index = -1;
  866. int32_t weapon_wheel_index = -1;
  867. int32_t powerup_wheel_index = -1;
  868. };
  869. // means of death
  870. enum mod_id_t : uint8_t
  871. {
  872. MOD_UNKNOWN,
  873. MOD_BLASTER,
  874. MOD_SHOTGUN,
  875. MOD_SSHOTGUN,
  876. MOD_MACHINEGUN,
  877. MOD_CHAINGUN,
  878. MOD_GRENADE,
  879. MOD_G_SPLASH,
  880. MOD_ROCKET,
  881. MOD_R_SPLASH,
  882. MOD_HYPERBLASTER,
  883. MOD_RAILGUN,
  884. MOD_BFG_LASER,
  885. MOD_BFG_BLAST,
  886. MOD_BFG_EFFECT,
  887. MOD_HANDGRENADE,
  888. MOD_HG_SPLASH,
  889. MOD_WATER,
  890. MOD_SLIME,
  891. MOD_LAVA,
  892. MOD_CRUSH,
  893. MOD_TELEFRAG,
  894. MOD_TELEFRAG_SPAWN,
  895. MOD_FALLING,
  896. MOD_SUICIDE,
  897. MOD_HELD_GRENADE,
  898. MOD_EXPLOSIVE,
  899. MOD_BARREL,
  900. MOD_BOMB,
  901. MOD_EXIT,
  902. MOD_SPLASH,
  903. MOD_TARGET_LASER,
  904. MOD_TRIGGER_HURT,
  905. MOD_HIT,
  906. MOD_TARGET_BLASTER,
  907. // RAFAEL 14-APR-98
  908. MOD_RIPPER,
  909. MOD_PHALANX,
  910. MOD_BRAINTENTACLE,
  911. MOD_BLASTOFF,
  912. MOD_GEKK,
  913. MOD_TRAP,
  914. // END 14-APR-98
  915. //========
  916. // ROGUE
  917. MOD_CHAINFIST,
  918. MOD_DISINTEGRATOR,
  919. MOD_ETF_RIFLE,
  920. MOD_BLASTER2,
  921. MOD_HEATBEAM,
  922. MOD_TESLA,
  923. MOD_PROX,
  924. MOD_NUKE,
  925. MOD_VENGEANCE_SPHERE,
  926. MOD_HUNTER_SPHERE,
  927. MOD_DEFENDER_SPHERE,
  928. MOD_TRACKER,
  929. MOD_DBALL_CRUSH,
  930. MOD_DOPPLE_EXPLODE,
  931. MOD_DOPPLE_VENGEANCE,
  932. MOD_DOPPLE_HUNTER,
  933. // ROGUE
  934. //========
  935. MOD_GRAPPLE,
  936. MOD_BLUEBLASTER
  937. };
  938. struct mod_t
  939. {
  940. mod_id_t id;
  941. bool friendly_fire = false;
  942. bool no_point_loss = false;
  943. mod_t() = default;
  944. constexpr mod_t(mod_id_t id, bool no_point_loss = false) :
  945. id(id),
  946. no_point_loss(no_point_loss)
  947. {
  948. }
  949. };
  950. // the total number of levels we'll track for the
  951. // end of unit screen.
  952. constexpr size_t MAX_LEVELS_PER_UNIT = 8;
  953. struct level_entry_t
  954. {
  955. // bsp name
  956. char map_name[MAX_QPATH];
  957. // map name
  958. char pretty_name[MAX_QPATH];
  959. // these are set when we leave the level
  960. int32_t total_secrets;
  961. int32_t found_secrets;
  962. int32_t total_monsters;
  963. int32_t killed_monsters;
  964. // total time spent in the level, for end screen
  965. gtime_t time;
  966. // the order we visited levels in
  967. int32_t visit_order;
  968. };
  969. //
  970. // this structure is left intact through an entire game
  971. // it should be initialized at dll load time, and read/written to
  972. // the server.ssv file for savegames
  973. //
  974. struct game_locals_t
  975. {
  976. char helpmessage1[MAX_TOKEN_CHARS];
  977. char helpmessage2[MAX_TOKEN_CHARS];
  978. int32_t help1changed, help2changed;
  979. gclient_t *clients; // [maxclients]
  980. // can't store spawnpoint in level, because
  981. // it would get overwritten by the savegame restore
  982. char spawnpoint[MAX_TOKEN_CHARS]; // needed for coop respawns
  983. // store latched cvars here that we want to get at often
  984. uint32_t maxclients;
  985. uint32_t maxentities;
  986. // cross level triggers
  987. uint32_t cross_level_flags, cross_unit_flags;
  988. bool autosaved;
  989. // [Paril-KEX]
  990. int32_t airacceleration_modified, gravity_modified;
  991. std::array<level_entry_t, MAX_LEVELS_PER_UNIT> level_entries;
  992. int32_t max_lag_origins;
  993. vec3_t *lag_origins; // maxclients * max_lag_origins
  994. };
  995. constexpr size_t MAX_HEALTH_BARS = 2;
  996. //
  997. // this structure is cleared as each map is entered
  998. // it is read/written to the level.sav file for savegames
  999. //
  1000. struct level_locals_t
  1001. {
  1002. bool in_frame;
  1003. gtime_t time;
  1004. char level_name[MAX_QPATH]; // the descriptive name (Outer Base, etc)
  1005. char mapname[MAX_QPATH]; // the server name (base1, etc)
  1006. char nextmap[MAX_QPATH]; // go here when fraglimit is hit
  1007. char forcemap[MAX_QPATH]; // go here
  1008. // intermission state
  1009. gtime_t intermissiontime; // time the intermission was started
  1010. const char *changemap;
  1011. const char *achievement;
  1012. bool exitintermission;
  1013. bool intermission_eou;
  1014. bool intermission_clear; // [Paril-KEX] clear inventory on switch
  1015. bool level_intermission_set; // [Paril-KEX] for target_camera switches; don't find intermission point
  1016. bool intermission_fade, intermission_fading; // [Paril-KEX] fade on exit instead of immediately leaving
  1017. gtime_t intermission_fade_time;
  1018. vec3_t intermission_origin;
  1019. vec3_t intermission_angle;
  1020. bool respawn_intermission; // only set once for respawning players
  1021. int32_t pic_health;
  1022. int32_t pic_ping;
  1023. int32_t total_secrets;
  1024. int32_t found_secrets;
  1025. int32_t total_goals;
  1026. int32_t found_goals;
  1027. int32_t total_monsters;
  1028. std::array<edict_t *, MAX_EDICTS> monsters_registered; // only for debug
  1029. int32_t killed_monsters;
  1030. edict_t *current_entity; // entity running from G_RunFrame
  1031. int32_t body_que; // dead bodies
  1032. int32_t power_cubes; // ugly necessity for coop
  1033. // ROGUE
  1034. edict_t *disguise_violator;
  1035. gtime_t disguise_violation_time;
  1036. int32_t disguise_icon; // [Paril-KEX]
  1037. // ROGUE
  1038. int32_t shadow_light_count; // [Sam-KEX]
  1039. bool is_n64;
  1040. gtime_t coop_level_restart_time; // restart the level after this time
  1041. bool instantitems; // instantitems 1 set in worldspawn
  1042. // N64 goal stuff
  1043. const char *goals; // nullptr if no goals in world
  1044. int32_t goal_num; // current relative goal number, increased with each target_goal
  1045. // offset for the first vwep model, for
  1046. // skinnum encoding
  1047. int32_t vwep_offset;
  1048. // coop health scaling factor;
  1049. // this percentage of health is added
  1050. // to the monster's health per player.
  1051. float coop_health_scaling;
  1052. // this isn't saved in the save file, but stores
  1053. // the amount of players currently active in the
  1054. // level, compared against monsters' individual
  1055. // scale #
  1056. int32_t coop_scale_players;
  1057. // [Paril-KEX] current level entry
  1058. level_entry_t *entry;
  1059. // [Paril-KEX] current poi
  1060. bool valid_poi;
  1061. vec3_t current_poi;
  1062. int32_t current_poi_image;
  1063. int32_t current_poi_stage;
  1064. edict_t *current_dynamic_poi;
  1065. vec3_t *poi_points[MAX_SPLIT_PLAYERS]; // temporary storage for POIs in coop
  1066. // start items
  1067. const char *start_items;
  1068. // disable grappling hook
  1069. bool no_grapple;
  1070. // saved gravity
  1071. float gravity;
  1072. // level is a hub map, and shouldn't be included in EOU stuff
  1073. bool hub_map;
  1074. // active health bar entities
  1075. std::array<edict_t *, MAX_HEALTH_BARS> health_bar_entities;
  1076. int32_t intermission_server_frame;
  1077. bool deadly_kill_box;
  1078. bool story_active;
  1079. gtime_t next_auto_save;
  1080. gtime_t next_match_report;
  1081. };
  1082. struct shadow_light_temp_t
  1083. {
  1084. shadow_light_data_t data;
  1085. const char *lightstyletarget = nullptr;
  1086. };
  1087. void G_LoadShadowLights();
  1088. #include <unordered_set>
  1089. // spawn_temp_t is only used to hold entity field values that
  1090. // can be set from the editor, but aren't actualy present
  1091. // in edict_t during gameplay.
  1092. // defaults can/should be set in the struct.
  1093. struct spawn_temp_t
  1094. {
  1095. // world vars
  1096. const char *sky;
  1097. float skyrotate;
  1098. vec3_t skyaxis;
  1099. int32_t skyautorotate = 1;
  1100. const char *nextmap;
  1101. int32_t lip;
  1102. int32_t distance;
  1103. int32_t height;
  1104. const char *noise;
  1105. float pausetime;
  1106. const char *item;
  1107. const char *gravity;
  1108. float minyaw;
  1109. float maxyaw;
  1110. float minpitch;
  1111. float maxpitch;
  1112. shadow_light_temp_t sl; // [Sam-KEX]
  1113. const char* music; // [Edward-KEX]
  1114. int instantitems;
  1115. float radius; // [Paril-KEX]
  1116. bool hub_map; // [Paril-KEX]
  1117. const char *achievement; // [Paril-KEX]
  1118. // [Paril-KEX]
  1119. const char *goals;
  1120. // [Paril-KEX]
  1121. const char *image;
  1122. int fade_start_dist = 96;
  1123. int fade_end_dist = 384;
  1124. const char *start_items;
  1125. int no_grapple = 0;
  1126. float health_multiplier = 1.0f;
  1127. const char *reinforcements; // [Paril-KEX]
  1128. const char *noise_start, *noise_middle, *noise_end; // [Paril-KEX]
  1129. int32_t loop_count; // [Paril-KEX]
  1130. std::unordered_set<const char *> keys_specified;
  1131. inline bool was_key_specified(const char *key) const
  1132. {
  1133. return keys_specified.find(key) != keys_specified.end();
  1134. }
  1135. };
  1136. enum move_state_t
  1137. {
  1138. STATE_TOP,
  1139. STATE_BOTTOM,
  1140. STATE_UP,
  1141. STATE_DOWN
  1142. };
  1143. #define DEFINE_DATA_FUNC(ns_lower, ns_upper, returnType, ...) \
  1144. using save_##ns_lower##_t = save_data_t<returnType(*)(__VA_ARGS__), SAVE_FUNC_##ns_upper>
  1145. #define SAVE_DATA_FUNC(n, ns, returnType, ...) \
  1146. using save_##n##_t = save_data_t<returnType(*)(__VA_ARGS__), SAVE_FUNC_##ns>; \
  1147. extern returnType n(__VA_ARGS__); \
  1148. static const save_data_list_t save__##n(#n, SAVE_FUNC_##ns, reinterpret_cast<const void *>(n)); \
  1149. auto n
  1150. DEFINE_DATA_FUNC(moveinfo_endfunc, MOVEINFO_ENDFUNC, void, edict_t *self);
  1151. #define MOVEINFO_ENDFUNC(n) \
  1152. SAVE_DATA_FUNC(n, MOVEINFO_ENDFUNC, void, edict_t *self)
  1153. DEFINE_DATA_FUNC(moveinfo_blocked, MOVEINFO_BLOCKED, void, edict_t *self, edict_t *other);
  1154. #define MOVEINFO_BLOCKED(n) \
  1155. SAVE_DATA_FUNC(n, MOVEINFO_BLOCKED, void, edict_t *self, edict_t *other)
  1156. // a struct that can store type-safe allocations
  1157. // of a fixed amount of data. it self-destructs when
  1158. // re-assigned. TODO: because edicts are still kind of
  1159. // managed like C memory, the destructor may not be
  1160. // called for a freed entity if this is stored as a member.
  1161. template<typename T, int32_t tag>
  1162. struct savable_allocated_memory_t
  1163. {
  1164. T *ptr;
  1165. size_t count;
  1166. constexpr savable_allocated_memory_t(T *ptr, size_t count) :
  1167. ptr(ptr),
  1168. count(count)
  1169. {
  1170. }
  1171. inline ~savable_allocated_memory_t()
  1172. {
  1173. release();
  1174. }
  1175. // no copy
  1176. constexpr savable_allocated_memory_t(const savable_allocated_memory_t &) = delete;
  1177. constexpr savable_allocated_memory_t &operator=(const savable_allocated_memory_t &) = delete;
  1178. // free move
  1179. constexpr savable_allocated_memory_t(savable_allocated_memory_t &&move)
  1180. {
  1181. ptr = move.ptr;
  1182. count = move.count;
  1183. move.ptr = nullptr;
  1184. move.count = 0;
  1185. }
  1186. constexpr savable_allocated_memory_t &operator=(savable_allocated_memory_t &&move)
  1187. {
  1188. ptr = move.ptr;
  1189. count = move.count;
  1190. move.ptr = nullptr;
  1191. move.count = 0;
  1192. return *this;
  1193. }
  1194. inline void release()
  1195. {
  1196. if (ptr)
  1197. {
  1198. gi.TagFree(ptr);
  1199. count = 0;
  1200. ptr = nullptr;
  1201. }
  1202. }
  1203. constexpr explicit operator T *() { return ptr; }
  1204. constexpr explicit operator const T *() const { return ptr; }
  1205. constexpr std::add_lvalue_reference_t<T> operator[](const size_t index) { return ptr[index]; }
  1206. constexpr const std::add_lvalue_reference_t<T> operator[](const size_t index) const { return ptr[index]; }
  1207. constexpr size_t size() const { return count * sizeof(T); }
  1208. constexpr operator bool() const { return !!ptr; }
  1209. };
  1210. template<typename T, int32_t tag>
  1211. inline savable_allocated_memory_t<T, tag> make_savable_memory(size_t count)
  1212. {
  1213. if (!count)
  1214. return { nullptr, 0 };
  1215. return { reinterpret_cast<T *>(gi.TagMalloc(sizeof(T) * count, tag)), count };
  1216. }
  1217. struct moveinfo_t
  1218. {
  1219. // fixed data
  1220. vec3_t start_origin;
  1221. vec3_t start_angles;
  1222. vec3_t end_origin;
  1223. vec3_t end_angles, end_angles_reversed;
  1224. int32_t sound_start;
  1225. int32_t sound_middle;
  1226. int32_t sound_end;
  1227. float accel;
  1228. float speed;
  1229. float decel;
  1230. float distance;
  1231. float wait;
  1232. // state data
  1233. move_state_t state;
  1234. bool reversing;
  1235. vec3_t dir;
  1236. vec3_t dest;
  1237. float current_speed;
  1238. float move_speed;
  1239. float next_speed;
  1240. float remaining_distance;
  1241. float decel_distance;
  1242. save_moveinfo_endfunc_t endfunc;
  1243. save_moveinfo_blocked_t blocked;
  1244. // [Paril-KEX] new accel state
  1245. vec3_t curve_ref;
  1246. savable_allocated_memory_t<float, TAG_LEVEL> curve_positions;
  1247. size_t curve_frame;
  1248. uint8_t subframe, num_subframes;
  1249. size_t num_frames_done;
  1250. };
  1251. struct mframe_t
  1252. {
  1253. void (*aifunc)(edict_t *self, float dist) = nullptr;
  1254. float dist = 0;
  1255. void (*thinkfunc)(edict_t *self) = nullptr;
  1256. int32_t lerp_frame = -1;
  1257. };
  1258. // this check only works on windows, and is only
  1259. // of importance to developers anyways
  1260. #if defined(_WIN32) && defined(_MSC_VER)
  1261. #if _MSC_VER >= 1934
  1262. #define COMPILE_TIME_MOVE_CHECK
  1263. #endif
  1264. #endif
  1265. struct mmove_t
  1266. {
  1267. int32_t firstframe;
  1268. int32_t lastframe;
  1269. const mframe_t *frame;
  1270. void (*endfunc)(edict_t *self);
  1271. float sidestep_scale;
  1272. #ifdef COMPILE_TIME_MOVE_CHECK
  1273. template<size_t N>
  1274. constexpr mmove_t(int32_t firstframe, int32_t lastframe, const mframe_t (&frames)[N], void (*endfunc)(edict_t *self) = nullptr, float sidestep_scale = 0.0f) :
  1275. firstframe(firstframe),
  1276. lastframe(lastframe),
  1277. frame(frames),
  1278. endfunc(endfunc),
  1279. sidestep_scale(sidestep_scale)
  1280. {
  1281. if ((lastframe - firstframe + 1) != N)
  1282. throw std::exception("bad animation frames; check your numbers!");
  1283. }
  1284. #endif
  1285. };
  1286. using save_mmove_t = save_data_t<mmove_t, SAVE_DATA_MMOVE>;
  1287. #ifdef COMPILE_TIME_MOVE_CHECK
  1288. #define MMOVE_T(n) \
  1289. extern const mmove_t n; \
  1290. static const save_data_list_t save__##n(#n, SAVE_DATA_MMOVE, &n); \
  1291. constexpr mmove_t n
  1292. #else
  1293. #define MMOVE_T(n) \
  1294. extern const mmove_t n; \
  1295. static const save_data_list_t save__##n(#n, SAVE_DATA_MMOVE, &n); \
  1296. const mmove_t n
  1297. #endif
  1298. DEFINE_DATA_FUNC(monsterinfo_stand, MONSTERINFO_STAND, void, edict_t *self);
  1299. #define MONSTERINFO_STAND(n) \
  1300. SAVE_DATA_FUNC(n, MONSTERINFO_STAND, void, edict_t *self)
  1301. DEFINE_DATA_FUNC(monsterinfo_idle, MONSTERINFO_IDLE, void, edict_t *self);
  1302. #define MONSTERINFO_IDLE(n) \
  1303. SAVE_DATA_FUNC(n, MONSTERINFO_IDLE, void, edict_t *self)
  1304. DEFINE_DATA_FUNC(monsterinfo_search, MONSTERINFO_SEARCH, void, edict_t *self);
  1305. #define MONSTERINFO_SEARCH(n) \
  1306. SAVE_DATA_FUNC(n, MONSTERINFO_SEARCH, void, edict_t *self)
  1307. DEFINE_DATA_FUNC(monsterinfo_walk, MONSTERINFO_WALK, void, edict_t *self);
  1308. #define MONSTERINFO_WALK(n) \
  1309. SAVE_DATA_FUNC(n, MONSTERINFO_WALK, void, edict_t *self)
  1310. DEFINE_DATA_FUNC(monsterinfo_run, MONSTERINFO_RUN, void, edict_t *self);
  1311. #define MONSTERINFO_RUN(n) \
  1312. SAVE_DATA_FUNC(n, MONSTERINFO_RUN, void, edict_t *self)
  1313. DEFINE_DATA_FUNC(monsterinfo_dodge, MONSTERINFO_DODGE, void, edict_t *self, edict_t *attacker, gtime_t eta, trace_t *tr, bool gravity);
  1314. #define MONSTERINFO_DODGE(n) \
  1315. SAVE_DATA_FUNC(n, MONSTERINFO_DODGE, void, edict_t *self, edict_t *attacker, gtime_t eta, trace_t *tr, bool gravity)
  1316. DEFINE_DATA_FUNC(monsterinfo_attack, MONSTERINFO_ATTACK, void, edict_t *self);
  1317. #define MONSTERINFO_ATTACK(n) \
  1318. SAVE_DATA_FUNC(n, MONSTERINFO_ATTACK, void, edict_t *self)
  1319. DEFINE_DATA_FUNC(monsterinfo_melee, MONSTERINFO_MELEE, void, edict_t *self);
  1320. #define MONSTERINFO_MELEE(n) \
  1321. SAVE_DATA_FUNC(n, MONSTERINFO_MELEE, void, edict_t *self)
  1322. DEFINE_DATA_FUNC(monsterinfo_sight, MONSTERINFO_SIGHT, void, edict_t *self, edict_t *other);
  1323. #define MONSTERINFO_SIGHT(n) \
  1324. SAVE_DATA_FUNC(n, MONSTERINFO_SIGHT, void, edict_t *self, edict_t *other)
  1325. DEFINE_DATA_FUNC(monsterinfo_checkattack, MONSTERINFO_CHECKATTACK, bool, edict_t *self);
  1326. #define MONSTERINFO_CHECKATTACK(n) \
  1327. SAVE_DATA_FUNC(n, MONSTERINFO_CHECKATTACK, bool, edict_t *self)
  1328. DEFINE_DATA_FUNC(monsterinfo_setskin, MONSTERINFO_SETSKIN, void, edict_t *self);
  1329. #define MONSTERINFO_SETSKIN(n) \
  1330. SAVE_DATA_FUNC(n, MONSTERINFO_SETSKIN, void, edict_t *self)
  1331. DEFINE_DATA_FUNC(monsterinfo_blocked, MONSTERINFO_BLOCKED, bool, edict_t *self, float dist);
  1332. #define MONSTERINFO_BLOCKED(n) \
  1333. SAVE_DATA_FUNC(n, MONSTERINFO_BLOCKED, bool, edict_t *self, float dist)
  1334. DEFINE_DATA_FUNC(monsterinfo_physicschange, MONSTERINFO_PHYSCHANGED, void, edict_t *self);
  1335. #define MONSTERINFO_PHYSCHANGED(n) \
  1336. SAVE_DATA_FUNC(n, MONSTERINFO_PHYSCHANGED, void, edict_t *self)
  1337. DEFINE_DATA_FUNC(monsterinfo_duck, MONSTERINFO_DUCK, bool, edict_t *self, gtime_t eta);
  1338. #define MONSTERINFO_DUCK(n) \
  1339. SAVE_DATA_FUNC(n, MONSTERINFO_DUCK, bool, edict_t *self, gtime_t eta)
  1340. DEFINE_DATA_FUNC(monsterinfo_unduck, MONSTERINFO_UNDUCK, void, edict_t *self);
  1341. #define MONSTERINFO_UNDUCK(n) \
  1342. SAVE_DATA_FUNC(n, MONSTERINFO_UNDUCK, void, edict_t *self)
  1343. DEFINE_DATA_FUNC(monsterinfo_sidestep, MONSTERINFO_SIDESTEP, bool, edict_t *self);
  1344. #define MONSTERINFO_SIDESTEP(n) \
  1345. SAVE_DATA_FUNC(n, MONSTERINFO_SIDESTEP, bool, edict_t *self)
  1346. // combat styles, for navigation
  1347. enum combat_style_t
  1348. {
  1349. COMBAT_UNKNOWN, // automatically choose based on attack functions
  1350. COMBAT_MELEE, // should attempt to get up close for melee
  1351. COMBAT_MIXED, // has mixed melee/ranged; runs to get up close if far enough away
  1352. COMBAT_RANGED // don't bother pathing if we can see the player
  1353. };
  1354. struct reinforcement_t
  1355. {
  1356. const char *classname;
  1357. int32_t strength;
  1358. vec3_t mins, maxs;
  1359. };
  1360. struct reinforcement_list_t
  1361. {
  1362. reinforcement_t *reinforcements;
  1363. uint32_t num_reinforcements;
  1364. };
  1365. constexpr size_t MAX_REINFORCEMENTS = 5; // max number of spawns we can do at once.
  1366. constexpr gtime_t HOLD_FOREVER = gtime_t::from_ms(std::numeric_limits<int64_t>::max());
  1367. struct monsterinfo_t
  1368. {
  1369. // [Paril-KEX] allow some moves to be done instantaneously, but
  1370. // others can wait the full frame.
  1371. // NB: always use `M_SetAnimation` as it handles edge cases.
  1372. save_mmove_t active_move, next_move;
  1373. monster_ai_flags_t aiflags; // PGM - unsigned, since we're close to the max
  1374. int32_t nextframe; // if next_move is set, this is ignored until a frame is ran
  1375. float scale;
  1376. save_monsterinfo_stand_t stand;
  1377. save_monsterinfo_idle_t idle;
  1378. save_monsterinfo_search_t search;
  1379. save_monsterinfo_walk_t walk;
  1380. save_monsterinfo_run_t run;
  1381. save_monsterinfo_dodge_t dodge;
  1382. save_monsterinfo_attack_t attack;
  1383. save_monsterinfo_melee_t melee;
  1384. save_monsterinfo_sight_t sight;
  1385. save_monsterinfo_checkattack_t checkattack;
  1386. save_monsterinfo_setskin_t setskin;
  1387. save_monsterinfo_physicschange_t physics_change;
  1388. gtime_t pausetime;
  1389. gtime_t attack_finished;
  1390. gtime_t fire_wait;
  1391. vec3_t saved_goal;
  1392. gtime_t search_time;
  1393. gtime_t trail_time;
  1394. vec3_t last_sighting;
  1395. monster_attack_state_t attack_state;
  1396. bool lefty;
  1397. gtime_t idle_time;
  1398. int32_t linkcount;
  1399. item_id_t power_armor_type;
  1400. int32_t power_armor_power;
  1401. // for monster revive
  1402. item_id_t initial_power_armor_type;
  1403. int32_t max_power_armor_power;
  1404. int32_t weapon_sound, engine_sound;
  1405. // ROGUE
  1406. save_monsterinfo_blocked_t blocked;
  1407. gtime_t last_hint_time; // last time the monster checked for hintpaths.
  1408. edict_t *goal_hint; // which hint_path we're trying to get to
  1409. int32_t medicTries;
  1410. edict_t *badMedic1, *badMedic2; // these medics have declared this monster "unhealable"
  1411. edict_t *healer; // this is who is healing this monster
  1412. save_monsterinfo_duck_t duck;
  1413. save_monsterinfo_unduck_t unduck;
  1414. save_monsterinfo_sidestep_t sidestep;
  1415. float base_height;
  1416. gtime_t next_duck_time;
  1417. gtime_t duck_wait_time;
  1418. edict_t *last_player_enemy;
  1419. // blindfire stuff .. the boolean says whether the monster will do it, and blind_fire_time is the timing
  1420. // (set in the monster) of the next shot
  1421. bool blindfire; // will the monster blindfire?
  1422. bool can_jump; // will the monster jump?
  1423. bool had_visibility; // Paril: used for blindfire
  1424. float drop_height, jump_height;
  1425. gtime_t blind_fire_delay;
  1426. vec3_t blind_fire_target;
  1427. // used by the spawners to not spawn too much and keep track of #s of monsters spawned
  1428. int32_t monster_slots; // nb: for spawned monsters, this is how many slots we took from our commander
  1429. int32_t monster_used;
  1430. edict_t *commander;
  1431. // powerup timers, used by widow, our friend
  1432. gtime_t quad_time;
  1433. gtime_t invincible_time;
  1434. gtime_t double_time;
  1435. // ROGUE
  1436. // Paril
  1437. gtime_t surprise_time;
  1438. item_id_t armor_type;
  1439. int32_t armor_power;
  1440. bool close_sight_tripped;
  1441. gtime_t melee_debounce_time; // don't melee until this time has passed
  1442. gtime_t strafe_check_time; // time until we should reconsider strafing
  1443. int32_t base_health; // health that we had on spawn, before any co-op adjustments
  1444. int32_t health_scaling; // number of players we've been scaled up to
  1445. gtime_t next_move_time; // high tick rate
  1446. gtime_t bad_move_time; // don't try straight moves until this is over
  1447. gtime_t bump_time; // don't slide against walls for a bit
  1448. gtime_t random_change_time; // high tickrate
  1449. gtime_t path_blocked_counter; // break out of paths when > a certain time
  1450. gtime_t path_wait_time; // don't try nav nodes until this is over
  1451. PathInfo nav_path; // if AI_PATHING, this is where we are trying to reach
  1452. gtime_t nav_path_cache_time; // cache nav_path result for this much time
  1453. combat_style_t combat_style; // pathing style
  1454. edict_t *damage_attacker;
  1455. edict_t *damage_inflictor;
  1456. int32_t damage_blood, damage_knockback;
  1457. vec3_t damage_from;
  1458. mod_t damage_mod;
  1459. // alternate flying mechanics
  1460. float fly_max_distance, fly_min_distance; // how far we should try to stay
  1461. float fly_acceleration; // accel/decel speed
  1462. float fly_speed; // max speed from flying
  1463. vec3_t fly_ideal_position; // ideally where we want to end up to hover, relative to our target if not pinned
  1464. gtime_t fly_position_time; // if <= level.time, we can try changing positions
  1465. bool fly_buzzard, fly_above; // orbit around all sides of their enemy, not just the sides
  1466. bool fly_pinned; // whether we're currently pinned to ideal position (made absolute)
  1467. bool fly_thrusters; // slightly different flight mechanics, for melee attacks
  1468. gtime_t fly_recovery_time; // time to try a new dir to get away from hazards
  1469. vec3_t fly_recovery_dir;
  1470. gtime_t checkattack_time;
  1471. int32_t start_frame;
  1472. gtime_t dodge_time;
  1473. int32_t move_block_counter;
  1474. gtime_t move_block_change_time;
  1475. gtime_t react_to_damage_time;
  1476. reinforcement_list_t reinforcements;
  1477. std::array<uint8_t, MAX_REINFORCEMENTS> chosen_reinforcements; // readied for spawn; 255 is value for none
  1478. gtime_t jump_time;
  1479. // NOTE: if adding new elements, make sure to add them
  1480. // in g_save.cpp too!
  1481. };
  1482. // non-monsterinfo save stuff
  1483. using save_prethink_t = save_data_t<void(*)(edict_t *self), SAVE_FUNC_PRETHINK>;
  1484. #define PRETHINK(n) \
  1485. void n(edict_t *self); \
  1486. static const save_data_list_t save__##n(#n, SAVE_FUNC_PRETHINK, reinterpret_cast<const void *>(n)); \
  1487. auto n
  1488. using save_think_t = save_data_t<void(*)(edict_t *self), SAVE_FUNC_THINK>;
  1489. #define THINK(n) \
  1490. void n(edict_t *self); \
  1491. static const save_data_list_t save__##n(#n, SAVE_FUNC_THINK, reinterpret_cast<const void *>(n)); \
  1492. auto n
  1493. using save_touch_t = save_data_t<void(*)(edict_t *self, edict_t *other, const trace_t &tr, bool other_touching_self), SAVE_FUNC_TOUCH>;
  1494. #define TOUCH(n) \
  1495. void n(edict_t *self, edict_t *other, const trace_t &tr, bool other_touching_self); \
  1496. static const save_data_list_t save__##n(#n, SAVE_FUNC_TOUCH, reinterpret_cast<const void *>(n)); \
  1497. auto n
  1498. using save_use_t = save_data_t<void(*)(edict_t *self, edict_t *other, edict_t *activator), SAVE_FUNC_USE>;
  1499. #define USE(n) \
  1500. void n(edict_t *self, edict_t *other, edict_t *activator); \
  1501. static const save_data_list_t save__##n(#n, SAVE_FUNC_USE, reinterpret_cast<const void *>(n)); \
  1502. auto n
  1503. using save_pain_t = save_data_t<void(*)(edict_t *self, edict_t *other, float kick, int damage, const mod_t &mod), SAVE_FUNC_PAIN>;
  1504. #define PAIN(n) \
  1505. void n(edict_t *self, edict_t *other, float kick, int damage, const mod_t &mod); \
  1506. static const save_data_list_t save__##n(#n, SAVE_FUNC_PAIN, reinterpret_cast<const void *>(n)); \
  1507. auto n
  1508. using save_die_t = save_data_t<void(*)(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, const vec3_t &point, const mod_t &mod), SAVE_FUNC_DIE>;
  1509. #define DIE(n) \
  1510. void n(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, const vec3_t &point, const mod_t &mod); \
  1511. static const save_data_list_t save__##n(#n, SAVE_FUNC_DIE, reinterpret_cast<const void *>(n)); \
  1512. auto n
  1513. // ROGUE
  1514. // this determines how long to wait after a duck to duck again.
  1515. // if we finish a duck-up, this gets cut in half.
  1516. constexpr gtime_t DUCK_INTERVAL = 5000_ms;
  1517. // ROGUE
  1518. extern game_locals_t game;
  1519. extern level_locals_t level;
  1520. extern game_export_t globals;
  1521. extern spawn_temp_t st;
  1522. extern edict_t *g_edicts;
  1523. #include <random>
  1524. extern std::mt19937 mt_rand;
  1525. // uniform float [0, 1)
  1526. [[nodiscard]] inline float frandom()
  1527. {
  1528. return std::uniform_real_distribution<float>()(mt_rand);
  1529. }
  1530. // uniform float [min_inclusive, max_exclusive)
  1531. [[nodiscard]] inline float frandom(float min_inclusive, float max_exclusive)
  1532. {
  1533. return std::uniform_real_distribution<float>(min_inclusive, max_exclusive)(mt_rand);
  1534. }
  1535. // uniform float [0, max_exclusive)
  1536. [[nodiscard]] inline float frandom(float max_exclusive)
  1537. {
  1538. return std::uniform_real_distribution<float>(0, max_exclusive)(mt_rand);
  1539. }
  1540. // uniform time [min_inclusive, max_exclusive)
  1541. [[nodiscard]] inline gtime_t random_time(gtime_t min_inclusive, gtime_t max_exclusive)
  1542. {
  1543. return gtime_t::from_ms(std::uniform_int_distribution<int64_t>(min_inclusive.milliseconds(), max_exclusive.milliseconds())(mt_rand));
  1544. }
  1545. // uniform time [0, max_exclusive)
  1546. [[nodiscard]] inline gtime_t random_time(gtime_t max_exclusive)
  1547. {
  1548. return gtime_t::from_ms(std::uniform_int_distribution<int64_t>(0, max_exclusive.milliseconds())(mt_rand));
  1549. }
  1550. // uniform float [-1, 1)
  1551. // note: closed on min but not max
  1552. // to match vanilla behavior
  1553. [[nodiscard]] inline float crandom()
  1554. {
  1555. return std::uniform_real_distribution<float>(-1.f, 1.f)(mt_rand);
  1556. }
  1557. // uniform float (-1, 1)
  1558. [[nodiscard]] inline float crandom_open()
  1559. {
  1560. return std::uniform_real_distribution<float>(std::nextafterf(-1.f, 0.f), 1.f)(mt_rand);
  1561. }
  1562. // raw unsigned int32 value from random
  1563. [[nodiscard]] inline uint32_t irandom()
  1564. {
  1565. return mt_rand();
  1566. }
  1567. // uniform int [min, max)
  1568. // always returns min if min == (max - 1)
  1569. // undefined behavior if min > (max - 1)
  1570. [[nodiscard]] inline int32_t irandom(int32_t min_inclusive, int32_t max_exclusive)
  1571. {
  1572. if (min_inclusive == max_exclusive - 1)
  1573. return min_inclusive;
  1574. return std::uniform_int_distribution<int32_t>(min_inclusive, max_exclusive - 1)(mt_rand);
  1575. }
  1576. // uniform int [0, max)
  1577. // always returns 0 if max <= 0
  1578. // note for Q2 code:
  1579. // - to fix rand()%x, do irandom(x)
  1580. // - to fix rand()&x, do irandom(x + 1)
  1581. [[nodiscard]] inline int32_t irandom(int32_t max_exclusive)
  1582. {
  1583. if (max_exclusive <= 0)
  1584. return 0;
  1585. return irandom(0, max_exclusive);
  1586. }
  1587. // uniform random index from given container
  1588. template<typename T>
  1589. [[nodiscard]] inline int32_t random_index(const T &container)
  1590. {
  1591. return irandom(std::size(container));
  1592. }
  1593. // uniform random element from given container
  1594. template<typename T>
  1595. [[nodiscard]] inline auto random_element(T &container) -> decltype(*std::begin(container))
  1596. {
  1597. return *(std::begin(container) + random_index(container));
  1598. }
  1599. // flip a coin
  1600. [[nodiscard]]inline bool brandom()
  1601. {
  1602. return irandom(2) == 0;
  1603. }
  1604. extern cvar_t *deathmatch;
  1605. extern cvar_t *coop;
  1606. extern cvar_t *skill;
  1607. extern cvar_t *fraglimit;
  1608. extern cvar_t *timelimit;
  1609. // ZOID
  1610. extern cvar_t *capturelimit;
  1611. extern cvar_t *g_quick_weapon_switch;
  1612. extern cvar_t *g_instant_weapon_switch;
  1613. // ZOID
  1614. extern cvar_t *password;
  1615. extern cvar_t *spectator_password;
  1616. extern cvar_t *needpass;
  1617. extern cvar_t *g_select_empty;
  1618. extern cvar_t *sv_dedicated;
  1619. extern cvar_t *filterban;
  1620. extern cvar_t *sv_gravity;
  1621. extern cvar_t *sv_maxvelocity;
  1622. extern cvar_t *gun_x, *gun_y, *gun_z;
  1623. extern cvar_t *sv_rollspeed;
  1624. extern cvar_t *sv_rollangle;
  1625. extern cvar_t *run_pitch;
  1626. extern cvar_t *run_roll;
  1627. extern cvar_t *bob_up;
  1628. extern cvar_t *bob_pitch;
  1629. extern cvar_t *bob_roll;
  1630. extern cvar_t *sv_cheats;
  1631. extern cvar_t *g_debug_monster_paths;
  1632. extern cvar_t *g_debug_monster_kills;
  1633. extern cvar_t *maxspectators;
  1634. extern cvar_t *bot_debug_follow_actor;
  1635. extern cvar_t *bot_debug_move_to_point;
  1636. extern cvar_t *flood_msgs;
  1637. extern cvar_t *flood_persecond;
  1638. extern cvar_t *flood_waitdelay;
  1639. extern cvar_t *sv_maplist;
  1640. extern cvar_t *g_skipViewModifiers;
  1641. extern cvar_t *sv_stopspeed; // PGM - this was a define in g_phys.c
  1642. extern cvar_t *g_strict_saves;
  1643. extern cvar_t *g_coop_health_scaling;
  1644. extern cvar_t *g_weapon_respawn_time;
  1645. extern cvar_t* g_no_health;
  1646. extern cvar_t* g_no_items;
  1647. extern cvar_t* g_dm_weapons_stay;
  1648. extern cvar_t* g_dm_no_fall_damage;
  1649. extern cvar_t* g_dm_instant_items;
  1650. extern cvar_t* g_dm_same_level;
  1651. extern cvar_t* g_friendly_fire;
  1652. extern cvar_t* g_dm_force_respawn;
  1653. extern cvar_t* g_dm_force_respawn_time;
  1654. extern cvar_t* g_dm_spawn_farthest;
  1655. extern cvar_t* g_no_armor;
  1656. extern cvar_t* g_dm_allow_exit;
  1657. extern cvar_t* g_infinite_ammo;
  1658. extern cvar_t* g_dm_no_quad_drop;
  1659. extern cvar_t* g_dm_no_quadfire_drop;
  1660. extern cvar_t* g_no_mines;
  1661. extern cvar_t* g_dm_no_stack_double;
  1662. extern cvar_t* g_no_nukes;
  1663. extern cvar_t* g_no_spheres;
  1664. extern cvar_t* g_teamplay_armor_protect;
  1665. extern cvar_t* g_allow_techs;
  1666. extern cvar_t* g_start_items;
  1667. extern cvar_t* g_map_list;
  1668. extern cvar_t* g_map_list_shuffle;
  1669. extern cvar_t *g_lag_compensation;
  1670. // ROGUE
  1671. extern cvar_t *gamerules;
  1672. extern cvar_t *huntercam;
  1673. extern cvar_t *g_dm_strong_mines;
  1674. extern cvar_t *g_dm_random_items;
  1675. // ROGUE
  1676. // [Kex]
  1677. extern cvar_t* g_instagib;
  1678. extern cvar_t* g_coop_player_collision;
  1679. extern cvar_t* g_coop_squad_respawn;
  1680. extern cvar_t* g_coop_enable_lives;
  1681. extern cvar_t* g_coop_num_lives;
  1682. extern cvar_t* g_coop_instanced_items;
  1683. extern cvar_t* g_allow_grapple;
  1684. extern cvar_t* g_grapple_fly_speed;
  1685. extern cvar_t* g_grapple_pull_speed;
  1686. extern cvar_t* g_grapple_damage;
  1687. extern cvar_t *sv_airaccelerate;
  1688. extern cvar_t *g_damage_scale;
  1689. extern cvar_t *g_disable_player_collision;
  1690. extern cvar_t *ai_damage_scale;
  1691. extern cvar_t *ai_model_scale;
  1692. extern cvar_t *ai_allow_dm_spawn;
  1693. extern cvar_t *ai_movement_disabled;
  1694. #define world (&g_edicts[0])
  1695. uint32_t GetUnicastKey();
  1696. // item spawnflags
  1697. constexpr spawnflags_t SPAWNFLAG_ITEM_TRIGGER_SPAWN = 0x00000001_spawnflag;
  1698. constexpr spawnflags_t SPAWNFLAG_ITEM_NO_TOUCH = 0x00000002_spawnflag;
  1699. constexpr spawnflags_t SPAWNFLAG_ITEM_TOSS_SPAWN = 0x00000004_spawnflag;
  1700. constexpr spawnflags_t SPAWNFLAG_ITEM_MAX = 0x00000008_spawnflag;
  1701. // 8 bits reserved for editor flags & power cube bits
  1702. // (see SPAWNFLAG_NOT_EASY above)
  1703. constexpr spawnflags_t SPAWNFLAG_ITEM_DROPPED = 0x00010000_spawnflag;
  1704. constexpr spawnflags_t SPAWNFLAG_ITEM_DROPPED_PLAYER = 0x00020000_spawnflag;
  1705. constexpr spawnflags_t SPAWNFLAG_ITEM_TARGETS_USED = 0x00040000_spawnflag;
  1706. extern gitem_t itemlist[IT_TOTAL];
  1707. //
  1708. // g_cmds.c
  1709. //
  1710. bool CheckFlood(edict_t *ent);
  1711. void Cmd_Help_f(edict_t *ent);
  1712. void Cmd_Score_f(edict_t *ent);
  1713. //
  1714. // g_items.c
  1715. //
  1716. void PrecacheItem(gitem_t *it);
  1717. void InitItems();
  1718. void SetItemNames();
  1719. gitem_t *FindItem(const char *pickup_name);
  1720. gitem_t *FindItemByClassname(const char *classname);
  1721. edict_t *Drop_Item(edict_t *ent, gitem_t *item);
  1722. void SetRespawn(edict_t *ent, gtime_t delay, bool hide_self = true);
  1723. void ChangeWeapon(edict_t *ent);
  1724. void SpawnItem(edict_t *ent, gitem_t *item);
  1725. void Think_Weapon(edict_t *ent);
  1726. item_id_t ArmorIndex(edict_t *ent);
  1727. item_id_t PowerArmorType(edict_t *ent);
  1728. gitem_t *GetItemByIndex(item_id_t index);
  1729. gitem_t *GetItemByAmmo(ammo_t ammo);
  1730. gitem_t *GetItemByPowerup(powerup_t powerup);
  1731. bool Add_Ammo(edict_t *ent, gitem_t *item, int count);
  1732. void G_CheckPowerArmor(edict_t *ent);
  1733. void Touch_Item(edict_t *ent, edict_t *other, const trace_t &tr, bool other_touching_self);
  1734. void droptofloor(edict_t *ent);
  1735. void P_ToggleFlashlight(edict_t *ent, bool state);
  1736. bool Entity_IsVisibleToPlayer(edict_t* ent, edict_t* player);
  1737. void Compass_Update(edict_t *ent, bool first);
  1738. //
  1739. // g_utils.c
  1740. //
  1741. bool KillBox(edict_t *ent, bool from_spawning, mod_id_t mod = MOD_TELEFRAG, bool bsp_clipping = true);
  1742. edict_t *G_Find(edict_t *from, std::function<bool(edict_t *e)> matcher);
  1743. // utility template for getting the type of a field
  1744. template<typename>
  1745. struct member_object_type { };
  1746. template<typename T1, typename T2>
  1747. struct member_object_type<T1 T2::*> { using type = T1; };
  1748. template<typename T>
  1749. using member_object_type_t = typename member_object_type<std::remove_cv_t<T>>::type;
  1750. template<auto M>
  1751. edict_t *G_FindByString(edict_t *from, const std::string_view &value)
  1752. {
  1753. static_assert(std::is_same_v<member_object_type_t<decltype(M)>, const char *>, "can only use string member functions");
  1754. return G_Find(from, [&](edict_t *e) {
  1755. return e->*M && strlen(e->*M) == value.length() && !Q_strncasecmp(e->*M, value.data(), value.length());
  1756. });
  1757. }
  1758. edict_t *findradius(edict_t *from, const vec3_t &org, float rad);
  1759. edict_t *G_PickTarget(const char *targetname);
  1760. void G_UseTargets(edict_t *ent, edict_t *activator);
  1761. void G_PrintActivationMessage(edict_t *ent, edict_t *activator, bool coop_global);
  1762. void G_SetMovedir(vec3_t &angles, vec3_t &movedir);
  1763. void G_InitEdict(edict_t *e);
  1764. edict_t *G_Spawn();
  1765. void G_FreeEdict(edict_t *e);
  1766. void G_TouchTriggers(edict_t *ent);
  1767. void G_TouchProjectiles(edict_t *ent, vec3_t previous_origin);
  1768. char *G_CopyString(const char *in, int32_t tag);
  1769. char *G_CopyString(const char *in, size_t len, int32_t tag);
  1770. // ROGUE
  1771. edict_t *findradius2(edict_t *from, const vec3_t &org, float rad);
  1772. // ROGUE
  1773. void G_PlayerNotifyGoal(edict_t *player);
  1774. //
  1775. // g_spawn.c
  1776. //
  1777. void ED_CallSpawn(edict_t *ent);
  1778. char *ED_NewString(char *string);
  1779. //
  1780. // g_target.c
  1781. //
  1782. void target_laser_think(edict_t *self);
  1783. void target_laser_off(edict_t *self);
  1784. constexpr spawnflags_t SPAWNFLAG_LASER_ON = 0x0001_spawnflag;
  1785. constexpr spawnflags_t SPAWNFLAG_LASER_RED = 0x0002_spawnflag;
  1786. constexpr spawnflags_t SPAWNFLAG_LASER_GREEN = 0x0004_spawnflag;
  1787. constexpr spawnflags_t SPAWNFLAG_LASER_BLUE = 0x0008_spawnflag;
  1788. constexpr spawnflags_t SPAWNFLAG_LASER_YELLOW = 0x0010_spawnflag;
  1789. constexpr spawnflags_t SPAWNFLAG_LASER_ORANGE = 0x0020_spawnflag;
  1790. constexpr spawnflags_t SPAWNFLAG_LASER_FAT = 0x0040_spawnflag;
  1791. constexpr spawnflags_t SPAWNFLAG_LASER_ZAP = 0x80000000_spawnflag;
  1792. constexpr spawnflags_t SPAWNFLAG_LASER_LIGHTNING = 0x10000_spawnflag;
  1793. constexpr spawnflags_t SPAWNFLAG_HEALTHBAR_PVS_ONLY = 1_spawnflag;
  1794. // damage flags
  1795. enum damageflags_t
  1796. {
  1797. DAMAGE_NONE = 0, // no damage flags
  1798. DAMAGE_RADIUS = 0x00000001, // damage was indirect
  1799. DAMAGE_NO_ARMOR = 0x00000002, // armour does not protect from this damage
  1800. DAMAGE_ENERGY = 0x00000004, // damage is from an energy based weapon
  1801. DAMAGE_NO_KNOCKBACK = 0x00000008, // do not affect velocity, just view angles
  1802. DAMAGE_BULLET = 0x00000010, // damage is from a bullet (used for ricochets)
  1803. DAMAGE_NO_PROTECTION = 0x00000020, // armor, shields, invulnerability, and godmode have no effect
  1804. // ROGUE
  1805. DAMAGE_DESTROY_ARMOR = 0x00000040, // damage is done to armor and health.
  1806. DAMAGE_NO_REG_ARMOR = 0x00000080, // damage skips regular armor
  1807. DAMAGE_NO_POWER_ARMOR = 0x00000100,// damage skips power armor
  1808. // ROGUE
  1809. DAMAGE_NO_INDICATOR = 0x00000200 // for clients: no damage indicators
  1810. };
  1811. MAKE_ENUM_BITFLAGS(damageflags_t);
  1812. //
  1813. // g_combat.c
  1814. //
  1815. bool OnSameTeam(edict_t *ent1, edict_t *ent2);
  1816. bool CanDamage(edict_t *targ, edict_t *inflictor);
  1817. bool CheckTeamDamage(edict_t *targ, edict_t *attacker);
  1818. void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, const vec3_t &dir, const vec3_t &point,
  1819. const vec3_t &normal, int damage, int knockback, damageflags_t dflags, mod_t mod);
  1820. void T_RadiusDamage(edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, damageflags_t dflags, mod_t mod);
  1821. void Killed(edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, const vec3_t &point, mod_t mod);
  1822. // ROGUE
  1823. void T_RadiusNukeDamage(edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, mod_t mod);
  1824. void T_RadiusClassDamage(edict_t *inflictor, edict_t *attacker, float damage, char *ignoreClass, float radius,
  1825. mod_t mod);
  1826. void cleanupHealTarget(edict_t *ent);
  1827. // ROGUE
  1828. constexpr int32_t DEFAULT_BULLET_HSPREAD = 300;
  1829. constexpr int32_t DEFAULT_BULLET_VSPREAD = 500;
  1830. constexpr int32_t DEFAULT_SHOTGUN_HSPREAD = 1000;
  1831. constexpr int32_t DEFAULT_SHOTGUN_VSPREAD = 500;
  1832. constexpr int32_t DEFAULT_DEATHMATCH_SHOTGUN_COUNT = 12;
  1833. constexpr int32_t DEFAULT_SHOTGUN_COUNT = 12;
  1834. constexpr int32_t DEFAULT_SSHOTGUN_COUNT = 20;
  1835. //
  1836. // g_func.c
  1837. //
  1838. void train_use(edict_t *self, edict_t *other, edict_t *activator);
  1839. void func_train_find(edict_t *self);
  1840. edict_t *plat_spawn_inside_trigger(edict_t *ent);
  1841. void Move_Calc(edict_t *ent, const vec3_t &dest, void(*endfunc)(edict_t *self));
  1842. void G_SetMoveinfoSounds(edict_t *self, const char *default_start, const char *default_mid, const char *default_end);
  1843. constexpr spawnflags_t SPAWNFLAG_TRAIN_START_ON = 1_spawnflag;
  1844. constexpr spawnflags_t SPAWNFLAG_WATER_SMART = 2_spawnflag;
  1845. constexpr spawnflags_t SPAWNFLAG_TRAIN_MOVE_TEAMCHAIN = 8_spawnflag;
  1846. constexpr spawnflags_t SPAWNFLAG_DOOR_REVERSE = 2_spawnflag;
  1847. //
  1848. // g_monster.c
  1849. //
  1850. void monster_muzzleflash(edict_t *self, const vec3_t &start, monster_muzzleflash_id_t id);
  1851. void monster_fire_bullet(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int kick, int hspread,
  1852. int vspread, monster_muzzleflash_id_t flashtype);
  1853. void monster_fire_shotgun(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int kick, int hspread,
  1854. int vspread, int count, monster_muzzleflash_id_t flashtype);
  1855. void monster_fire_blaster(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed,
  1856. monster_muzzleflash_id_t flashtype, effects_t effect);
  1857. void monster_fire_flechette(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed,
  1858. monster_muzzleflash_id_t flashtype);
  1859. void monster_fire_grenade(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed,
  1860. monster_muzzleflash_id_t flashtype, float right_adjust, float up_adjust);
  1861. void monster_fire_rocket(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed,
  1862. monster_muzzleflash_id_t flashtype);
  1863. void monster_fire_railgun(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int kick,
  1864. monster_muzzleflash_id_t flashtype);
  1865. void monster_fire_bfg(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed, int kick,
  1866. float damage_radius, monster_muzzleflash_id_t flashtype);
  1867. bool M_CheckClearShot(edict_t *self, const vec3_t &offset);
  1868. bool M_CheckClearShot(edict_t *self, const vec3_t &offset, vec3_t &start);
  1869. vec3_t M_ProjectFlashSource(edict_t *self, const vec3_t &offset, const vec3_t &forward, const vec3_t &right);
  1870. bool M_droptofloor_generic(vec3_t &origin, const vec3_t &mins, const vec3_t &maxs, bool ceiling, edict_t *ignore, contents_t mask, bool allow_partial);
  1871. bool M_droptofloor(edict_t *ent);
  1872. void monster_think(edict_t *self);
  1873. void monster_dead_think(edict_t *self);
  1874. void monster_dead(edict_t *self);
  1875. void walkmonster_start(edict_t *self);
  1876. void swimmonster_start(edict_t *self);
  1877. void flymonster_start(edict_t *self);
  1878. void monster_death_use(edict_t *self);
  1879. void M_CatagorizePosition(edict_t *self, const vec3_t &in_point, water_level_t &waterlevel, contents_t &watertype);
  1880. void M_WorldEffects(edict_t *ent);
  1881. bool M_CheckAttack(edict_t *self);
  1882. void M_CheckGround(edict_t *ent, contents_t mask);
  1883. void monster_use(edict_t *self, edict_t *other, edict_t *activator);
  1884. void M_ProcessPain(edict_t *e);
  1885. bool M_ShouldReactToPain(edict_t *self, const mod_t &mod);
  1886. void M_SetAnimation(edict_t *self, const save_mmove_t &move, bool instant = true);
  1887. bool M_AllowSpawn( edict_t * self );
  1888. // Paril: used in N64. causes them to be mad at the player
  1889. // regardless of circumstance.
  1890. constexpr size_t HACKFLAG_ATTACK_PLAYER = 1;
  1891. // used in N64, appears to change their behavior for the end scene.
  1892. constexpr size_t HACKFLAG_END_CUTSCENE = 4;
  1893. bool monster_start(edict_t *self);
  1894. void monster_start_go(edict_t *self);
  1895. // RAFAEL
  1896. void monster_fire_ionripper(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed,
  1897. monster_muzzleflash_id_t flashtype, effects_t effect);
  1898. void monster_fire_heat(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed,
  1899. monster_muzzleflash_id_t flashtype, float lerp_factor);
  1900. void monster_fire_dabeam(edict_t *self, int damage, bool secondary, void(*update_func)(edict_t *self));
  1901. void dabeam_update(edict_t *self, bool damage);
  1902. void monster_fire_blueblaster(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed,
  1903. monster_muzzleflash_id_t flashtype, effects_t effect);
  1904. void G_Monster_CheckCoopHealthScaling();
  1905. // RAFAEL
  1906. // ROGUE
  1907. void monster_fire_blaster2(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed,
  1908. monster_muzzleflash_id_t flashtype, effects_t effect);
  1909. void monster_fire_tracker(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed, edict_t *enemy,
  1910. monster_muzzleflash_id_t flashtype);
  1911. void monster_fire_heatbeam(edict_t *self, const vec3_t &start, const vec3_t &dir, const vec3_t &offset, int damage,
  1912. int kick, monster_muzzleflash_id_t flashtype);
  1913. void stationarymonster_start(edict_t *self);
  1914. void monster_done_dodge(edict_t *self);
  1915. // ROGUE
  1916. stuck_result_t G_FixStuckObject(edict_t *self, vec3_t check);
  1917. // this is for the count of monsters
  1918. int32_t M_SlotsLeft(edict_t *self);
  1919. // shared with monsters
  1920. constexpr spawnflags_t SPAWNFLAG_MONSTER_AMBUSH = 1_spawnflag;
  1921. constexpr spawnflags_t SPAWNFLAG_MONSTER_TRIGGER_SPAWN = 2_spawnflag;
  1922. constexpr spawnflags_t SPAWNFLAG_MONSTER_DEAD = 16_spawnflag_bit;
  1923. constexpr spawnflags_t SPAWNFLAG_MONSTER_SUPER_STEP = 17_spawnflag_bit;
  1924. constexpr spawnflags_t SPAWNFLAG_MONSTER_NO_DROP = 18_spawnflag_bit;
  1925. constexpr spawnflags_t SPAWNFLAG_MONSTER_SCENIC = 19_spawnflag_bit;
  1926. // fixbot spawnflags
  1927. constexpr spawnflags_t SPAWNFLAG_FIXBOT_FIXIT = 4_spawnflag;
  1928. constexpr spawnflags_t SPAWNFLAG_FIXBOT_TAKEOFF = 8_spawnflag;
  1929. constexpr spawnflags_t SPAWNFLAG_FIXBOT_LANDING = 16_spawnflag;
  1930. constexpr spawnflags_t SPAWNFLAG_FIXBOT_WORKING = 32_spawnflag;
  1931. //
  1932. // g_misc.c
  1933. //
  1934. void ThrowClientHead(edict_t *self, int damage);
  1935. void gib_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, const vec3_t &point, const mod_t &mod);
  1936. edict_t *ThrowGib(edict_t *self, const char *gibname, int damage, gib_type_t type, float scale);
  1937. void BecomeExplosion1(edict_t *self);
  1938. void misc_viper_use(edict_t *self, edict_t *other, edict_t *activator);
  1939. void misc_strogg_ship_use(edict_t *self, edict_t *other, edict_t *activator);
  1940. void VelocityForDamage(int damage, vec3_t &v);
  1941. void ClipGibVelocity(edict_t *ent);
  1942. constexpr spawnflags_t SPAWNFLAG_PATH_CORNER_TELEPORT = 1_spawnflag;
  1943. constexpr spawnflags_t SPAWNFLAG_POINT_COMBAT_HOLD = 1_spawnflag;
  1944. // max chars for a clock string;
  1945. // " 0:00:00" is the longest string possible
  1946. // plus null terminator.
  1947. constexpr size_t CLOCK_MESSAGE_SIZE = 9;
  1948. //
  1949. // g_ai.c
  1950. //
  1951. edict_t *AI_GetSightClient(edict_t *self);
  1952. void ai_stand(edict_t *self, float dist);
  1953. void ai_move(edict_t *self, float dist);
  1954. void ai_walk(edict_t *self, float dist);
  1955. void ai_turn(edict_t *self, float dist);
  1956. void ai_run(edict_t *self, float dist);
  1957. void ai_charge(edict_t *self, float dist);
  1958. constexpr float RANGE_MELEE = 20; // bboxes basically touching
  1959. constexpr float RANGE_NEAR = 440;
  1960. constexpr float RANGE_MID = 940;
  1961. // [Paril-KEX] adjusted to return an actual distance, measured
  1962. // in a way that is consistent regardless of what is fighting what
  1963. float range_to(edict_t *self, edict_t *other);
  1964. void FoundTarget(edict_t *self);
  1965. void HuntTarget(edict_t *self, bool animate_state = true);
  1966. bool infront(edict_t *self, edict_t *other);
  1967. bool visible(edict_t *self, edict_t *other, bool through_glass = true);
  1968. bool FacingIdeal(edict_t *self);
  1969. // [Paril-KEX] generic function
  1970. bool M_CheckAttack_Base(edict_t *self, float stand_ground_chance, float melee_chance, float near_chance, float mid_chance, float far_chance, float strafe_scalar);
  1971. //
  1972. // g_weapon.c
  1973. //
  1974. bool fire_hit(edict_t *self, vec3_t aim, int damage, int kick);
  1975. void fire_bullet(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int kick, int hspread,
  1976. int vspread, mod_t mod);
  1977. void fire_shotgun(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int kick, int hspread,
  1978. int vspread, int count, mod_t mod);
  1979. void blaster_touch(edict_t *self, edict_t *other, const trace_t &tr, bool other_touching_self);
  1980. void fire_blaster(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed, effects_t effect,
  1981. mod_t mod);
  1982. void Grenade_Explode(edict_t *ent);
  1983. void fire_grenade(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed, gtime_t timer,
  1984. float damage_radius, float right_adjust, float up_adjust, bool monster);
  1985. void fire_grenade2(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed, gtime_t timer,
  1986. float damage_radius, bool held);
  1987. void rocket_touch(edict_t *ent, edict_t *other, const trace_t &tr, bool other_touching_self);
  1988. edict_t *fire_rocket(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed, float damage_radius,
  1989. int radius_damage);
  1990. void fire_rail(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int kick);
  1991. void fire_bfg(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed, float damage_radius);
  1992. // RAFAEL
  1993. void fire_ionripper(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed, effects_t effect);
  1994. void fire_heat(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed, float damage_radius,
  1995. int radius_damage, float turn_fraction);
  1996. void fire_blueblaster(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed,
  1997. effects_t effect);
  1998. void fire_plasma(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed, float damage_radius,
  1999. int radius_damage);
  2000. void fire_trap(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int speed);
  2001. // RAFAEL
  2002. void fire_disintegrator(edict_t *self, const vec3_t &start, const vec3_t &dir, int speed);
  2003. vec3_t P_CurrentKickAngles(edict_t *ent);
  2004. vec3_t P_CurrentKickOrigin(edict_t *ent);
  2005. void P_AddWeaponKick(edict_t *ent, const vec3_t &origin, const vec3_t &angles);
  2006. // we won't ever pierce more than this many entities for a single trace.
  2007. constexpr size_t MAX_PIERCE = 16;
  2008. // base class for pierce args; this stores
  2009. // the stuff we are piercing.
  2010. struct pierce_args_t
  2011. {
  2012. // stuff we pierced
  2013. std::array<edict_t *, MAX_PIERCE> pierced;
  2014. std::array<solid_t, MAX_PIERCE> pierce_solidities;
  2015. size_t num_pierced = 0;
  2016. // the last trace that was done, when piercing stopped
  2017. trace_t tr;
  2018. // mark entity as pierced
  2019. inline bool mark(edict_t *ent);
  2020. // restore entities' previous solidities
  2021. inline void restore();
  2022. // we hit an entity; return false to stop the piercing.
  2023. // you can adjust the mask for the re-trace (for water, etc).
  2024. virtual bool hit(contents_t &mask, vec3_t &end) = 0;
  2025. virtual ~pierce_args_t()
  2026. {
  2027. restore();
  2028. }
  2029. };
  2030. void pierce_trace(const vec3_t &start, const vec3_t &end, edict_t *ignore, pierce_args_t &pierce, contents_t mask);
  2031. //
  2032. // g_ptrail.c
  2033. //
  2034. void PlayerTrail_Add(edict_t *player);
  2035. void PlayerTrail_Destroy(edict_t *player);
  2036. edict_t *PlayerTrail_Pick(edict_t *self, bool next);
  2037. //
  2038. // g_client.c
  2039. //
  2040. constexpr spawnflags_t SPAWNFLAG_CHANGELEVEL_CLEAR_INVENTORY = 8_spawnflag;
  2041. constexpr spawnflags_t SPAWNFLAG_CHANGELEVEL_NO_END_OF_UNIT = 16_spawnflag;
  2042. constexpr spawnflags_t SPAWNFLAG_CHANGELEVEL_FADE_OUT = 32_spawnflag;
  2043. constexpr spawnflags_t SPAWNFLAG_CHANGELEVEL_IMMEDIATE_LEAVE = 64_spawnflag;
  2044. void respawn(edict_t *ent);
  2045. void BeginIntermission(edict_t *targ);
  2046. void PutClientInServer(edict_t *ent);
  2047. void InitClientPersistant(edict_t *ent, gclient_t *client);
  2048. void InitClientResp(gclient_t *client);
  2049. void InitBodyQue();
  2050. void ClientBeginServerFrame(edict_t *ent);
  2051. void ClientUserinfoChanged(edict_t *ent, const char *userinfo);
  2052. void P_AssignClientSkinnum(edict_t *ent);
  2053. void P_ForceFogTransition(edict_t *ent, bool instant);
  2054. void P_SendLevelPOI(edict_t *ent);
  2055. unsigned int P_GetLobbyUserNum( const edict_t * player );
  2056. void G_UpdateLevelEntry();
  2057. void G_EndOfUnitMessage();
  2058. bool SelectSpawnPoint(edict_t *ent, vec3_t &origin, vec3_t &angles, bool force_spawn, bool &landmark);
  2059. struct select_spawn_result_t
  2060. {
  2061. edict_t *spot;
  2062. bool any_valid = false; // set if a spawn point was found, even if it was taken
  2063. };
  2064. select_spawn_result_t SelectDeathmatchSpawnPoint(bool farthest, bool force_spawn, bool fallback_to_ctf_or_start);
  2065. void G_PostRespawn(edict_t *self);
  2066. //
  2067. // g_player.c
  2068. //
  2069. void player_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, const vec3_t &point, const mod_t &mod);
  2070. //
  2071. // g_svcmds.c
  2072. //
  2073. void ServerCommand();
  2074. bool SV_FilterPacket(const char *from);
  2075. //
  2076. // p_view.c
  2077. //
  2078. void ClientEndServerFrame(edict_t *ent);
  2079. void G_LagCompensate(edict_t *from_player, const vec3_t &start, const vec3_t &dir);
  2080. void G_UnLagCompensate();
  2081. //
  2082. // p_hud.c
  2083. //
  2084. void MoveClientToIntermission(edict_t *client);
  2085. void G_SetStats(edict_t *ent);
  2086. void G_SetCoopStats(edict_t *ent);
  2087. void G_SetSpectatorStats(edict_t *ent);
  2088. void G_CheckChaseStats(edict_t *ent);
  2089. void ValidateSelectedItem(edict_t *ent);
  2090. void DeathmatchScoreboardMessage(edict_t *client, edict_t *killer);
  2091. void G_ReportMatchDetails(bool is_end);
  2092. //
  2093. // p_weapon.c
  2094. //
  2095. void PlayerNoise(edict_t *who, const vec3_t &where, player_noise_t type);
  2096. void P_ProjectSource(edict_t *ent, const vec3_t &angles, vec3_t distance, vec3_t &result_start, vec3_t &result_dir);
  2097. void NoAmmoWeaponChange(edict_t *ent, bool sound);
  2098. void G_RemoveAmmo(edict_t *ent);
  2099. void G_RemoveAmmo(edict_t *ent, int32_t quantity);
  2100. void Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST,
  2101. int FRAME_DEACTIVATE_LAST, const int *pause_frames, const int *fire_frames,
  2102. void (*fire)(edict_t *ent));
  2103. void Weapon_Repeating(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST,
  2104. int FRAME_DEACTIVATE_LAST, const int *pause_frames, void (*fire)(edict_t *ent));
  2105. void Throw_Generic(edict_t *ent, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_PRIME_SOUND,
  2106. const char *prime_sound, int FRAME_THROW_HOLD, int FRAME_THROW_FIRE, const int *pause_frames,
  2107. int EXPLODE, const char *primed_sound, void (*fire)(edict_t *ent, bool held), bool extra_idle_frame);
  2108. byte P_DamageModifier(edict_t *ent);
  2109. bool G_CheckInfiniteAmmo(gitem_t *item);
  2110. void Weapon_PowerupSound(edict_t *ent);
  2111. constexpr gtime_t GRENADE_TIMER = 3_sec;
  2112. constexpr float GRENADE_MINSPEED = 400.f;
  2113. constexpr float GRENADE_MAXSPEED = 800.f;
  2114. extern bool is_quad;
  2115. // RAFAEL
  2116. extern bool is_quadfire;
  2117. // RAFAEL
  2118. extern player_muzzle_t is_silenced;
  2119. // ROGUE
  2120. extern byte damage_multiplier;
  2121. // ROGUE
  2122. //
  2123. // m_move.c
  2124. //
  2125. bool M_CheckBottom_Fast_Generic(const vec3_t &absmins, const vec3_t &absmaxs, bool ceiling);
  2126. bool M_CheckBottom_Slow_Generic(const vec3_t &origin, const vec3_t &absmins, const vec3_t &absmaxs, edict_t *ignore, contents_t mask, bool ceiling, bool allow_any_step_height);
  2127. bool M_CheckBottom(edict_t *ent);
  2128. bool SV_CloseEnough(edict_t *ent, edict_t *goal, float dist);
  2129. bool M_walkmove(edict_t *ent, float yaw, float dist);
  2130. void M_MoveToGoal(edict_t *ent, float dist);
  2131. void M_ChangeYaw(edict_t *ent);
  2132. bool ai_check_move(edict_t *self, float dist);
  2133. //
  2134. // g_phys.c
  2135. //
  2136. constexpr float sv_friction = 6;
  2137. constexpr float sv_waterfriction = 1;
  2138. void G_RunEntity(edict_t *ent);
  2139. bool SV_RunThink(edict_t *ent);
  2140. void SV_AddRotationalFriction(edict_t *ent);
  2141. void SV_AddGravity(edict_t *ent);
  2142. void SV_CheckVelocity(edict_t *ent);
  2143. void SV_FlyMove(edict_t *ent, float time, contents_t mask);
  2144. contents_t G_GetClipMask(edict_t *ent);
  2145. void G_Impact(edict_t *e1, const trace_t &trace);
  2146. //
  2147. // g_main.c
  2148. //
  2149. void SaveClientData();
  2150. void FetchClientEntData(edict_t *ent);
  2151. void EndDMLevel();
  2152. //
  2153. // g_chase.c
  2154. //
  2155. void UpdateChaseCam(edict_t *ent);
  2156. void ChaseNext(edict_t *ent);
  2157. void ChasePrev(edict_t *ent);
  2158. void GetChaseTarget(edict_t *ent);
  2159. //====================
  2160. // ROGUE PROTOTYPES
  2161. //
  2162. // g_newweap.c
  2163. //
  2164. void fire_flechette(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed, int kick);
  2165. void fire_prox(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed);
  2166. void fire_nuke(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int speed);
  2167. bool fire_player_melee(edict_t *self, const vec3_t &start, const vec3_t &aim, int reach, int damage, int kick, mod_t mod);
  2168. void fire_tesla(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed);
  2169. void fire_blaster2(edict_t *self, const vec3_t &start, const vec3_t &aimdir, int damage, int speed, effects_t effect,
  2170. bool hyper);
  2171. void fire_heatbeam(edict_t *self, const vec3_t &start, const vec3_t &aimdir, const vec3_t &offset, int damage, int kick,
  2172. bool monster);
  2173. void fire_tracker(edict_t *self, const vec3_t &start, const vec3_t &dir, int damage, int speed, edict_t *enemy);
  2174. //
  2175. // g_newai.c
  2176. //
  2177. bool blocked_checkplat(edict_t *self, float dist);
  2178. enum class blocked_jump_result_t
  2179. {
  2180. NO_JUMP,
  2181. JUMP_TURN,
  2182. JUMP_JUMP_UP,
  2183. JUMP_JUMP_DOWN
  2184. };
  2185. blocked_jump_result_t blocked_checkjump(edict_t *self, float dist);
  2186. bool monsterlost_checkhint(edict_t *self);
  2187. bool inback(edict_t *self, edict_t *other);
  2188. float realrange(edict_t *self, edict_t *other);
  2189. edict_t *SpawnBadArea(const vec3_t &mins, const vec3_t &maxs, gtime_t lifespan, edict_t *owner);
  2190. edict_t *CheckForBadArea(edict_t *ent);
  2191. bool MarkTeslaArea(edict_t *self, edict_t *tesla);
  2192. void InitHintPaths();
  2193. void PredictAim(edict_t *self, edict_t *target, const vec3_t &start, float bolt_speed, bool eye_height, float offset, vec3_t *aimdir,
  2194. vec3_t *aimpoint);
  2195. bool M_CalculatePitchToFire(edict_t *self, const vec3_t &target, const vec3_t &start, vec3_t &aim, float speed, float time_remaining, bool mortar, bool destroy_on_touch = false);
  2196. bool below(edict_t *self, edict_t *other);
  2197. void drawbbox(edict_t *self);
  2198. void M_MonsterDodge(edict_t *self, edict_t *attacker, gtime_t eta, trace_t *tr, bool gravity);
  2199. void monster_duck_down(edict_t *self);
  2200. void monster_duck_hold(edict_t *self);
  2201. void monster_duck_up(edict_t *self);
  2202. bool has_valid_enemy(edict_t *self);
  2203. void TargetTesla(edict_t *self, edict_t *tesla);
  2204. void hintpath_stop(edict_t *self);
  2205. edict_t *PickCoopTarget(edict_t *self);
  2206. int CountPlayers();
  2207. bool monster_jump_finished(edict_t *self);
  2208. void BossExplode(edict_t *self);
  2209. // g_rogue_func
  2210. void plat2_spawn_danger_area(edict_t *ent);
  2211. void plat2_kill_danger_area(edict_t *ent);
  2212. // g_rogue_spawn
  2213. edict_t *CreateMonster(const vec3_t &origin, const vec3_t &angles, const char *classname);
  2214. edict_t *CreateFlyMonster(const vec3_t &origin, const vec3_t &angles, const vec3_t &mins, const vec3_t &maxs,
  2215. const char *classname);
  2216. edict_t *CreateGroundMonster(const vec3_t &origin, const vec3_t &angles, const vec3_t &mins, const vec3_t &maxs,
  2217. const char *classname, float height);
  2218. bool FindSpawnPoint(const vec3_t &startpoint, const vec3_t &mins, const vec3_t &maxs, vec3_t &spawnpoint,
  2219. float maxMoveUp, bool drop = true);
  2220. bool CheckSpawnPoint(const vec3_t &origin, const vec3_t &mins, const vec3_t &maxs);
  2221. bool CheckGroundSpawnPoint(const vec3_t &origin, const vec3_t &entMins, const vec3_t &entMaxs, float height,
  2222. float gravity);
  2223. void SpawnGrow_Spawn(const vec3_t &startpos, float start_size, float end_size);
  2224. void Widowlegs_Spawn(const vec3_t &startpos, const vec3_t &angles);
  2225. // g_rogue_items
  2226. bool Pickup_Nuke(edict_t *ent, edict_t *other);
  2227. void Use_IR(edict_t *ent, gitem_t *item);
  2228. void Use_Double(edict_t *ent, gitem_t *item);
  2229. void Use_Nuke(edict_t *ent, gitem_t *item);
  2230. void Use_Doppleganger(edict_t *ent, gitem_t *item);
  2231. bool Pickup_Doppleganger(edict_t *ent, edict_t *other);
  2232. bool Pickup_Sphere(edict_t *ent, edict_t *other);
  2233. void Use_Defender(edict_t *ent, gitem_t *item);
  2234. void Use_Hunter(edict_t *ent, gitem_t *item);
  2235. void Use_Vengeance(edict_t *ent, gitem_t *item);
  2236. void Item_TriggeredSpawn(edict_t *self, edict_t *other, edict_t *activator);
  2237. void SetTriggeredSpawn(edict_t *ent);
  2238. //
  2239. // g_sphere.c
  2240. //
  2241. void Defender_Launch(edict_t *self);
  2242. void Vengeance_Launch(edict_t *self);
  2243. void Hunter_Launch(edict_t *self);
  2244. //
  2245. // g_newdm.c
  2246. //
  2247. void InitGameRules();
  2248. item_id_t DoRandomRespawn(edict_t *ent);
  2249. void PrecacheForRandomRespawn();
  2250. bool Tag_PickupToken(edict_t *ent, edict_t *other);
  2251. void Tag_DropToken(edict_t *ent, gitem_t *item);
  2252. void fire_doppleganger(edict_t *ent, const vec3_t &start, const vec3_t &aimdir);
  2253. //
  2254. // p_client.c
  2255. //
  2256. void RemoveAttackingPainDaemons(edict_t *self);
  2257. bool G_ShouldPlayersCollide(bool weaponry);
  2258. bool P_UseCoopInstancedItems();
  2259. constexpr spawnflags_t SPAWNFLAG_LANDMARK_KEEP_Z = 1_spawnflag;
  2260. // [Paril-KEX] convenience functions that returns true
  2261. // if the powerup should be 'active' (false to disable,
  2262. // will flash at 500ms intervals after 3 sec)
  2263. [[nodiscard]] constexpr bool G_PowerUpExpiringRelative(gtime_t left)
  2264. {
  2265. return left.milliseconds() > 3000 || (left.milliseconds() % 1000) < 500;
  2266. }
  2267. [[nodiscard]] constexpr bool G_PowerUpExpiring(gtime_t time)
  2268. {
  2269. return G_PowerUpExpiringRelative(time - level.time);
  2270. }
  2271. // ZOID
  2272. #include "ctf/g_ctf.h"
  2273. #include "ctf/p_ctf_menu.h"
  2274. // ZOID
  2275. //============================================================================
  2276. // client_t->anim_priority
  2277. enum anim_priority_t
  2278. {
  2279. ANIM_BASIC, // stand / run
  2280. ANIM_WAVE,
  2281. ANIM_JUMP,
  2282. ANIM_PAIN,
  2283. ANIM_ATTACK,
  2284. ANIM_DEATH,
  2285. // flags
  2286. ANIM_REVERSED = bit_v<8>
  2287. };
  2288. MAKE_ENUM_BITFLAGS(anim_priority_t);
  2289. // height fog data values
  2290. struct height_fog_t
  2291. {
  2292. // r g b dist
  2293. std::array<float, 4> start;
  2294. std::array<float, 4> end;
  2295. float falloff;
  2296. float density;
  2297. inline bool operator==(const height_fog_t &o) const
  2298. {
  2299. return start == o.start && end == o.end && falloff == o.falloff && density == o.density;
  2300. }
  2301. };
  2302. constexpr gtime_t SELECTED_ITEM_TIME = 3_sec;
  2303. enum bmodel_animstyle_t : int32_t
  2304. {
  2305. BMODEL_ANIM_FORWARDS,
  2306. BMODEL_ANIM_BACKWARDS,
  2307. BMODEL_ANIM_RANDOM
  2308. };
  2309. struct bmodel_anim_t
  2310. {
  2311. // range, inclusive
  2312. int32_t start, end;
  2313. bmodel_animstyle_t style;
  2314. int32_t speed; // in milliseconds
  2315. bool nowrap;
  2316. int32_t alt_start, alt_end;
  2317. bmodel_animstyle_t alt_style;
  2318. int32_t alt_speed; // in milliseconds
  2319. bool alt_nowrap;
  2320. // game-only
  2321. bool enabled;
  2322. bool alternate, currently_alternate;
  2323. gtime_t next_tick;
  2324. };
  2325. // never turn back shield on automatically; this is
  2326. // the legacy behavior.
  2327. constexpr int32_t AUTO_SHIELD_MANUAL = -1;
  2328. // when it is >= 0, the shield will turn back on
  2329. // when we have that many cells in our inventory
  2330. // if possible.
  2331. constexpr int32_t AUTO_SHIELD_AUTO = 0;
  2332. // client data that stays across multiple level loads
  2333. struct client_persistant_t
  2334. {
  2335. char userinfo[MAX_INFO_STRING];
  2336. char social_id[MAX_INFO_VALUE];
  2337. char netname[MAX_NETNAME];
  2338. handedness_t hand;
  2339. auto_switch_t autoswitch;
  2340. int32_t autoshield; // see AUTO_SHIELD_*
  2341. bool connected, spawned; // a loadgame will leave valid entities that
  2342. // just don't have a connection yet
  2343. // values saved and restored from edicts when changing levels
  2344. int32_t health;
  2345. int32_t max_health;
  2346. ent_flags_t savedFlags;
  2347. item_id_t selected_item;
  2348. gtime_t selected_item_time;
  2349. std::array<int32_t, IT_TOTAL> inventory;
  2350. // ammo capacities
  2351. std::array<int16_t, AMMO_MAX> max_ammo;
  2352. gitem_t *weapon;
  2353. gitem_t *lastweapon;
  2354. int32_t power_cubes; // used for tracking the cubes in coop games
  2355. int32_t score; // for calculating total unit score in coop games
  2356. int32_t game_help1changed, game_help2changed;
  2357. int32_t helpchanged; // flash F1 icon if non 0, play sound
  2358. // and increment only if 1, 2, or 3
  2359. gtime_t help_time;
  2360. bool spectator; // client wants to be a spectator
  2361. bool bob_skip; // [Paril-KEX] client wants no movement bob
  2362. // [Paril-KEX] fog that we want to achieve; density rgb skyfogfactor
  2363. std::array<float, 5> wanted_fog;
  2364. height_fog_t wanted_heightfog;
  2365. // relative time value, copied from last touched trigger
  2366. gtime_t fog_transition_time;
  2367. gtime_t megahealth_time; // relative megahealth time value
  2368. int32_t lives; // player lives left (1 = no respawns remaining)
  2369. uint8_t n64_crouch_warn_times;
  2370. gtime_t n64_crouch_warning;
  2371. };
  2372. // client data that stays across deathmatch respawns
  2373. struct client_respawn_t
  2374. {
  2375. client_persistant_t coop_respawn; // what to set client->pers to on a respawn
  2376. gtime_t entertime; // level.time the client entered the game
  2377. int32_t score; // frags, etc
  2378. vec3_t cmd_angles; // angles sent over in the last command
  2379. bool spectator; // client is a spectator
  2380. // ZOID
  2381. ctfteam_t ctf_team; // CTF team
  2382. int32_t ctf_state;
  2383. gtime_t ctf_lasthurtcarrier;
  2384. gtime_t ctf_lastreturnedflag;
  2385. gtime_t ctf_flagsince;
  2386. gtime_t ctf_lastfraggedcarrier;
  2387. bool id_state;
  2388. gtime_t lastidtime;
  2389. bool voted; // for elections
  2390. bool ready;
  2391. bool admin;
  2392. ghost_t *ghost; // for ghost codes
  2393. // ZOID
  2394. };
  2395. // [Paril-KEX] seconds until we are fully invisible after
  2396. // making a racket
  2397. constexpr gtime_t INVISIBILITY_TIME = 2_sec;
  2398. // max number of individual damage indicators we'll track
  2399. constexpr size_t MAX_DAMAGE_INDICATORS = 4;
  2400. struct damage_indicator_t
  2401. {
  2402. vec3_t from;
  2403. int32_t health, armor, power;
  2404. };
  2405. // time between ladder sounds
  2406. constexpr gtime_t LADDER_SOUND_TIME = 300_ms;
  2407. // time after damage that we can't respawn on a player for
  2408. constexpr gtime_t COOP_DAMAGE_RESPAWN_TIME = 2000_ms;
  2409. // time after firing that we can't respawn on a player for
  2410. constexpr gtime_t COOP_DAMAGE_FIRING_TIME = 2500_ms;
  2411. // this structure is cleared on each PutClientInServer(),
  2412. // except for 'client->pers'
  2413. struct gclient_t
  2414. {
  2415. // shared with server; do not touch members until the "private" section
  2416. player_state_t ps; // communicated by server to clients
  2417. int32_t ping;
  2418. // private to game
  2419. client_persistant_t pers;
  2420. client_respawn_t resp;
  2421. pmove_state_t old_pmove; // for detecting out-of-pmove changes
  2422. bool showscores; // set layout stat
  2423. bool showeou; // end of unit screen
  2424. bool showinventory; // set layout stat
  2425. bool showhelp;
  2426. button_t buttons;
  2427. button_t oldbuttons;
  2428. button_t latched_buttons;
  2429. usercmd_t cmd; // last CMD send
  2430. // weapon cannot fire until this time is up
  2431. gtime_t weapon_fire_finished;
  2432. // time between processing individual animation frames
  2433. gtime_t weapon_think_time;
  2434. // if we latched fire between server frames but before
  2435. // the weapon fire finish has elapsed, we'll "press" it
  2436. // automatically when we have a chance
  2437. bool weapon_fire_buffered;
  2438. bool weapon_thunk;
  2439. gitem_t *newweapon;
  2440. // sum up damage over an entire frame, so
  2441. // shotgun blasts give a single big kick
  2442. int32_t damage_armor; // damage absorbed by armor
  2443. int32_t damage_parmor; // damage absorbed by power armor
  2444. int32_t damage_blood; // damage taken out of health
  2445. int32_t damage_knockback; // impact damage
  2446. vec3_t damage_from; // origin for vector calculation
  2447. damage_indicator_t damage_indicators[MAX_DAMAGE_INDICATORS];
  2448. uint8_t num_damage_indicators;
  2449. float killer_yaw; // when dead, look at killer
  2450. weaponstate_t weaponstate;
  2451. struct {
  2452. vec3_t angles, origin;
  2453. gtime_t time, total;
  2454. } kick;
  2455. gtime_t quake_time;
  2456. vec3_t kick_origin;
  2457. float v_dmg_roll, v_dmg_pitch;
  2458. gtime_t v_dmg_time; // damage kicks
  2459. gtime_t fall_time;
  2460. float fall_value; // for view drop on fall
  2461. float damage_alpha;
  2462. float bonus_alpha;
  2463. vec3_t damage_blend;
  2464. vec3_t v_angle, v_forward; // aiming direction
  2465. float bobtime; // so off-ground doesn't change it
  2466. vec3_t oldviewangles;
  2467. vec3_t oldvelocity;
  2468. edict_t *oldgroundentity; // [Paril-KEX]
  2469. gtime_t flash_time; // [Paril-KEX] for high tickrate
  2470. gtime_t next_drown_time;
  2471. water_level_t old_waterlevel;
  2472. int32_t breather_sound;
  2473. int32_t machinegun_shots; // for weapon raising
  2474. // animation vars
  2475. int32_t anim_end;
  2476. anim_priority_t anim_priority;
  2477. bool anim_duck;
  2478. bool anim_run;
  2479. gtime_t anim_time;
  2480. // powerup timers
  2481. gtime_t quad_time;
  2482. gtime_t invincible_time;
  2483. gtime_t breather_time;
  2484. gtime_t enviro_time;
  2485. gtime_t invisible_time;
  2486. bool grenade_blew_up;
  2487. gtime_t grenade_time, grenade_finished_time;
  2488. // RAFAEL
  2489. gtime_t quadfire_time;
  2490. // RAFAEL
  2491. int32_t silencer_shots;
  2492. int32_t weapon_sound;
  2493. gtime_t pickup_msg_time;
  2494. gtime_t flood_locktill; // locked from talking
  2495. gtime_t flood_when[10]; // when messages were said
  2496. int32_t flood_whenhead; // head pointer for when said
  2497. gtime_t respawn_time; // can respawn when time > this
  2498. edict_t *chase_target; // player we are chasing
  2499. bool update_chase; // need to update chase info?
  2500. //=======
  2501. // ROGUE
  2502. gtime_t double_time;
  2503. gtime_t ir_time;
  2504. gtime_t nuke_time;
  2505. gtime_t tracker_pain_time;
  2506. edict_t *owned_sphere; // this points to the player's sphere
  2507. // ROGUE
  2508. //=======
  2509. gtime_t empty_click_sound;
  2510. // ZOID
  2511. bool inmenu; // in menu
  2512. pmenuhnd_t *menu; // current menu
  2513. gtime_t menutime; // time to update menu
  2514. bool menudirty;
  2515. edict_t *ctf_grapple; // entity of grapple
  2516. int32_t ctf_grapplestate; // true if pulling
  2517. gtime_t ctf_grapplereleasetime; // time of grapple release
  2518. gtime_t ctf_regentime; // regen tech
  2519. gtime_t ctf_techsndtime;
  2520. gtime_t ctf_lasttechmsg;
  2521. // ZOID
  2522. // used for player trails.
  2523. edict_t *trail_head, *trail_tail;
  2524. // whether to use weapon chains
  2525. bool no_weapon_chains;
  2526. // seamless level transitions
  2527. bool landmark_free_fall;
  2528. const char* landmark_name;
  2529. vec3_t landmark_rel_pos; // position relative to landmark, un-rotated from landmark angle
  2530. gtime_t landmark_noise_time;
  2531. gtime_t invisibility_fade_time; // [Paril-KEX] at this time, the player will be mostly fully cloaked
  2532. gtime_t chase_msg_time; // to prevent CTF message spamming
  2533. int32_t menu_sign; // menu sign
  2534. vec3_t last_ladder_pos; // for ladder step sounds
  2535. gtime_t last_ladder_sound;
  2536. coop_respawn_t coop_respawn_state;
  2537. gtime_t last_damage_time;
  2538. // [Paril-KEX] these are now per-player, to work better in coop
  2539. edict_t *sight_entity;
  2540. gtime_t sight_entity_time;
  2541. edict_t *sound_entity;
  2542. gtime_t sound_entity_time;
  2543. edict_t *sound2_entity;
  2544. gtime_t sound2_entity_time;
  2545. // saved positions for lag compensation
  2546. uint8_t num_lag_origins; // 0 to MAX_LAG_ORIGINS, how many we can go back
  2547. uint8_t next_lag_origin; // the next one to write to
  2548. bool is_lag_compensated;
  2549. vec3_t lag_restore_origin;
  2550. // for high tickrate weapon angles
  2551. vec3_t slow_view_angles;
  2552. gtime_t slow_view_angle_time;
  2553. // not saved
  2554. bool help_draw_points;
  2555. size_t help_draw_index, help_draw_count;
  2556. gtime_t help_draw_time;
  2557. uint32_t step_frame;
  2558. int32_t help_poi_image;
  2559. vec3_t help_poi_location;
  2560. // only set temporarily
  2561. bool awaiting_respawn;
  2562. gtime_t respawn_timeout; // after this time, force a respawn
  2563. // [Paril-KEX] current active fog values; density rgb skyfogfactor
  2564. std::array<float, 5> fog;
  2565. height_fog_t heightfog;
  2566. gtime_t last_attacker_time;
  2567. // saved - for coop; last time we were in a firing state
  2568. gtime_t last_firing_time;
  2569. };
  2570. // ==========================================
  2571. // PLAT 2
  2572. // ==========================================
  2573. enum plat2flags_t
  2574. {
  2575. PLAT2_NONE = 0,
  2576. PLAT2_CALLED = 1,
  2577. PLAT2_MOVING = 2,
  2578. PLAT2_WAITING = 4
  2579. };
  2580. MAKE_ENUM_BITFLAGS(plat2flags_t);
  2581. #include <bitset>
  2582. struct edict_t
  2583. {
  2584. edict_t() = delete;
  2585. edict_t(const edict_t &) = delete;
  2586. edict_t(edict_t &&) = delete;
  2587. // shared with server; do not touch members until the "private" section
  2588. entity_state_t s;
  2589. gclient_t *client; // nullptr if not a player
  2590. // the server expects the first part
  2591. // of gclient_t to be a player_state_t
  2592. // but the rest of it is opaque
  2593. sv_entity_t sv; // read only info about this entity for the server
  2594. bool inuse;
  2595. // world linkage data
  2596. bool linked;
  2597. int32_t linkcount;
  2598. int32_t areanum, areanum2;
  2599. svflags_t svflags;
  2600. vec3_t mins, maxs;
  2601. vec3_t absmin, absmax, size;
  2602. solid_t solid;
  2603. contents_t clipmask;
  2604. edict_t *owner;
  2605. //================================
  2606. // private to game
  2607. int32_t spawn_count; // [Paril-KEX] used to differentiate different entities that may be in the same slot
  2608. movetype_t movetype;
  2609. ent_flags_t flags;
  2610. const char *model;
  2611. gtime_t freetime; // sv.time when the object was freed
  2612. //
  2613. // only used locally in game, not by server
  2614. //
  2615. const char *message;
  2616. const char *classname;
  2617. spawnflags_t spawnflags;
  2618. gtime_t timestamp;
  2619. float angle; // set in qe3, -1 = up, -2 = down
  2620. const char *target;
  2621. const char *targetname;
  2622. const char *killtarget;
  2623. const char *team;
  2624. const char *pathtarget;
  2625. const char *deathtarget;
  2626. const char *healthtarget;
  2627. const char *itemtarget; // [Paril-KEX]
  2628. const char *combattarget;
  2629. edict_t *target_ent;
  2630. float speed, accel, decel;
  2631. vec3_t movedir;
  2632. vec3_t pos1, pos2, pos3;
  2633. vec3_t velocity;
  2634. vec3_t avelocity;
  2635. int32_t mass;
  2636. gtime_t air_finished;
  2637. float gravity; // per entity gravity multiplier (1.0 is normal)
  2638. // use for lowgrav artifact, flares
  2639. edict_t *goalentity;
  2640. edict_t *movetarget;
  2641. float yaw_speed;
  2642. float ideal_yaw;
  2643. gtime_t nextthink;
  2644. save_prethink_t prethink;
  2645. save_prethink_t postthink;
  2646. save_think_t think;
  2647. save_touch_t touch;
  2648. save_use_t use;
  2649. save_pain_t pain;
  2650. save_die_t die;
  2651. gtime_t touch_debounce_time; // are all these legit? do we need more/less of them?
  2652. gtime_t pain_debounce_time;
  2653. gtime_t damage_debounce_time;
  2654. gtime_t fly_sound_debounce_time; // move to clientinfo
  2655. gtime_t last_move_time;
  2656. int32_t health;
  2657. int32_t max_health;
  2658. int32_t gib_health;
  2659. gtime_t show_hostile;
  2660. gtime_t powerarmor_time;
  2661. const char *map; // target_changelevel
  2662. int32_t viewheight; // height above origin where eyesight is determined
  2663. bool deadflag;
  2664. bool takedamage;
  2665. int32_t dmg;
  2666. int32_t radius_dmg;
  2667. float dmg_radius;
  2668. int32_t sounds; // make this a spawntemp var?
  2669. int32_t count;
  2670. edict_t *chain;
  2671. edict_t *enemy;
  2672. edict_t *oldenemy;
  2673. edict_t *activator;
  2674. edict_t *groundentity;
  2675. int32_t groundentity_linkcount;
  2676. edict_t *teamchain;
  2677. edict_t *teammaster;
  2678. edict_t *mynoise; // can go in client only
  2679. edict_t *mynoise2;
  2680. int32_t noise_index;
  2681. int32_t noise_index2;
  2682. float volume;
  2683. float attenuation;
  2684. // timing variables
  2685. float wait;
  2686. float delay; // before firing targets
  2687. float random;
  2688. gtime_t teleport_time;
  2689. contents_t watertype;
  2690. water_level_t waterlevel;
  2691. vec3_t move_origin;
  2692. vec3_t move_angles;
  2693. int32_t style; // also used as areaportal number
  2694. gitem_t *item; // for bonus items
  2695. // common data blocks
  2696. moveinfo_t moveinfo;
  2697. monsterinfo_t monsterinfo;
  2698. //=========
  2699. // ROGUE
  2700. plat2flags_t plat2flags;
  2701. vec3_t offset;
  2702. vec3_t gravityVector;
  2703. edict_t *bad_area;
  2704. edict_t *hint_chain;
  2705. edict_t *monster_hint_chain;
  2706. edict_t *target_hint_chain;
  2707. int32_t hint_chain_id;
  2708. // ROGUE
  2709. //=========
  2710. char clock_message[CLOCK_MESSAGE_SIZE];
  2711. // Paril: we died on this frame, apply knockback even if we're dead
  2712. gtime_t dead_time;
  2713. // used for dabeam monsters
  2714. edict_t *beam, *beam2;
  2715. // proboscus for Parasite
  2716. edict_t *proboscus;
  2717. // for vooping things
  2718. edict_t *disintegrator;
  2719. gtime_t disintegrator_time;
  2720. int32_t hackflags; // n64
  2721. // fog stuff
  2722. struct {
  2723. vec3_t color;
  2724. float density;
  2725. float sky_factor;
  2726. vec3_t color_off;
  2727. float density_off;
  2728. float sky_factor_off;
  2729. } fog;
  2730. struct {
  2731. float falloff;
  2732. float density;
  2733. vec3_t start_color;
  2734. float start_dist;
  2735. vec3_t end_color;
  2736. float end_dist;
  2737. float falloff_off;
  2738. float density_off;
  2739. vec3_t start_color_off;
  2740. float start_dist_off;
  2741. vec3_t end_color_off;
  2742. float end_dist_off;
  2743. } heightfog;
  2744. // instanced coop items
  2745. std::bitset<MAX_CLIENTS> item_picked_up_by;
  2746. gtime_t slime_debounce_time;
  2747. // [Paril-KEX]
  2748. bmodel_anim_t bmodel_anim;
  2749. mod_t lastMOD;
  2750. const char *style_on, *style_off;
  2751. uint32_t crosslevel_flags;
  2752. // NOTE: if adding new elements, make sure to add them
  2753. // in g_save.cpp too!
  2754. };
  2755. //=============
  2756. // ROGUE
  2757. constexpr spawnflags_t SPHERE_DEFENDER = 0x0001_spawnflag;
  2758. constexpr spawnflags_t SPHERE_HUNTER = 0x0002_spawnflag;
  2759. constexpr spawnflags_t SPHERE_VENGEANCE = 0x0004_spawnflag;
  2760. constexpr spawnflags_t SPHERE_DOPPLEGANGER = 0x10000_spawnflag;
  2761. constexpr spawnflags_t SPHERE_TYPE = SPHERE_DEFENDER | SPHERE_HUNTER | SPHERE_VENGEANCE;
  2762. constexpr spawnflags_t SPHERE_FLAGS = SPHERE_DOPPLEGANGER;
  2763. //
  2764. // deathmatch games
  2765. //
  2766. enum
  2767. {
  2768. RDM_TAG = 2,
  2769. RDM_DEATHBALL = 3
  2770. };
  2771. struct dm_game_rt
  2772. {
  2773. void (*GameInit)();
  2774. void (*PostInitSetup)();
  2775. void (*ClientBegin)(edict_t *ent);
  2776. bool (*SelectSpawnPoint)(edict_t *ent, vec3_t &origin, vec3_t &angles, bool force_spawn);
  2777. void (*PlayerDeath)(edict_t *targ, edict_t *inflictor, edict_t *attacker);
  2778. void (*Score)(edict_t *attacker, edict_t *victim, int scoreChange, const mod_t &mod);
  2779. void (*PlayerEffects)(edict_t *ent);
  2780. void (*DogTag)(edict_t *ent, edict_t *killer, const char **pic);
  2781. void (*PlayerDisconnect)(edict_t *ent);
  2782. int (*ChangeDamage)(edict_t *targ, edict_t *attacker, int damage, mod_t mod);
  2783. int (*ChangeKnockback)(edict_t *targ, edict_t *attacker, int knockback, mod_t mod);
  2784. int (*CheckDMRules)();
  2785. };
  2786. extern dm_game_rt DMGame;
  2787. // ROGUE
  2788. //============
  2789. // [Paril-KEX]
  2790. inline void monster_footstep(edict_t *self)
  2791. {
  2792. if (self->groundentity)
  2793. self->s.event = EV_OTHER_FOOTSTEP;
  2794. }
  2795. // [Kex] helpers
  2796. // TFilter must be a type that is invokable with the
  2797. // signature bool(edict_t *); it must return true if
  2798. // the entity given is valid for the given filter
  2799. template<typename TFilter>
  2800. struct entity_iterator_t
  2801. {
  2802. using iterator_category = std::random_access_iterator_tag;
  2803. using value_type = edict_t *;
  2804. using reference = edict_t *;
  2805. using pointer = edict_t *;
  2806. using difference_type = ptrdiff_t;
  2807. private:
  2808. uint32_t index;
  2809. uint32_t end_index; // where the end index is located for this iterator
  2810. // index < globals.num_edicts are valid
  2811. TFilter filter;
  2812. // this doubles as the "end" iterator
  2813. inline bool is_out_of_range(uint32_t i) const
  2814. {
  2815. return i >= end_index;
  2816. }
  2817. inline bool is_out_of_range() const
  2818. {
  2819. return is_out_of_range(index);
  2820. }
  2821. inline void throw_if_out_of_range() const
  2822. {
  2823. if (is_out_of_range())
  2824. throw std::out_of_range("index");
  2825. }
  2826. inline difference_type clamped_index() const
  2827. {
  2828. if (is_out_of_range())
  2829. return end_index;
  2830. return index;
  2831. }
  2832. public:
  2833. // note: index is not affected by filter. it is up to
  2834. // the caller to ensure this index is filtered.
  2835. constexpr entity_iterator_t(uint32_t i, uint32_t end_index = -1) : index(i), end_index((end_index >= globals.num_edicts) ? globals.num_edicts : end_index) { }
  2836. inline reference operator*() { throw_if_out_of_range(); return &g_edicts[index]; }
  2837. inline pointer operator->() { throw_if_out_of_range(); return &g_edicts[index]; }
  2838. inline entity_iterator_t &operator++()
  2839. {
  2840. throw_if_out_of_range();
  2841. return *this = *this + 1;
  2842. }
  2843. inline entity_iterator_t &operator--()
  2844. {
  2845. throw_if_out_of_range();
  2846. return *this = *this - 1;
  2847. }
  2848. inline difference_type operator-(const entity_iterator_t &it) const
  2849. {
  2850. return clamped_index() - it.clamped_index();
  2851. }
  2852. inline entity_iterator_t operator+(const difference_type &offset) const
  2853. {
  2854. entity_iterator_t it(index + offset, end_index);
  2855. // move in the specified direction, only stopping if we
  2856. // run out of range or find a filtered entity
  2857. while (!is_out_of_range(it.index) && !filter(*it))
  2858. it.index += offset > 0 ? 1 : -1;
  2859. return it;
  2860. }
  2861. // + -1 and - 1 are the same (and - -1 & + 1)
  2862. inline entity_iterator_t operator-(const difference_type &offset) const { return *this + (-offset); }
  2863. // comparison. hopefully this won't break anything, but == and != use the
  2864. // clamped index (so -1 and num_edicts will be equal technically since they
  2865. // are the same "invalid" entity) but <= and >= will affect them properly.
  2866. inline bool operator==(const entity_iterator_t &it) const { return clamped_index() == it.clamped_index(); }
  2867. inline bool operator!=(const entity_iterator_t &it) const { return clamped_index() != it.clamped_index(); }
  2868. inline bool operator<(const entity_iterator_t &it) const { return index < it.index; }
  2869. inline bool operator>(const entity_iterator_t &it) const { return index > it.index; }
  2870. inline bool operator<=(const entity_iterator_t &it) const { return index <= it.index; }
  2871. inline bool operator>=(const entity_iterator_t &it) const { return index >= it.index; }
  2872. inline edict_t *operator[](const difference_type &offset) const { return *(*this + offset); }
  2873. };
  2874. // iterate over range of entities, with the specified filter.
  2875. // can be "open-ended" (automatically expand with num_edicts)
  2876. // by leaving the max unset.
  2877. template<typename TFilter>
  2878. struct entity_iterable_t
  2879. {
  2880. private:
  2881. uint32_t begin_index, end_index;
  2882. TFilter filter;
  2883. // find the first entity that matches the filter, from the specified index,
  2884. // in the specified direction
  2885. inline uint32_t find_matched_index(uint32_t index, int32_t direction)
  2886. {
  2887. while (index < globals.num_edicts && !filter(&g_edicts[index]))
  2888. index += direction;
  2889. return index;
  2890. }
  2891. public:
  2892. // iterate all allocated entities that match the filter,
  2893. // including ones allocated after this iterator is constructed
  2894. inline entity_iterable_t<TFilter>() : begin_index(find_matched_index(0, 1)), end_index(game.maxentities) { }
  2895. // iterate all allocated entities that match the filter from the specified begin offset
  2896. // including ones allocated after this iterator is constructed
  2897. inline entity_iterable_t<TFilter>(uint32_t start) : begin_index(find_matched_index(start, 1)), end_index(game.maxentities) { }
  2898. // iterate all allocated entities that match the filter from the specified begin offset
  2899. // to the specified INCLUSIVE end offset (or the first entity that matches before it),
  2900. // including end itself but not ones that may appear after this iterator is done
  2901. inline entity_iterable_t<TFilter>(uint32_t start, uint32_t end) :
  2902. begin_index(find_matched_index(start, 1)),
  2903. end_index(find_matched_index(end, -1) + 1)
  2904. {
  2905. }
  2906. inline entity_iterator_t<TFilter> begin() const { return entity_iterator_t<TFilter>(begin_index, end_index); }
  2907. inline entity_iterator_t<TFilter> end() const { return end_index; }
  2908. };
  2909. // inuse players that are connected; may not be spawned yet, however
  2910. struct active_players_filter_t
  2911. {
  2912. inline bool operator()(edict_t *ent) const
  2913. {
  2914. return (ent->inuse && ent->client && ent->client->pers.connected);
  2915. }
  2916. };
  2917. inline entity_iterable_t<active_players_filter_t> active_players()
  2918. {
  2919. return entity_iterable_t<active_players_filter_t> { 1u, game.maxclients };
  2920. }
  2921. struct gib_def_t
  2922. {
  2923. size_t count;
  2924. const char *gibname;
  2925. float scale;
  2926. gib_type_t type;
  2927. constexpr gib_def_t(size_t count, const char *gibname) :
  2928. count(count),
  2929. gibname(gibname),
  2930. scale(1.0f),
  2931. type(GIB_NONE)
  2932. {
  2933. }
  2934. constexpr gib_def_t(size_t count, const char *gibname, gib_type_t type) :
  2935. count(count),
  2936. gibname(gibname),
  2937. scale(1.0f),
  2938. type(type)
  2939. {
  2940. }
  2941. constexpr gib_def_t(size_t count, const char *gibname, float scale) :
  2942. count(count),
  2943. gibname(gibname),
  2944. scale(scale),
  2945. type(GIB_NONE)
  2946. {
  2947. }
  2948. constexpr gib_def_t(size_t count, const char *gibname, float scale, gib_type_t type) :
  2949. count(count),
  2950. gibname(gibname),
  2951. scale(scale),
  2952. type(type)
  2953. {
  2954. }
  2955. constexpr gib_def_t(const char *gibname, float scale, gib_type_t type) :
  2956. count(1),
  2957. gibname(gibname),
  2958. scale(scale),
  2959. type(type)
  2960. {
  2961. }
  2962. constexpr gib_def_t(const char *gibname, float scale) :
  2963. count(1),
  2964. gibname(gibname),
  2965. scale(scale),
  2966. type(GIB_NONE)
  2967. {
  2968. }
  2969. constexpr gib_def_t(const char *gibname, gib_type_t type) :
  2970. count(1),
  2971. gibname(gibname),
  2972. scale(1.0f),
  2973. type(type)
  2974. {
  2975. }
  2976. constexpr gib_def_t(const char *gibname) :
  2977. count(1),
  2978. gibname(gibname),
  2979. scale(1.0f),
  2980. type(GIB_NONE)
  2981. {
  2982. }
  2983. };
  2984. // convenience function to throw different gib types
  2985. // NOTE: always throw the head gib *last* since self's size is used
  2986. // to position the gibs!
  2987. inline void ThrowGibs(edict_t *self, int32_t damage, std::initializer_list<gib_def_t> gibs)
  2988. {
  2989. for (auto &gib : gibs)
  2990. for (size_t i = 0; i < gib.count; i++)
  2991. ThrowGib(self, gib.gibname, damage, gib.type, gib.scale * (self->s.scale ? self->s.scale : 1));
  2992. }
  2993. inline bool M_CheckGib(edict_t *self, const mod_t &mod)
  2994. {
  2995. if (self->deadflag)
  2996. {
  2997. if (mod.id == MOD_CRUSH)
  2998. return true;
  2999. }
  3000. return self->health <= self->gib_health;
  3001. }
  3002. // Fmt support for entities
  3003. template<>
  3004. struct fmt::formatter<edict_t>
  3005. {
  3006. template<typename ParseContext>
  3007. constexpr auto parse(ParseContext& ctx)
  3008. {
  3009. return ctx.begin();
  3010. }
  3011. template<typename FormatContext>
  3012. auto format(const edict_t &p, FormatContext &ctx) -> decltype(ctx.out())
  3013. {
  3014. if (p.linked)
  3015. return fmt::format_to(ctx.out(), FMT_STRING("{} @ {}"), p.classname, (p.absmax + p.absmin) * 0.5f);
  3016. return fmt::format_to(ctx.out(), FMT_STRING("{} @ {}"), p.classname, p.s.origin);
  3017. }
  3018. };
  3019. // POI tags used by this mod
  3020. enum pois_t : uint16_t
  3021. {
  3022. POI_OBJECTIVE = MAX_EDICTS, // current objective
  3023. POI_RED_FLAG, // red flag/carrier
  3024. POI_BLUE_FLAG, // blue flag/carrier
  3025. POI_PING,
  3026. POI_PING_END = POI_PING + MAX_CLIENTS - 1,
  3027. };
  3028. // implementation of pierce stuff
  3029. inline bool pierce_args_t::mark(edict_t *ent)
  3030. {
  3031. // ran out of pierces
  3032. if (num_pierced == MAX_PIERCE)
  3033. return false;
  3034. pierced[num_pierced] = ent;
  3035. pierce_solidities[num_pierced] = ent->solid;
  3036. num_pierced++;
  3037. ent->solid = SOLID_NOT;
  3038. gi.linkentity(ent);
  3039. return true;
  3040. }
  3041. // implementation of pierce stuff
  3042. inline void pierce_args_t::restore()
  3043. {
  3044. for (size_t i = 0; i < num_pierced; i++)
  3045. {
  3046. auto &ent = pierced[i];
  3047. ent->solid = pierce_solidities[i];
  3048. gi.linkentity(ent);
  3049. }
  3050. num_pierced = 0;
  3051. }
  3052. // [Paril-KEX] these are to fix a legacy bug with cached indices
  3053. // in save games. these can *only* be static/globals!
  3054. template<auto T>
  3055. struct cached_assetindex
  3056. {
  3057. static cached_assetindex<T> *head;
  3058. const char *name;
  3059. int32_t index = 0;
  3060. cached_assetindex *next = nullptr;
  3061. inline cached_assetindex()
  3062. {
  3063. next = head;
  3064. cached_assetindex<T>::head = this;
  3065. }
  3066. constexpr operator int32_t() const { return index; }
  3067. // assigned from spawn functions
  3068. inline void assign(const char *name) { this->name = name; index = (gi.*T)(name); }
  3069. // cleared before SpawnEntities
  3070. constexpr void clear() { index = 0; }
  3071. // re-find the index for the given cached entry, if we were cached
  3072. // by the regular map load
  3073. inline void reset() { if (index) index = (gi.*T)(this->name); }
  3074. static void reset_all()
  3075. {
  3076. auto asset = head;
  3077. while (asset)
  3078. {
  3079. asset->reset();
  3080. asset = asset->next;
  3081. }
  3082. }
  3083. static void clear_all()
  3084. {
  3085. auto asset = head;
  3086. while (asset)
  3087. {
  3088. asset->clear();
  3089. asset = asset->next;
  3090. }
  3091. }
  3092. };
  3093. using cached_soundindex = cached_assetindex<&local_game_import_t::soundindex>;
  3094. using cached_modelindex = cached_assetindex<&local_game_import_t::modelindex>;
  3095. using cached_imageindex = cached_assetindex<&local_game_import_t::imageindex>;
  3096. template<> cached_soundindex *cached_soundindex::head;
  3097. template<> cached_modelindex *cached_modelindex::head;
  3098. template<> cached_imageindex *cached_imageindex::head;
  3099. extern cached_modelindex sm_meat_index;
  3100. extern cached_soundindex snd_fry;