fixed ticket [f9c074e766ade1bd] (pickups should not be infinitely tall) (i hope ;-)
[k8vavoom.git] / source / psim / p_levelinfo.h
blob1fb1f51b984db5f972c4ede885a8c630a754778a
1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
12 //**
13 //** This program is free software: you can redistribute it and/or modify
14 //** it under the terms of the GNU General Public License as published by
15 //** the Free Software Foundation, version 3 of the License ONLY.
16 //**
17 //** This program is distributed in the hope that it will be useful,
18 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 //** GNU General Public License for more details.
21 //**
22 //** You should have received a copy of the GNU General Public License
23 //** along with this program. If not, see <http://www.gnu.org/licenses/>.
24 //**
25 //**************************************************************************
26 #ifndef VAVOOM_PSIM_LEVELINFO_HEADER
27 #define VAVOOM_PSIM_LEVELINFO_HEADER
29 #include "../mapinfo.h"
30 #include "p_thinker.h"
33 extern VCvarI compat_nopassover;
34 extern VCvarI compat_notossdrops;
35 extern VCvarI compat_limitpain;
37 class VLevelInfo : public VThinker {
38 DECLARE_CLASS(VLevelInfo, VThinker, 0)
39 NO_DEFAULT_CONSTRUCTOR(VLevelInfo)
41 //enum { TID_HASH_SIZE = 1021 };
42 enum { TID_HASH_SIZE = 1024 };
44 VGameInfo *Game;
45 VWorldInfo *World;
47 VStr LevelName;
48 vint32 LevelNum;
49 vuint8 Cluster;
51 VName NextMap;
52 VName SecretMap;
54 vint32 ParTime;
55 vint32 SuckTime;
57 vint32 Sky1Texture;
58 vint32 Sky2Texture;
59 float Sky1ScrollDelta;
60 float Sky2ScrollDelta;
61 VName SkyBox;
63 VName FadeTable;
64 vuint32 Fade;
65 vuint32 OutsideFog;
67 VName SongLump;
69 enum {
70 LIF_DoubleSky = 0x00000001u, // parallax sky: sky2 behind sky1
71 LIF_Lightning = 0x00000002u, // use of lightning on the level flashes from sky1 to sky2
72 LIF_Map07Special = 0x00000004u,
73 LIF_BaronSpecial = 0x00000008u,
74 LIF_CyberDemonSpecial = 0x00000010u,
75 LIF_SpiderMastermindSpecial = 0x00000020u,
76 LIF_MinotaurSpecial = 0x00000040u,
77 LIF_DSparilSpecial = 0x00000080u,
78 LIF_IronLichSpecial = 0x00000100u,
79 LIF_SpecialActionOpenDoor = 0x00000200u,
80 LIF_SpecialActionLowerFloor = 0x00000400u,
81 LIF_SpecialActionKillMonsters = 0x00000800u,
82 LIF_NoIntermission = 0x00001000u,
83 LIF_AllowMonsterTelefrags = 0x00002000u,
84 LIF_NoAllies = 0x00004000u,
85 LIF_DeathSlideShow = 0x00008000u,
86 LIF_ForceNoSkyStretch = 0x00010000u,
87 LIF_LookupName = 0x00020000u,
88 LIF_FallingDamage = 0x00040000u,
89 LIF_OldFallingDamage = 0x00080000u,
90 LIF_StrifeFallingDamage = 0x00100000u,
91 LIF_MonsterFallingDamage = 0x00200000u,
92 LIF_NoFreelook = 0x00400000u,
93 LIF_NoJump = 0x00800000u,
94 LIF_NoAutoSndSeq = 0x01000000u,
95 LIF_ActivateOwnSpecial = 0x02000000u,
96 LIF_MissilesActivateImpact = 0x04000000u,
97 LIF_FilterStarts = 0x08000000u,
98 LIF_InfiniteFlightPowerup = 0x10000000u,
99 LIF_ClipMidTex = 0x20000000u,
100 LIF_WrapMidTex = 0x40000000u,
101 LIF_KeepFullInventory = 0x80000000u,
103 vuint32 LevelInfoFlags;
104 enum {
105 LIF2_CompatShortTex = 0x00000001u,
106 LIF2_CompatStairs = 0x00000002u,
107 LIF2_CompatLimitPain = 0x00000004u,
108 LIF2_CompatNoPassOver = 0x00000008u,
109 LIF2_CompatNoTossDrops = 0x00000010u,
110 LIF2_CompatUseBlocking = 0x00000020u,
111 LIF2_CompatNoDoorLight = 0x00000040u,
112 LIF2_CompatRavenScroll = 0x00000080u,
113 LIF2_CompatSoundTarget = 0x00000100u,
114 LIF2_CompatDehHealth = 0x00000200u,
115 LIF2_CompatTrace = 0x00000400u,
116 LIF2_CompatDropOff = 0x00000800u,
117 LIF2_CompatBoomScroll = 0x00001000u,
118 LIF2_CompatInvisibility = 0x00002000u,
119 LIF2_LaxMonsterActivation = 0x00004000u,
120 LIF2_HaveMonsterActivation = 0x00008000u,
121 LIF2_ClusterHub = 0x00010000u,
122 LIF2_BegunPlay = 0x00020000u,
123 LIF2_Frozen = 0x00040000u,
124 LIF2_NoCrouch = 0x00080000u,
125 LIF2_ResetHealth = 0x00100000u,
126 LIF2_ResetInventory = 0x00200000u,
127 LIF2_ResetItems = 0x00400000u,
128 LIF2_CheckSwitchRange = 0x00800000u, // force "check switch range" flag
129 LIF2_NoCheckSwitchRange = 0x01000000u, // ignore "check switch range" flag
131 vuint32 LevelInfoFlags2;
133 vint32 TotalKills;
134 vint32 TotalItems;
135 vint32 TotalSecret; // for intermission
136 vint32 CurrentKills;
137 vint32 CurrentItems;
138 vint32 CurrentSecret;
140 float CompletitionTime; // for intermission
142 // maintain single and multi player starting spots
143 TArray<mthing_t> DeathmatchStarts; // player spawn spots for deathmatch
144 TArray<mthing_t> PlayerStarts; // player spawn spots
146 VEntity *TIDHash[TID_HASH_SIZE];
148 float Gravity; // level gravity
149 float AirControl;
150 vint32 Infighting;
151 TArray<VMapSpecialAction> SpecialActions;
153 vint32 PerfectHatredMode;
155 public:
156 static inline int TIDHashBucket (int tid) noexcept { return (int)(hashU32((unsigned)tid)%TID_HASH_SIZE); }
158 public:
159 //VLevelInfo ();
160 virtual void PostCtor () override;
162 void SetMapInfo (VLevel *Level, const VMapInfo &);
164 // if `org` is `nullptr`, use sector sound origin
165 void SectorStartSound (const sector_t *Sector, int SoundId, int Channel, float Volume, float Attenuation, const TVec *org=nullptr);
166 void SectorStopSound (const sector_t *sector, int channel);
167 void SectorStartSequence (const sector_t *Sector, VName Name, int ModeNum);
168 void SectorStopSequence (const sector_t *sector);
169 void PolyobjStartSequence (const polyobj_t *Poly, VName Name, int ModeNum);
170 void PolyobjStopSequence (const polyobj_t *poly);
172 void ExitLevel (int Position);
173 void SecretExitLevel (int Position);
174 void Completed (int Map, int Position, int SaveAngle);
176 static bool IsSwitchTexture (int texid);
177 // `line` is used to calculate sound origin; can be `nullptr1
178 // `sidenum` is side index in `Sides` array
179 bool ChangeSwitchTexture (line_t *line, VEntity *activator, int sidenum, bool useAgain, VName DefaultSound, bool &Quest, const TVec *org=nullptr);
180 bool StartButton (line_t *line, VEntity *activator, int sidenum, vuint8 w, int SwitchDef, VName DefaultSound, bool UseAgain, TVec &outsndorg);
182 VEntity *FindMobjFromTID (int, VEntity *);
184 void ChangeMusic (VName);
186 VStr GetLevelName () const;
188 int FindFreeTID (int tidstart, int limit=0) const;
189 bool IsTIDUsed (int tid, bool allowdead=false) const;
191 void ChangeSky (VStr skytex1, VStr skytex2);
193 // static lights
194 DECLARE_FUNCTION(AddStaticLight)
195 DECLARE_FUNCTION(AddStaticLightRGB)
196 DECLARE_FUNCTION(AddStaticLightRGBSector)
197 DECLARE_FUNCTION(MoveStaticLightByOwner)
198 DECLARE_FUNCTION(RemoveStaticLightByOwner)
200 // sound sequences
201 DECLARE_FUNCTION(SectorStartSequence)
202 DECLARE_FUNCTION(SectorStopSequence)
203 DECLARE_FUNCTION(PolyobjStartSequence)
204 DECLARE_FUNCTION(PolyobjStopSequence)
206 // exiting the level
207 DECLARE_FUNCTION(ExitLevel)
208 DECLARE_FUNCTION(SecretExitLevel)
209 DECLARE_FUNCTION(Completed)
211 // special thinker utilites
212 DECLARE_FUNCTION(IsSwitchTexture)
213 DECLARE_FUNCTION(ChangeSwitchTexture)
214 DECLARE_FUNCTION(FindMobjFromTID)
215 DECLARE_FUNCTION(AutoSave)
217 DECLARE_FUNCTION(ChangeMusic)
219 DECLARE_FUNCTION(FindFreeTID)
220 DECLARE_FUNCTION(IsTIDUsed)
222 DECLARE_FUNCTION(ChangeSky)
224 DECLARE_FUNCTION(GetLevelName)
226 DECLARE_FUNCTION (get_CompatShortTex)
227 DECLARE_FUNCTION (get_CompatStairs)
228 DECLARE_FUNCTION (get_CompatLimitPain)
229 DECLARE_FUNCTION (get_CompatNoPassOver)
230 DECLARE_FUNCTION (get_CompatNoTossDrops)
231 DECLARE_FUNCTION (get_CompatUseBlocking)
232 DECLARE_FUNCTION (get_CompatNoDoorLight)
233 DECLARE_FUNCTION (get_CompatRavenScroll)
234 DECLARE_FUNCTION (get_CompatSoundTarget)
235 DECLARE_FUNCTION (get_CompatDehHealth)
236 DECLARE_FUNCTION (get_CompatTrace)
237 DECLARE_FUNCTION (get_CompatDropOff)
238 DECLARE_FUNCTION (get_CompatBoomScroll)
239 DECLARE_FUNCTION (get_CompatInvisibility)
242 static float GZSizeToRadius (float Val, bool attenuated, float attmult=1.04f) {
243 static VMethodProxy method("GZSizeToRadius");
244 vobjPutParam(Val, attenuated, VOptPutParamFloat(attmult, true));
245 VSTATIC_RET_FLOAT(method);
248 // EntityEx PickActor (optional TVec Origin, TVec dir, float distance, optional int actorMask, optional int wallMask) {
249 // final bool CheckLock (Entity user, int lock, bool door)
250 bool eventCheckLock (VEntity *user, int lock, bool door) { static VMethodProxy method("CheckLock"); vobjPutParamSelf(user, lock, door); VMT_RET_BOOL(method); }
251 void eventSpawnSpecials () { static VMethodProxy method("SpawnSpecials"); vobjPutParamSelf(); VMT_RET_VOID(method); }
252 void eventUpdateSpecials () { static VMethodProxy method("UpdateSpecials"); vobjPutParamSelf(); VMT_RET_VOID(method); }
253 void eventAfterUnarchiveThinkers () { static VMethodProxy method("AfterUnarchiveThinkers"); vobjPutParamSelf(); VMT_RET_VOID(method); }
255 bool eventPolyThrustMobj (VEntity *A, TVec thrustDir, polyobj_t *po, bool vertical) { static VMethodProxy method("PolyThrustMobj"); vobjPutParamSelf(A, thrustDir, po, vertical); VMT_RET_BOOL(method); }
256 void eventPolyCrushMobj (VEntity *A, polyobj_t *po) { static VMethodProxy method("PolyCrushMobj"); vobjPutParamSelf(A, po); VMT_RET_VOID(method); }
258 void eventPolyRotateMobj (VEntity *A, float dangle) { static VMethodProxy method("PolyRotateMobj"); vobjPutParamSelf(A, dangle); VMT_RET_VOID(method); }
259 //bool eventPolyMoveMobjBy (VEntity *A, vuint32 poflags, float dx, float dy) { static VMethodProxy method("PolyMoveMobjBy"); vobjPutParamSelf(A, poflags, dx, dy); VMT_RET_BOOL(method); }
261 bool eventTagBusy (int tag) { static VMethodProxy method("TagBusy"); vobjPutParamSelf(tag); VMT_RET_BOOL(method); }
262 bool eventPolyBusy (int polyobj) { static VMethodProxy method("PolyBusy"); vobjPutParamSelf(polyobj); VMT_RET_BOOL(method); }
263 float eventPolyAngle (int polyobj) { static VMethodProxy method("PolyAngle"); vobjPutParamSelf(polyobj); VMT_RET_FLOAT(method); }
264 int eventThingCount (int type, VName TypeName, int tid, int SectorTag) { static VMethodProxy method("ThingCount"); vobjPutParamSelf(type, TypeName, tid, SectorTag); VMT_RET_INT(method); }
265 int eventExecuteActionSpecial (int Special, int Arg1, int Arg2, int Arg3,
266 int Arg4, int Arg5, line_t *Line, int Side, VEntity *A)
268 static VMethodProxy method("ExecuteActionSpecial");
269 vobjPutParamSelf(Special, Arg1, Arg2, Arg3, Arg4, Arg5, Line, Side, A);
270 VMT_RET_INT(method);
272 int eventEV_ThingProjectile (int tid, int type, int angle, int speed,
273 int vspeed, int gravity, int newtid,
274 VName TypeName, VEntity *Activator)
276 static VMethodProxy method("EV_ThingProjectile");
277 vobjPutParamSelf(tid, type, angle, speed, vspeed, gravity, newtid, TypeName, Activator);
278 VMT_RET_INT(method);
280 void eventStartPlaneWatcher (VEntity *it, line_t *line, int lineSide,
281 bool ceiling, int tag, int height, int special,
282 int arg1, int arg2, int arg3, int arg4, int arg5)
284 static VMethodProxy method("StartPlaneWatcher");
285 vobjPutParamSelf(it, line, lineSide, ceiling, tag, height, special, arg1, arg2, arg3, arg4, arg5);
286 VMT_RET_VOID(method);
288 void eventSpawnMapThing (mthing_t *mthing) { static VMethodProxy method("SpawnMapThing"); vobjPutParamSelf(mthing); VMT_RET_VOID(method); }
289 void eventUpdateParticle (particle_t *p, float DeltaTime) { if (DeltaTime <= 0.0f) return; static VMethodProxy method("UpdateParticle"); vobjPutParamSelf(p, DeltaTime); VMT_RET_VOID(method); }
290 //final override int AcsSpawnThing(name Name, TVec Org, int Tid, float Angle, bool forced)
291 int eventAcsSpawnThing (VName Name, TVec Org, int Tid, float Angle, bool forced=false) {
292 static VMethodProxy method("AcsSpawnThing");
293 vobjPutParamSelf(Name, Org, Tid, Angle, forced);
294 VMT_RET_INT(method);
296 int eventAcsSpawnSpot (VName Name, int SpotTid, int Tid, float Angle, bool forced=false) {
297 static VMethodProxy method("AcsSpawnSpot");
298 vobjPutParamSelf(Name, SpotTid, Tid, Angle, forced);
299 VMT_RET_INT(method);
301 int eventAcsSpawnSpotFacing (VName Name, int SpotTid, int Tid, bool forced=false) {
302 static VMethodProxy method("AcsSpawnSpotFacing");
303 vobjPutParamSelf(Name, SpotTid, Tid, forced);
304 VMT_RET_INT(method);
306 int eventAcsDamageActor (int targettid, int targetptr, int inflictortid, int inflictorptr, int damage, VName damagetype, VEntity *Activator) {
307 static VMethodProxy method("AcsDamageActor");
308 vobjPutParamSelf(targettid, targetptr, inflictortid, inflictorptr, damage, damagetype, Activator);
309 VMT_RET_INT(method);
312 int AcsSpawnDecal (VEntity *ent, VName decalname, TVec org, float dist, float angle, bool permanent) {
313 static VMethodProxy method("AcsSpawnDecal");
314 vobjPutParamSelf(ent, decalname, org, dist, angle, permanent);
315 VMT_RET_INT(method);
318 int eventAcsPolyMoveRotateEx (int po, int hspeed, int yawangle, int dist, int vspeed, int vdist, float deltaangle, int moveflags, VEntity *Activator) {
319 static VMethodProxy method("AcsPolyMoveRotateEx");
320 vobjPutParamSelf(po, hspeed, yawangle, dist, vspeed, vdist, deltaangle, moveflags, Activator);
321 VMT_RET_INT(method);
323 int eventAcsPolyMoveToRotateEx (int po, int speed, int x, int y, int z, float deltaangle, int moveflags, VEntity *Activator) {
324 static VMethodProxy method("AcsPolyMoveToRotateEx");
325 vobjPutParamSelf(po, speed, x, y, z, deltaangle, moveflags, Activator);
326 VMT_RET_INT(method);
328 int eventAcsPolyMoveToSpotRotateEx (int po, int speed, int targettid, float deltaangle, int moveflags, VEntity *Activator) {
329 static VMethodProxy method("AcsPolyMoveToSpotRotateEx");
330 vobjPutParamSelf(po, speed, targettid, deltaangle, moveflags, Activator);
331 VMT_RET_INT(method);
333 int eventAcsPolyRotateEx (int po, int speed, float deltaangle, int moveflags, VEntity *Activator) {
334 static VMethodProxy method("AcsPolyRotateEx");
335 vobjPutParamSelf(po, speed, deltaangle, moveflags, Activator);
336 VMT_RET_INT(method);
339 void eventSectorDamage (int Tag, int Amount, VName DamageType, VName ProtectionType, int Flags) {
340 static VMethodProxy method("SectorDamage");
341 vobjPutParamSelf(Tag, Amount, DamageType, ProtectionType, Flags);
342 VMT_RET_VOID(method);
344 int eventDoThingDamage (int Tid, int Amount, VName DmgType, VEntity *Activator) {
345 static VMethodProxy method("DoThingDamage");
346 vobjPutParamSelf(Tid, Amount, DmgType, Activator);
347 VMT_RET_INT(method);
349 void eventSetMarineWeapon (int Tid, int Weapon, VEntity *Activator) {
350 static VMethodProxy method("SetMarineWeapon");
351 vobjPutParamSelf(Tid, Weapon, Activator);
352 VMT_RET_VOID(method);
354 void eventSetMarineSprite (int Tid, VName SrcClass, VEntity *Activator) {
355 static VMethodProxy method("SetMarineSprite");
356 vobjPutParamSelf(Tid, SrcClass, Activator);
357 VMT_RET_VOID(method);
359 void eventAcsFadeRange (float BlendR1, float BlendG1, float BlendB1,
360 float BlendA1, float BlendR2, float BlendG2, float BlendB2,
361 float BlendA2, float Duration, VEntity *Activator)
363 static VMethodProxy method("AcsFadeRange");
364 vobjPutParamSelf(BlendR1, BlendG1, BlendB1, BlendA1, BlendR2, BlendG2, BlendB2, BlendA2, Duration, Activator);
365 VMT_RET_VOID(method);
367 void eventAcsCancelFade (VEntity *Activator) {
368 static VMethodProxy method("AcsCancelFade");
369 vobjPutParamSelf(Activator);
370 VMT_RET_VOID(method);
372 void eventAcsRadiusQuake2 (VEntity *Activator, int tid, int intensity, int duration, int damrad, int tremrad, VName sound) {
373 static VMethodProxy method("AcsRadiusQuake2");
374 vobjPutParamSelf(Activator, tid, intensity, duration, damrad, tremrad, sound);
375 VMT_RET_VOID(method);
377 void eventAcsWarp (VEntity *Activator, int tid, float xofs, float yofs, float zofs, float angle, int flags, VName succState, bool exact, float heightoffset, float radiusoffset, float pitch) {
378 static VMethodProxy method("AcsWarp");
379 vobjPutParamSelf(Activator, tid, xofs, yofs, zofs, angle, flags, succState, exact, heightoffset, radiusoffset, pitch);
380 VMT_RET_VOID(method);
383 void eventAfterSetMapInfo (VLevel *Level) { static VMethodProxy method("AfterSetMapInfo"); vobjPutParamSelf(Level); VMT_RET_VOID(method); }
385 #define CREATE_COMPAT_GETTER(name_,cvar_,flagvar_,flagname_) \
386 VVA_CHECKRESULT inline bool name_ () const noexcept { \
387 switch (cvar_.asInt()) { \
388 case 1: return true; /* always on */ \
389 case 2: return false; /* always off */ \
390 default: return !!(flagvar_&flagname_); /* map default */ \
394 CREATE_COMPAT_GETTER(GetNoPassOver,compat_nopassover,LevelInfoFlags2,LIF2_CompatNoPassOver)
395 CREATE_COMPAT_GETTER(GetNoTossDrops,compat_notossdrops,LevelInfoFlags2,LIF2_CompatNoTossDrops)
396 CREATE_COMPAT_GETTER(GetLimitPain,compat_limitpain,LevelInfoFlags2,LIF2_CompatLimitPain)
398 #undef CREATE_COMPAT_GETTER
402 #endif