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