1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: p_entity.h 4327 2010-07-24 19:30:53Z firebrand_kh $
11 //**
12 //**	Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 //
26 //								ENTITY DATA
27 //
28 // 	NOTES: VEntity
29 //
30 // 	mobj_ts are used to tell the refresh where to draw an image, tell the
31 // world simulation when objects are contacted, and tell the sound driver
32 // how to position a sound.
33 //
34 // 	The refresh uses the next and prev links to follow lists of things in
35 // sectors as they are being drawn. The sprite, frame, and angle elements
36 // determine which patch_t is used to draw the sprite if it is visible.
37 // The sprite and frame values are allmost allways set from VState
38 // structures. The statescr.exe utility generates the states.h and states.c
39 // files that contain the sprite/frame numbers from the statescr.txt source
40 // file. The xyz origin point represents a point at the bottom middle of the
41 // sprite (between the feet of a biped). This is the default origin position
42 // for patch_ts grabbed with lumpy.exe. A walking creature will have its z
43 // equal to the floor it is standing on.
44 //
45 // 	The sound code uses the x,y, and subsector fields to do stereo
46 // positioning of any sound effited by the VEntity.
47 //
48 // 	The play simulation uses the blocklinks, x,y,z, radius, height to
49 // determine when mobj_ts are touching each other, touching lines in the map,
50 // or hit by trace lines (gunshots, lines of sight, etc). The VEntity->flags
51 // element has various bit flags used by the simulation.
52 //
53 // 	Every VEntity is linked into a single sector based on its origin
54 // coordinates. The subsector_t is found with R_PointInSubsector(x,y), and
55 // the sector_t can be found with subsector->sector. The sector links are
56 // only used by the rendering code, the play simulation does not care about
57 // them at all.
58 //
59 // 	Any VEntity that needs to be acted upon by something else in the play
60 // world (block movement, be shot, etc) will also need to be linked into the
61 // blockmap. If the thing has the MF_NOBLOCK flag set, it will not use the
62 // block links. It can still interact with other things, but only as the
63 // instigator (missiles will run into other things, but nothing can run into
64 // a missile). Each block in the grid is 128*128 units, and knows about every
65 // line_t that it contains a piece of, and every interactable VEntity that has
66 // its origin contained.
67 //
68 // 	A valid VEntity is a VEntity that has the proper subsector_t filled in for
69 // its xy coordinates and is linked into the sector from which the subsector
70 // was made, or has the MF_NOSECTOR flag set (the subsector_t needs to be
71 // valid even if MF_NOSECTOR is set), and is linked into a blockmap block or
72 // has the MF_NOBLOCKMAP flag set. Links should only be modified by the
73 // P_[Un]SetThingPosition() functions. Do not change the MF_NO? flags while
74 // a thing is valid.
75 //
76 // 	Any questions?
77 //
78 //==========================================================================
79 
80 struct tmtrace_t;
81 struct cptrace_t;
82 
83 enum
84 {
85 	STYLE_None,					// Do not draw
86 	STYLE_Normal,				// Normal; just copy the image to the screen
87 	STYLE_Fuzzy,				// Draw silhouette using "fuzz" effect
88 	STYLE_SoulTrans,			// Draw translucent with amount in r_transsouls
89 	STYLE_OptFuzzy,				// Draw as fuzzy or translucent, based on user preference
90 	STYLE_Translucent = 64,		// Draw translucent
91 	STYLE_Add,					// Draw additive
92 };
93 
94 //	Colour tralslation types.
95 enum
96 {
97 	//	No translation.
98 	TRANSL_None,
99 	//	Game's standard translations.
100 	TRANSL_Standard,
101 	//	Per-player translations.
102 	TRANSL_Player,
103 	//	ACS translations.
104 	TRANSL_Level,
105 	//	Translations of dead players.
106 	TRANSL_BodyQueue,
107 	//	Translations defined in DECORATE.
108 	TRANSL_Decorate,
109 	//	Blood translations, for blood colour
110 	TRANSL_Blood,
111 
112 	TRANSL_Max,
113 
114 	TRANSL_TYPE_SHIFT = 16
115 };
116 
117 struct VDropItemInfo
118 {
119 	VClass*			Type;
120 	VName			TypeName;
121 	vint32			Amount;
122 	float			Chance;
123 };
124 
125 struct VDamageFactor
126 {
127 	VName			DamageType;
128 	float			Factor;
129 };
130 
131 struct VPainChanceInfo
132 {
133 	VName			DamageType;
134 	float			Chance;
135 };
136 
137 class VEntity : public VThinker
138 {
139 	DECLARE_CLASS(VEntity, VThinker, 0)
140 	NO_DEFAULT_CONSTRUCTOR(VEntity)
141 
142 	// Info for drawing: position.
143 	TVec			Origin;
144 
145 	// Momentums, used to update position.
146 	TVec			Velocity;
147 
148 	TAVec			Angles;			// orientation
149 
150 	VState*			State;
151 	VState*			DispState;
152 	float			StateTime;		// state tic counter
153 
154 	//More drawing info.
155 	vuint8			SpriteType;		//  How to draw sprite
156 	VName			FixedSpriteName;
157 	VStr			FixedModelName;
158 	vuint8			ModelVersion;
159 
160 	vuint8			RenderStyle;
161 	float			Alpha;
162 	int				Translation;
163 
164 	float			FloorClip;		// value to use for floor clipping
165 
166 	//	Scaling.
167 	float			ScaleX;
168 	float			ScaleY;
169 
170 	subsector_t*	SubSector;
171 	sector_t*		Sector;
172 
173 	// Interaction info, by BLOCKMAP.
174 	// Links in blocks (if needed).
175 	VEntity*		BlockMapNext;
176 	VEntity*		BlockMapPrev;
177 
178 	// Links in sector (if needed).
179 	VEntity*		SNext;
180 	VEntity*		SPrev;
181 
182 	msecnode_t*		TouchingSectorList;
183 
184 	// The closest interval over all contacted Sectors.
185 	float			FloorZ;
186 	float			CeilingZ;
187 	float			DropOffZ;
188 
189 	//	Closest floor and ceiling, source of floorz and ceilingz
190 	sec_plane_t		*Floor;
191 	sec_plane_t		*Ceiling;
192 
193 	// If == validcount, already checked.
194 	int				ValidCount;
195 
196 	//	Flags
197 	enum
198 	{
199 		EF_Solid				= 0x00000001,	// Blocks.
200 		EF_NoSector				= 0x00000002,	// don't use the sector links
201 												// (invisible but touchable)
202 		EF_NoBlockmap			= 0x00000004,	// don't use the blocklinks
203 												// (inert but displayable)
204 		EF_IsPlayer				= 0x00000008,	// Player or player-bot
205 		EF_FixedModel			= 0x00000010,
206 		EF_NoGravity			= 0x00000020,	// don't apply gravity every tic
207 		EF_PassMobj				= 0x00000040,	// Enable z block checking.  If on,
208 												// this flag will allow the mobj
209 												// to pass over/under other mobjs.
210 		EF_ColideWithThings		= 0x00000080,
211 		EF_ColideWithWorld		= 0x00000100,
212 		EF_CheckLineBlocking	= 0x00000200,
213 		EF_CheckLineBlockMonsters	= 0x00000400,
214 		EF_DropOff				= 0x00000800,	// allow jumps from high places
215 		EF_Float				= 0x00001000,	// allow moves to any height, no gravity
216 		EF_Fly					= 0x00002000,	// fly mode is active
217 		EF_Blasted				= 0x00004000,	// missile will pass through ghosts
218 		EF_CantLeaveFloorpic	= 0x00008000,	// stay within a certain floor type
219 		EF_FloorClip			= 0x00010000,	// if feet are allowed to be clipped
220 		EF_IgnoreCeilingStep	= 0x00020000,	// continue walk without lowering itself
221 		EF_IgnoreFloorStep		= 0x00040000,	// continue walk ignoring floor height changes
222 		EF_AvoidingDropoff		= 0x00080000,	// used to move monsters away from dropoffs
223 		EF_OnMobj				= 0x00100000,	// mobj is resting on top of another mobj
224 		EF_Corpse				= 0x00200000,	// don't stop moving halfway off a step
225 		EF_FullBright			= 0x00400000,	// make current state full bright
226 		EF_Invisible			= 0x00800000,	// Don't draw this actor
227 		EF_Missile				= 0x01000000,	// don't hit same species, explode on block
228 		EF_DontOverlap			= 0x02000000,	// Prevent some things from overlapping.
229 		EF_UseDispState			= 0x04000000,	// Use DispState for rendering
230 		EF_ActLikeBridge		= 0x08000000,	// Always allow obkects to pass.
231 		EF_NoDropOff			= 0x10000000,	// Can't drop off under any circumstances
232 		EF_Bright				= 0x20000000,	// Always render full bright
233 		EF_CanJump				= 0x40000000,	// This entity can jump to high places
234 		EF_StepMissile			= 0x80000000,	// Missile can "walk" up steps
235 	};
236 	vuint32			EntityFlags;
237 
238 	int				Health;
239 
240 	// For movement checking.
241 	float			Radius;
242 	float			Height;
243 
244 	// Additional info record for player avatars only.
245 	// Only valid if type == MT_PLAYER
246 	VBasePlayer		*Player;
247 
248 	int				TID;			// thing identifier
249 	VEntity*		TIDHashNext;
250 	VEntity*		TIDHashPrev;
251 
252 	int				Special;		// special
253 	int				Args[5];		// special arguments
254 
255 	int				SoundOriginID;
256 
257 	//  Params
258 	float			Mass;
259 	float			MaxStepHeight;
260 	float			MaxDropoffHeight;
261 	float			Gravity;
262 
263 	//  Water
264 	vuint8			WaterLevel;
265 	vuint8			WaterType;
266 
267 	//   For player sounds.
268 	VName			SoundClass;
269 	VName			SoundGender;
270 
271 	//	Owner entity of inventory item
272 	VEntity*		Owner;
273 
274 	static int FIndex_OnMapSpawn;
275 	static int FIndex_BeginPlay;
276 	static int FIndex_Destroyed;
277 	static int FIndex_Touch;
278 	static int FIndex_BlastedHitLine;
279 	static int FIndex_CheckForPushSpecial;
280 	static int FIndex_ApplyFriction;
281 	static int FIndex_HandleFloorclip;
282 	static int FIndex_CrossSpecialLine;
283 	static int FIndex_SectorChanged;
284 	static int FIndex_RoughCheckThing;
285 	static int FIndex_GiveInventory;
286 	static int FIndex_TakeInventory;
287 	static int FIndex_CheckInventory;
288 	static int FIndex_GetSigilPieces;
289 	static int FIndex_MoveThing;
290 	static int FIndex_GetStateTime;
291 
292 	static void InitFuncIndexes();
293 
294 	//	VObject interface.
295 	void Serialise(VStream&);
296 
297 	//	VThinker interface.
298 	void DestroyThinker();
299 	void AddedToLevel();
300 
301 	void SetTID(int);
302 	void InsertIntoTIDList(int);
303 	void RemoveFromTIDList();
304 
GetTopOwner()305 	VEntity* GetTopOwner()
306 	{
307 		VEntity* Ret = this;
308 		while (Ret->Owner)
309 		{
310 			Ret = Ret->Owner;
311 		}
312 		return Ret;
313 	}
314 
eventOnMapSpawn(mthing_t * mthing)315 	void eventOnMapSpawn(mthing_t* mthing)
316 	{
317 		P_PASS_SELF;
318 		P_PASS_PTR(mthing);
319 		EV_RET_VOID_IDX(FIndex_OnMapSpawn);
320 	}
eventBeginPlay()321 	void eventBeginPlay()
322 	{
323 		P_PASS_SELF;
324 		EV_RET_VOID_IDX(FIndex_BeginPlay);
325 	}
eventDestroyed()326 	void eventDestroyed()
327 	{
328 		P_PASS_SELF;
329 		EV_RET_VOID_IDX(FIndex_Destroyed);
330 	}
eventTouch(VEntity * Other)331 	bool eventTouch(VEntity *Other)
332 	{
333 		P_PASS_SELF;
334 		P_PASS_REF(Other);
335 		EV_RET_BOOL_IDX(FIndex_Touch);
336 	}
eventCheckForPushSpecial(line_t * line,int side)337 	void eventCheckForPushSpecial(line_t* line, int side)
338 	{
339 		P_PASS_SELF;
340 		P_PASS_PTR(line);
341 		P_PASS_INT(side);
342 		EV_RET_VOID_IDX(FIndex_CheckForPushSpecial);
343 	}
eventBlastedHitLine()344 	void eventBlastedHitLine()
345 	{
346 		P_PASS_SELF;
347 		EV_RET_VOID_IDX(FIndex_BlastedHitLine);
348 	}
eventApplyFriction()349 	void eventApplyFriction()
350 	{
351 		P_PASS_SELF;
352 		EV_RET_VOID_IDX(FIndex_ApplyFriction);
353 	}
eventHandleFloorclip()354 	void eventHandleFloorclip()
355 	{
356 		P_PASS_SELF;
357 		EV_RET_VOID_IDX(FIndex_HandleFloorclip);
358 	}
eventCrossSpecialLine(line_t * ld,int side)359 	void eventCrossSpecialLine(line_t *ld, int side)
360 	{
361 		P_PASS_SELF;
362 		P_PASS_PTR(ld);
363 		P_PASS_INT(side);
364 		EV_RET_VOID_IDX(FIndex_CrossSpecialLine);
365 	}
eventSectorChanged(int CrushChange)366 	bool eventSectorChanged(int CrushChange)
367 	{
368 		P_PASS_SELF;
369 		P_PASS_INT(CrushChange);
370 		EV_RET_BOOL_IDX(FIndex_SectorChanged);
371 	}
eventClearInventory()372 	void eventClearInventory()
373 	{
374 		P_PASS_SELF;
375 		EV_RET_VOID(NAME_ClearInventory);
376 	}
eventGiveInventory(VName ItemName,int Amount)377 	void eventGiveInventory(VName ItemName, int Amount)
378 	{
379 		P_PASS_SELF;
380 		P_PASS_NAME(ItemName);
381 		P_PASS_INT(Amount);
382 		EV_RET_VOID_IDX(FIndex_GiveInventory);
383 	}
eventTakeInventory(VName ItemName,int Amount)384 	void eventTakeInventory(VName ItemName, int Amount)
385 	{
386 		P_PASS_SELF;
387 		P_PASS_NAME(ItemName);
388 		P_PASS_INT(Amount);
389 		EV_RET_VOID_IDX(FIndex_TakeInventory);
390 	}
eventCheckInventory(VName ItemName)391 	int eventCheckInventory(VName ItemName)
392 	{
393 		P_PASS_SELF;
394 		P_PASS_NAME(ItemName);
395 		EV_RET_INT_IDX(FIndex_CheckInventory);
396 	}
eventUseInventoryName(VName ItemName)397 	int eventUseInventoryName(VName ItemName)
398 	{
399 		P_PASS_SELF;
400 		P_PASS_NAME(ItemName);
401 		EV_RET_INT(NAME_UseInventoryName);
402 	}
eventGetSigilPieces()403 	int eventGetSigilPieces()
404 	{
405 		P_PASS_SELF;
406 		EV_RET_INT_IDX(FIndex_GetSigilPieces);
407 	}
eventGetArmorPoints()408 	int eventGetArmorPoints()
409 	{
410 		P_PASS_SELF;
411 		EV_RET_INT(NAME_GetArmorPoints);
412 	}
eventCheckNamedWeapon(VName Name)413 	int eventCheckNamedWeapon(VName Name)
414 	{
415 		P_PASS_SELF;
416 		P_PASS_NAME(Name);
417 		EV_RET_INT(NAME_CheckNamedWeapon);
418 	}
eventSetNamedWeapon(VName Name)419 	int eventSetNamedWeapon(VName Name)
420 	{
421 		P_PASS_SELF;
422 		P_PASS_NAME(Name);
423 		EV_RET_INT(NAME_SetNamedWeapon);
424 	}
eventGetAmmoCapacity(VName Name)425 	int eventGetAmmoCapacity(VName Name)
426 	{
427 		P_PASS_SELF;
428 		P_PASS_NAME(Name);
429 		EV_RET_INT(NAME_GetAmmoCapacity);
430 	}
eventSetAmmoCapacity(VName Name,int Amount)431 	void eventSetAmmoCapacity(VName Name, int Amount)
432 	{
433 		P_PASS_SELF;
434 		P_PASS_NAME(Name);
435 		P_PASS_INT(Amount);
436 		EV_RET_VOID(NAME_SetAmmoCapacity);
437 	}
eventMoveThing(TVec Pos,bool Fog)438 	bool eventMoveThing(TVec Pos, bool Fog)
439 	{
440 		P_PASS_SELF;
441 		P_PASS_VEC(Pos);
442 		P_PASS_BOOL(Fog);
443 		EV_RET_BOOL_IDX(FIndex_MoveThing);
444 	}
eventGetStateTime(VState * State,float StateTime)445 	float eventGetStateTime(VState* State, float StateTime)
446 	{
447 		P_PASS_SELF;
448 		P_PASS_PTR(State);
449 		P_PASS_FLOAT(StateTime);
450 		EV_RET_FLOAT_IDX(FIndex_GetStateTime);
451 	}
eventSetActorProperty(int Prop,int IntVal,VStr StrVal)452 	void eventSetActorProperty(int Prop, int IntVal, VStr StrVal)
453 	{
454 		P_PASS_SELF;
455 		P_PASS_INT(Prop);
456 		P_PASS_INT(IntVal);
457 		P_PASS_STR(StrVal);
458 		EV_RET_VOID(NAME_SetActorProperty);
459 	}
eventGetActorProperty(int Prop)460 	int eventGetActorProperty(int Prop)
461 	{
462 		P_PASS_SELF;
463 		P_PASS_INT(Prop);
464 		EV_RET_INT(NAME_GetActorProperty);
465 	}
eventCheckForSectorActions(sector_t * OldSec,bool OldAboveFakeFloor,bool OldAboveFakeCeiling)466 	void eventCheckForSectorActions(sector_t* OldSec, bool OldAboveFakeFloor,
467 		bool OldAboveFakeCeiling)
468 	{
469 		P_PASS_SELF;
470 		P_PASS_PTR(OldSec);
471 		P_PASS_BOOL(OldAboveFakeFloor);
472 		P_PASS_BOOL(OldAboveFakeCeiling);
473 		EV_RET_VOID(NAME_CheckForSectorActions);
474 	}
eventSkyBoxGetAlways()475 	bool eventSkyBoxGetAlways()
476 	{
477 		P_PASS_SELF;
478 		EV_RET_BOOL(NAME_SkyBoxGetAlways);
479 	}
eventSkyBoxGetMate()480 	VEntity* eventSkyBoxGetMate()
481 	{
482 		P_PASS_SELF;
483 		EV_RET_REF(VEntity, NAME_SkyBoxGetMate);
484 	}
eventSkyBoxGetPlaneAlpha()485 	float eventSkyBoxGetPlaneAlpha()
486 	{
487 		P_PASS_SELF;
488 		EV_RET_FLOAT(NAME_SkyBoxGetPlaneAlpha);
489 	}
eventCalcFakeZMovement(TVec & Ret,float DeltaTime)490 	void eventCalcFakeZMovement(TVec& Ret, float DeltaTime)
491 	{
492 		P_PASS_SELF;
493 		P_PASS_PTR(&Ret);
494 		P_PASS_FLOAT(DeltaTime);
495 		EV_RET_VOID(NAME_CalcFakeZMovement);
496 	}
eventClassifyActor()497 	int eventClassifyActor()
498 	{
499 		P_PASS_SELF;
500 		EV_RET_INT(NAME_ClassifyActor);
501 	}
eventMorphActor(VName PlayerClass,VName MonsterClass,float Duration,int Style,VName MorphFlash,VName UnmorphFlash)502 	int eventMorphActor(VName PlayerClass, VName MonsterClass, float Duration,
503 		int Style, VName MorphFlash, VName UnmorphFlash)
504 	{
505 		P_PASS_SELF;
506 		P_PASS_NAME(PlayerClass);
507 		P_PASS_NAME(MonsterClass);
508 		P_PASS_FLOAT(Duration);
509 		P_PASS_INT(Style);
510 		P_PASS_NAME(MorphFlash);
511 		P_PASS_NAME(UnmorphFlash);
512 		EV_RET_INT(NAME_MorphActor);
513 	}
eventUnmorphActor(VEntity * Activator,int Force)514 	int eventUnmorphActor(VEntity* Activator, int Force)
515 	{
516 		P_PASS_SELF;
517 		P_PASS_REF(Activator);
518 		P_PASS_INT(Force);
519 		EV_RET_INT(NAME_UnmorphActor);
520 	}
eventGetViewEntRenderParams(float & OutAlpha,int & OutRenderStyle)521 	void eventGetViewEntRenderParams(float& OutAlpha, int& OutRenderStyle)
522 	{
523 		P_PASS_SELF;
524 		P_PASS_PTR(&OutAlpha);
525 		P_PASS_PTR(&OutRenderStyle);
526 		EV_RET_VOID(NAME_GetViewEntRenderParams);
527 	}
528 
529 	bool SetState(VState*);
530 	void SetInitialState(VState*);
531 	bool AdvanceState(float);
532 	VState* FindState(VName, VName = NAME_None, bool = false);
533 	VState* FindStateEx(const VStr&, bool);
534 	bool HasSpecialStates(VName);
535 	void GetStateEffects(TArray<VLightEffectDef*>&,
536 		TArray<VParticleEffectDef*>&) const;
537 	bool CallStateChain(VEntity*, VState*);
538 
539 	bool CheckWater();
540 	bool CheckPosition(TVec);
541 	bool CheckRelPosition(tmtrace_t&, TVec);
542 	bool TryMove(tmtrace_t&, TVec, bool);
543 	VEntity* TestMobjZ(const TVec&);
544 	void SlideMove(float);
545 	void BounceWall(float, float);
546 	void UpdateVelocity();
547 	TVec FakeZMovement();
548 	VEntity *CheckOnmobj();
549 	bool CheckSides(TVec);
550 	void CheckDropOff(float&, float&);
551 
552 private:
553 	//	World iterator callbacks
554 	bool CheckThing(cptrace_t&, VEntity*);
555 	bool CheckLine(cptrace_t&, line_t*);
556 	bool CheckRelThing(tmtrace_t&, VEntity*);
557 	bool CheckRelLine(tmtrace_t&, line_t*);
558 	void BlockedByLine(line_t*);
559 	void PushLine(const tmtrace_t& tmtrace);
560 	static TVec ClipVelocity(const TVec&, const TVec&, float);
561 	void SlidePathTraverse(float&, line_t*&, float, float, float);
562 
563 	void CreateSecNodeList();
564 
565 	void SetDecorateFlag(const VStr&, bool);
566 
567 public:
568 	void LinkToWorld();
569 	void UnlinkFromWorld();
570 	bool CanSee(VEntity*);
571 
572 	void StartSound(VName, vint32, float, float, bool);
573 	void StartLocalSound(VName, vint32, float, float);
574 	void StopSound(vint32);
575 	void StartSoundSequence(VName, vint32);
576 	void AddSoundSequenceChoice(VName);
577 	void StopSoundSequence();
578 
579 	DECLARE_FUNCTION(SetTID)
580 	DECLARE_FUNCTION(SetState)
581 	DECLARE_FUNCTION(SetInitialState)
582 	DECLARE_FUNCTION(AdvanceState)
583 	DECLARE_FUNCTION(FindState)
584 	DECLARE_FUNCTION(FindStateEx)
585 	DECLARE_FUNCTION(HasSpecialStates)
586 	DECLARE_FUNCTION(GetStateEffects)
587 	DECLARE_FUNCTION(CallStateChain)
588 	DECLARE_FUNCTION(PlaySound)
589 	DECLARE_FUNCTION(StopSound)
590 	DECLARE_FUNCTION(AreSoundsEquivalent)
591 	DECLARE_FUNCTION(IsSoundPresent)
592 	DECLARE_FUNCTION(StartSoundSequence)
593 	DECLARE_FUNCTION(AddSoundSequenceChoice)
594 	DECLARE_FUNCTION(StopSoundSequence)
595 	DECLARE_FUNCTION(CheckWater)
596 	DECLARE_FUNCTION(CheckSides)
597 	DECLARE_FUNCTION(CheckDropOff)
598 	DECLARE_FUNCTION(CheckPosition)
599 	DECLARE_FUNCTION(CheckRelPosition)
600 	DECLARE_FUNCTION(TryMove)
601 	DECLARE_FUNCTION(TryMoveEx)
602 	DECLARE_FUNCTION(TestMobjZ)
603 	DECLARE_FUNCTION(SlideMove)
604 	DECLARE_FUNCTION(BounceWall)
605 	DECLARE_FUNCTION(UpdateVelocity)
606 	DECLARE_FUNCTION(CheckOnmobj)
607 	DECLARE_FUNCTION(LinkToWorld)
608 	DECLARE_FUNCTION(UnlinkFromWorld)
609 	DECLARE_FUNCTION(CanSee)
610 	DECLARE_FUNCTION(RoughBlockSearch)
611 	DECLARE_FUNCTION(SetDecorateFlag)
612 };
613