1//**************************************************************************
2//**
3//**    ##   ##    ##    ##   ##   ####     ####   ###     ###
4//**    ##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5//**     ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6//**     ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7//**      ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8//**       #    ##    ##    #      ####     ####   ##       ##
9//**
10//**    $Id: Entity.vc 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: Entity
29//
30//  Entities 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 snext and sprev 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 state_t
38// structures. The xyz origin point represents a point at the bottom middle
39// of the sprite (between the feet of a biped). This is the default origin
40// position for patch_ts grabbed with lumpy.exe. A walking creature will have
41// its z equal to the floor it is standing on.
42//
43//  The sound code uses the x,y, and z fields to do stereo positioning of any
44// sound effited by the Entity.
45//
46//  The play simulation uses the BlockLinks, x,y,z, radius, height to
47// determine when mobj_ts are touching each other, touching lines in the map,
48// or hit by trace lines (gunshots, lines of sight, etc). The Entity->flags
49// element has various bit flags used by the simulation.
50//
51//  Every Entity is linked into a single sector based on its origin
52// coordinates. The subsector_t is found with R_PointInSubsector(x,y), and
53// the sector_t can be found with subsector->sector. The sector links are
54// only used by the rendering code, the play simulation does not care about
55// them at all.
56//
57//  Any Entity that needs to be acted upon by something else in the play
58// world (block movement, be shot, etc) will also need to be linked into the
59// blockmap. If the thing has the MF_NOBLOCK flag set, it will not use the
60// block links. It can still interact with other things, but only as the
61// instigator (missiles will run into other things, but nothing can run into
62// a missile). Each block in the grid is 128*128 units, and knows about every
63// line_t that it contains a piece of, and every interactable Entity that has
64// its origin contained.
65//
66//  A valid Entity is a Entity that has the proper subsector_t filled in for
67// its xy coordinates and is linked into the sector from which the subsector
68// was made, or has the MF_NOSECTOR flag set (the subsector_t needs to be
69// valid even if MF_NOSECTOR is set), and is linked into a blockmap block or
70// has the MF_NOBLOCKMAP flag set. Links should only be modified by the
71// P_[Un]SetThingPosition() functions. Do not change the MF_NO? flags while
72// a thing is valid.
73//
74//  Any questions?
75//
76//**************************************************************************
77
78class Entity : Thinker
79	native
80	abstract;
81
82enum
83{
84	STYLE_None,					// Do not draw
85	STYLE_Normal,				// Normal; just copy the image to the screen
86	STYLE_Fuzzy,				// Draw silhouette using "fuzz" effect
87	STYLE_SoulTrans,			// Draw translucent with amount in r_transsouls
88	STYLE_OptFuzzy,				// Draw as fuzzy or translucent, based on user preference
89	STYLE_Translucent = 64,		// Draw translucent
90	STYLE_Add					// Draw additive
91};
92
93//	Colour tralslation types.
94enum
95{
96	//	No translation.
97	TRANSL_None,
98	//	Game's standard translations.
99	TRANSL_Standard,
100	//	Per-player translations.
101	TRANSL_Player,
102	//	ACS translations.
103	TRANSL_Level,
104	//	Translations of dead players.
105	TRANSL_BodyQueue,
106	//	Translations defined in DECORATE.
107	TRANSL_Decorate,
108	//	Blood translations, for blood colour
109	TRANSL_Blood,
110
111	TRANSL_Max
112};
113
114const int TRANSL_TYPE_SHIFT = 16;
115
116//	Flags for A_LookEx method
117enum
118{
119	LOF_NOSIGHTCHECK = 1,
120	LOF_NOSOUNDCHECK = 2,
121	LOF_DONTCHASEGOAL = 4,
122	LOF_NOSEESOUND = 8,
123	LOF_FULLVOLSEESOUND = 16
124};
125
126struct LightEffectDef
127{
128	name				Name;
129	byte				Type;
130	int					Colour;
131	float				Radius;
132	float				Radius2;
133	float				MinLight;
134	TVec				Offset;
135	float				Chance;
136	float				Interval;
137	float				Scale;
138};
139
140struct ParticleEffectDef
141{
142	name				Name;
143	byte				Type;
144	byte				Type2;
145	int					Colour;
146	TVec				Offset;
147	int					Count;
148	float				OrgRnd;
149	TVec				Velocity;
150	float				VelRnd;
151	float				Accel;
152	float				Grav;
153	float				Duration;
154	float				Ramp;
155};
156
157struct DropItemInfo
158{
159	class<Entity>		Type;
160	name				TypeName;
161	int					Amount;
162	float				Chance;
163};
164
165struct DamageFactor
166{
167	name				DamageType;
168	float				Factor;
169};
170
171struct PainChanceInfo
172{
173	name				DamageType;
174	float				Chance;
175};
176
177struct tmtrace_t
178{
179	Entity			StepThing;
180	TVec			End;
181	float			BBox[4];
182	float			FloorZ;
183	float			CeilingZ;
184	float			DropOffZ;
185	sec_plane_t*	Floor;
186	sec_plane_t*	Ceiling;
187
188	bool			bFloatOk;	// if true, move would be ok if
189								// within tmtrace.FloorZ - tmtrace.CeilingZ
190
191	// keep track of the line that lowers the ceiling,
192	// so missiles don't explode against sky hack walls
193	line_t*			CeilingLine;
194	// also keep track of the blocking line, for checking
195	// against doortracks
196	line_t*			BlockingLine;
197
198	// keep track of special lines as they are hit,
199	// but don't process them until the move is proven valid
200	array<line_t*>	SpecHit;
201
202	Entity			BlockingMobj;
203};
204
205// Info for drawing: position.
206TVec			Origin;
207
208// Momentums, used to update position.
209TVec			Velocity;
210
211TAVec			Angles;				// orientation
212
213readonly state	State;
214readonly state	DispState;
215float			StateTime;			// state tic counter
216
217//More drawing info.
218byte			SpriteType;				//  How to draw sprite
219name			FixedSpriteName;
220string			FixedModelName;
221byte			ModelVersion;
222
223byte			RenderStyle;
224float			Alpha;
225int				Translation;
226
227float			FloorClip;	// value to use for floor clipping
228
229//	Scaling.
230float			ScaleX;
231float			ScaleY;
232
233native readonly subsector_t*	SubSector;
234native readonly sector_t*		Sector;
235
236// Interaction info, by BLOCKMAP.
237// Links in blocks (if needed).
238native readonly private Entity	BlockMapNext;
239native readonly private Entity	BlockMapPrev;
240
241// Links in sector (if needed).
242native readonly Entity			SNext;
243native readonly Entity			SPrev;
244
245native readonly msecnode_t*		TouchingSectorList;
246
247// The closest interval over all contacted Sectors.
248native float	FloorZ;
249native float	CeilingZ;
250native float	DropOffZ;
251
252//  Closest floor and ceiling, source of floorz and ceilingz
253native sec_plane_t*	Floor;
254native sec_plane_t*	Ceiling;
255
256// If == validcount, already checked.
257int				ValidCount;
258
259//	Flags
260bool bSolid;			// Blocks.
261bool bNoSector;			// don't use the sector links (invisible but touchable)
262bool bNoBlockmap;		// don't use the BlockLinks (inert but displayable)
263bool bIsPlayer;			// PLayer or player-bot
264bool bFixedModel;
265
266bool bNoGravity;		// don't apply gravity every tic
267bool bPassMobj;			// Enable z block checking.  If on,
268						// this flag will allow the mobj
269						// to pass over/under other mobjs.
270bool bColideWithThings;
271bool bColideWithWorld;
272bool bCheckLineBlocking;
273bool bCheckLineBlockMonsters;
274bool bDropOff;			// allow jumps from high places
275bool bFloat;			// allow moves to any height, no gravity
276bool bFly;				// fly mode is active
277bool bBlasted;			// missile will pass through ghosts
278bool bCantLeaveFloorpic; // stay within a certain floor type
279bool bFloorClip;		// if feet are allowed to be clipped
280bool bIgnoreCeilingStep; // continue walk without lowering itself
281bool bIgnoreFloorStep;	// continue walk ignoring floor height changes
282bool bAvoidingDropoff;	// used to move monsters away from dropoffs
283bool bOnMobj;			// mobj is resting on top of another mobj
284bool bCorpse;			// don't stop moving halfway off a step
285bool bFullBright;		// make current state full bright
286bool bInvisible;		// Don't draw this actor
287bool bMissile;			// don't hit same species, explode on block
288bool bDontOverlap;		// Prevent some things from overlapping.
289readonly bool bUseDispState;	// Use DispState for rendering
290bool bActLikeBridge;	// Always allow obkects to pass.
291bool bNoDropOff;		// Can't drop off under any circumstances
292bool bBright;			// Always render full bright
293bool bCanJump;			// A dedicated flag instead of the BOUNCES+FLOAT+sentient as in MBF
294bool bStepMissile;		// Missile can "walk" up steps
295
296int				Health;
297
298// For movement checking.
299float			Radius;
300float			Height;
301
302// Additional info record for player avatars only.
303// Only valid if type == MT_PLAYER
304BasePlayer		Player;
305
306readonly int	TID;		// thing identifier
307readonly private Entity	TIDHashNext;
308readonly private Entity	TIDHashPrev;
309
310int				Special;	// special
311int				Args[5];	// special arguments
312
313readonly private int	SoundOriginID;
314
315//  Params
316float			Mass;
317float			MaxStepHeight;
318float			MaxDropoffHeight;
319float			Gravity;
320
321//  Water
322byte			WaterLevel;
323byte			WaterType;
324
325//   For player sounds.
326name			SoundClass;
327name			SoundGender;
328
329	//	Owner entity of inventory item
330Entity			Owner;
331
332replication
333{
334	reliable if (Role == ROLE_Authority)
335		Origin, Angles, FloorClip, State, StateTime, SpriteType,
336		FixedSpriteName, ModelVersion, RenderStyle, Alpha, Translation,
337		ScaleX, ScaleY, bFly, bNoSector, bInvisible, bFullBright, bFixedModel,
338		SoundOriginID, bUseDispState, bBright;
339
340	reliable if (Role == ROLE_Authority && bUseDispState)
341		DispState;
342
343	reliable if (Role == ROLE_Authority && bFixedModel)
344		FixedModelName;
345
346	reliable if (Role == ROLE_Authority && bNetOwner)
347		Owner;
348}
349
350//
351//	Natives
352//
353
354native final void SetTID(int tid);
355
356native final bool SetState(state State);
357native final void SetInitialState(state State);
358native final bool AdvanceState(float deltaTime);
359native final state FindState(name StateName, optional name SubLabel,
360	optional bool Exact);
361native final state FindStateEx(string StateName, optional bool Exact);
362native final state HasSpecialStates(name StateName);
363native final void GetStateEffects(out array<LightEffectDef*> Lights,
364	out array<ParticleEffectDef*> Lights);
365native final bool CallStateChain(Entity Actor, state State);
366
367native final void PlaySound(name SoundName, int Channel, optional float Volume,
368	optional float Atenuation, optional bool Loop);
369native final void StopSound(int Channel);
370native final bool AreSoundsEquivalent(name Sound1, name Sound2);
371native final bool IsSoundPresent(name Sound);
372
373native final void StartSoundSequence(name sequence, int ModeNum);
374native final void AddSoundSequenceChoice(name Choice);
375native final void StopSoundSequence();
376
377native final bool CheckSides(TVec lsPos);
378native final void CheckDropOff(out float DeltaX, out float DeltaY);
379native final bool CheckPosition(TVec Pos);
380native final bool CheckRelPosition(tmtrace_t* tmtrace, TVec Pos);
381native final bool TryMove(TVec newPos, bool AllowDropOff);
382native final bool TryMoveEx(tmtrace_t* tmtrace, TVec newPos, bool AllowDropOff);
383native final bool TestMobjZ();
384
385native final void SlideMove(float StepVelScale);
386native final void BounceWall(float overbounce, float bouncefactor);
387
388native final bool CheckWater();
389
390native final void UpdateVelocity();
391
392native final Entity CheckOnmobj();
393
394native final void LinkToWorld();
395native final void UnlinkFromWorld();
396
397native final bool CanSee(Entity Other);
398
399native final iterator RoughBlockSearch(out Entity EntPtr, int Distance);
400
401native final void SetDecorateFlag(string Name, bool Value);
402
403//===========================================================================
404//
405//  OnMapSpawn
406//
407//===========================================================================
408
409void OnMapSpawn(mthing_t* mthing)
410{
411}
412
413//==========================================================================
414//
415//	BeginPlay
416//
417//==========================================================================
418
419void BeginPlay()
420{
421}
422
423//==========================================================================
424//
425//	Destroyed
426//
427//==========================================================================
428
429void Destroyed()
430{
431}
432
433//==========================================================================
434//
435//	Touch
436//
437//==========================================================================
438
439bool Touch(Entity Other)
440{
441	return !Other.bSolid;
442}
443
444//===========================================================================
445//
446//	CheckForPushSpecial
447//
448//===========================================================================
449
450void CheckForPushSpecial(line_t* line, int side)
451{
452}
453
454//==========================================================================
455//
456//	BlastedHitLine
457//
458//==========================================================================
459
460void BlastedHitLine()
461{
462}
463
464//==========================================================================
465//
466//	PushLine
467//
468//==========================================================================
469
470void PushLine(tmtrace_t* tmtrace)
471{
472}
473
474//==========================================================================
475//
476//	HandleFloorclip
477//
478//==========================================================================
479
480void HandleFloorclip()
481{
482}
483
484//==========================================================================
485//
486//	CrossSpecialLine
487//
488//==========================================================================
489
490void CrossSpecialLine(line_t* ld, int side)
491{
492}
493
494//==========================================================================
495//
496//	ApplyFriction
497//
498//==========================================================================
499
500void ApplyFriction()
501{
502}
503
504//==========================================================================
505//
506//	SectorChanged
507//
508//==========================================================================
509
510bool SectorChanged(int CrushChange)
511{
512	return true;
513}
514
515//===========================================================================
516//
517//  ClearInventory
518//
519//===========================================================================
520
521void ClearInventory()
522{
523}
524
525//===========================================================================
526//
527//  GiveInventory
528//
529//===========================================================================
530
531void GiveInventory(name ItemName, int Amount)
532{
533}
534
535//===========================================================================
536//
537//  TakeInventory
538//
539//===========================================================================
540
541void TakeInventory(name ItemName, int Amount)
542{
543}
544
545//===========================================================================
546//
547//  CheckInventory
548//
549//===========================================================================
550
551int CheckInventory(name ItemName)
552{
553	return 0;
554}
555
556//===========================================================================
557//
558//  UseInventoryName
559//
560//===========================================================================
561
562int UseInventoryName(name ItemName)
563{
564	return 0;
565}
566
567//===========================================================================
568//
569//  GetSigilPieces
570//
571//===========================================================================
572
573int GetSigilPieces()
574{
575	return 0;
576}
577
578//===========================================================================
579//
580//  GetArmorPoints
581//
582//===========================================================================
583
584int GetArmorPoints()
585{
586	return 0;
587}
588
589//===========================================================================
590//
591//  CheckNamedWeapon
592//
593//===========================================================================
594
595int CheckNamedWeapon(name Name)
596{
597	return 0;
598}
599
600//===========================================================================
601//
602//  SetNamedWeapon
603//
604//===========================================================================
605
606int SetNamedWeapon(name Name)
607{
608	return 0;
609}
610
611//===========================================================================
612//
613//  GetAmmoCapacity
614//
615//===========================================================================
616
617int GetAmmoCapacity(name Name)
618{
619	return 0;
620}
621
622//===========================================================================
623//
624//  SetAmmoCapacity
625//
626//===========================================================================
627
628void SetAmmoCapacity(name Name, int Amount)
629{
630}
631
632//===========================================================================
633//
634//  MoveThing
635//
636//===========================================================================
637
638bool MoveThing(TVec Pos, bool Fog)
639{
640	return false;
641}
642
643//==========================================================================
644//
645//	GetStateTime
646//
647//==========================================================================
648
649float GetStateTime(state AState, float AStateTime)
650{
651	return AStateTime;
652}
653
654//==========================================================================
655//
656//	SetActorProperty
657//
658//==========================================================================
659
660void SetActorProperty(int Prop, int IntVal, string StrVal)
661{
662}
663
664//==========================================================================
665//
666//	GetActorProperty
667//
668//==========================================================================
669
670int GetActorProperty(int Prop)
671{
672	return 0;
673}
674
675//==========================================================================
676//
677//	CheckForSectorActions
678//
679//==========================================================================
680
681void CheckForSectorActions(sector_t* OldSec, bool OldAboveFakeFloor,
682	bool OldAboveFakeCeiling)
683{
684}
685
686//==========================================================================
687//
688//	SkyBoxGetAlways
689//
690//==========================================================================
691
692bool SkyBoxGetAlways()
693{
694	return false;
695}
696
697//==========================================================================
698//
699//	SkyBoxGetMate
700//
701//==========================================================================
702
703Entity SkyBoxGetMate()
704{
705	return none;
706}
707
708//==========================================================================
709//
710//	SkyBoxGetPlaneAlpha
711//
712//==========================================================================
713
714float SkyBoxGetPlaneAlpha()
715{
716	return 0.0;
717}
718
719//==========================================================================
720//
721//	ClassifyActor
722//
723//==========================================================================
724
725int ClassifyActor()
726{
727	return 0;
728}
729
730//==========================================================================
731//
732//	MorphActor
733//
734//==========================================================================
735
736int MorphActor(name PlayerClass, name MonsterClass, float Duration,
737	int Style, name MorphFlash, name UnmorphFlash)
738{
739	return 0;
740}
741
742//==========================================================================
743//
744//	UnmorphActor
745//
746//==========================================================================
747
748int UnmorphActor(Entity Activator, int Force)
749{
750	return 0;
751}
752
753//==========================================================================
754//
755//	GetViewEntRenderParams
756//
757//==========================================================================
758
759void GetViewEntRenderParams(out float OutAlpha, out int OutRenderStyle)
760{
761}
762
763//==========================================================================
764//
765//	CalcFakeZMovement
766//
767//==========================================================================
768
769void CalcFakeZMovement(out TVec Ret, float DeltaTime)
770{
771}
772
773//==========================================================================
774//
775//	SetOrigin
776//
777//==========================================================================
778
779final void SetOrigin(TVec NewOrigin)
780{
781	UnlinkFromWorld();
782	Origin = NewOrigin;
783	LinkToWorld();
784}
785
786//==========================================================================
787//
788//	RemoveThing
789//
790//==========================================================================
791
792void RemoveThing()
793{
794	Destroy();
795}
796
797//==========================================================================
798//
799//  DistTo
800//
801//==========================================================================
802
803final float DistTo(Entity Other)
804{
805	return Length(Other.GetCentre() - GetCentre());
806}
807
808//==========================================================================
809//
810//  DistTo2
811//
812//==========================================================================
813
814final float DistTo2(Entity Other)
815{
816	TVec dir;
817
818	dir = Other.Origin - Origin;
819	dir.z = 0.0;
820	return Length(dir);
821}
822
823//==========================================================================
824//
825//	GetCentre
826//
827//==========================================================================
828
829final TVec GetCentre()
830{
831	return Origin + vector(0.0, 0.0, Height * 0.5 - FloorClip);
832}
833
834defaultproperties
835{
836	RenderStyle = STYLE_Normal;
837	Alpha = 1.0;
838	ScaleX = 1.0;
839	ScaleY = 1.0;
840	bColideWithThings = true;
841	bColideWithWorld = true;
842	MaxDropoffHeight = 24.0;
843	Gravity = 1.0;
844	SoundClass = 'player';
845	SoundGender = 'male';
846}
847