//************************************************************************** //** //** ## ## ## ## ## #### #### ### ### //** ## ## ## ## ## ## ## ## ## ## #### #### //** ## ## ## ## ## ## ## ## ## ## ## ## ## ## //** ## ## ######## ## ## ## ## ## ## ## ### ## //** ### ## ## ### ## ## ## ## ## ## //** # ## ## # #### #### ## ## //** //** $Id: Entity.vc 2609 2007-08-09 23:25:00Z dj_jl $ //** //** Copyright (C) 1999-2006 Jānis Legzdiņš //** //** This program is free software; you can redistribute it and/or //** modify it under the terms of the GNU General Public License //** as published by the Free Software Foundation; either version 2 //** of the License, or (at your option) any later version. //** //** This program is distributed in the hope that it will be useful, //** but WITHOUT ANY WARRANTY; without even the implied warranty of //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //** GNU General Public License for more details. //** //************************************************************************** // // ENTITY DATA // // NOTES: Entity // // Entities are used to tell the refresh where to draw an image, tell the // world simulation when objects are contacted, and tell the sound driver // how to position a sound. // // The refresh uses the snext and sprev links to follow lists of things in // sectors as they are being drawn. The sprite, frame, and angle elements // determine which patch_t is used to draw the sprite if it is visible. // The sprite and frame values are allmost allways set from state_t // structures. The xyz origin point represents a point at the bottom middle // of the sprite (between the feet of a biped). This is the default origin // position for patch_ts grabbed with lumpy.exe. A walking creature will have // its z equal to the floor it is standing on. // // The sound code uses the x,y, and z fields to do stereo positioning of any // sound effited by the Entity. // // The play simulation uses the BlockLinks, x,y,z, radius, height to // determine when mobj_ts are touching each other, touching lines in the map, // or hit by trace lines (gunshots, lines of sight, etc). The Entity->flags // element has various bit flags used by the simulation. // // Every Entity is linked into a single sector based on its origin // coordinates. The subsector_t is found with R_PointInSubsector(x,y), and // the sector_t can be found with subsector->sector. The sector links are // only used by the rendering code, the play simulation does not care about // them at all. // // Any Entity that needs to be acted upon by something else in the play // world (block movement, be shot, etc) will also need to be linked into the // blockmap. If the thing has the MF_NOBLOCK flag set, it will not use the // block links. It can still interact with other things, but only as the // instigator (missiles will run into other things, but nothing can run into // a missile). Each block in the grid is 128*128 units, and knows about every // line_t that it contains a piece of, and every interactable Entity that has // its origin contained. // // A valid Entity is a Entity that has the proper subsector_t filled in for // its xy coordinates and is linked into the sector from which the subsector // was made, or has the MF_NOSECTOR flag set (the subsector_t needs to be // valid even if MF_NOSECTOR is set), and is linked into a blockmap block or // has the MF_NOBLOCKMAP flag set. Links should only be modified by the // P_[Un]SetThingPosition() functions. Do not change the MF_NO? flags while // a thing is valid. // // Any questions? // //************************************************************************** class Entity : Thinker native abstract; // Info for drawing: position. TVec Origin; // Momentums, used to update position. TVec Velocity; TAVec Angles; // orientation readonly state State; float StateTime; // state tic counter //More drawing info. byte SpriteType; // How to draw sprite string FixedModelName; string ModelSkin; byte ModelVersion; float Alpha; int Translation; float FloorClip; // value to use for floor clipping native readonly subsector_t* SubSector; native readonly sector_t* Sector; // Interaction info, by BLOCKMAP. // Links in blocks (if needed). native readonly private Entity BlockMapNext; native readonly private Entity BlockMapPrev; // The closest interval over all contacted Sectors. native float FloorZ; native float CeilingZ; native float DropOffZ; // Closest floor and ceiling, source of floorz and ceilingz native sec_plane_t* Floor; native sec_plane_t* Ceiling; // If == validcount, already checked. int ValidCount; // Flags bool bSolid; // Blocks. bool bHidden; // don't update to clients (invisible but touchable) bool bNoBlockmap; // don't use the BlockLinks (inert but displayable) bool bIsPlayer; // PLayer or player-bot bool bFixedModel; bool bNoGravity; // don't apply gravity every tic bool bNoPassMobj; // Disable z block checking. If on, // this flag will prevent the mobj // from passing over/under other mobjs. bool bColideWithThings; bool bColideWithWorld; bool bCheckLineBlocking; bool bCheckLineBlockMonsters; bool bDropOff; // allow jumps from high places bool bFloat; // allow moves to any height, no gravity bool bFly; // fly mode is active bool bBlasted; // missile will pass through ghosts bool bCantLeaveFloorpic;// stay within a certain floor type bool bFloorClip; // if feet are allowed to be clipped bool bIgnoreCeilingStep;// continue walk without lowering itself bool bIgnoreFloorStep; // continue walk ignoring floor height changes bool bAvoidingDropoff; // used to move monsters away from dropoffs bool bOnMobj; // mobj is resting on top of another mobj bool bCorpse; // don't stop moving halfway off a step bool bFullBright; // make current state full bright native readonly bool bNetLocalPlayer; // Mobj of player currently being updated int Health; // For movement checking. float Radius; float Height; // Additional info record for player avatars only. // Only valid if type == MT_PLAYER BasePlayer Player; int TID; // thing identifier int Special; // special int Args[5]; // special arguments readonly private int NetID; // Params float Mass; float MaxStepHeight; float MaxDropoffHeight; float Gravity; // Water byte WaterLevel; byte WaterType; // For player sounds. name SoundClass; name SoundGender; // Owner entity of inventory item Entity Owner; replication { reliable if (Role == ROLE_Authority) Origin, Angles, FloorClip, State, StateTime, SpriteType, ModelSkin, ModelVersion, Alpha, Translation, bFly, bHidden, bFullBright, bFixedModel, bNetLocalPlayer, NetID; reliable if (Role == ROLE_Authority && bFixedModel) FixedModelName; reliable if (Role == ROLE_Authority && bNetOwner) Owner; } // // Natives // native final bool SetState(state State); native final void SetInitialState(state State); native final bool AdvanceState(float deltaTime); native final state FindState(name StateName); native final void PlaySound(name SoundName, int Channel, optional float Volume, optional float Atenuation); native final void StopSound(int Channel); native final bool AreSoundsEquivalent(name Sound1, name Sound2); native final void StartSoundSequence(name sequence, int ModeNum); native final void AddSoundSequenceChoice(name Choice); native final void StopSoundSequence(); native final bool CheckSides(TVec lsPos); native final bool CheckDropOff(avoiddropoff_t* a); native final bool CheckPosition(TVec Pos); native final bool CheckRelPosition(tmtrace_t* tmtrace, TVec Pos); native final bool TryMove(TVec newPos); native final bool TryMoveEx(tmtrace_t* tmtrace, TVec newPos); native final bool TestMobjZ(); native final void SlideMove(); native final void BounceWall(float overbounce); native final bool CheckWater(); native final void UpdateVelocity(); native final Entity CheckOnmobj(); native final void LinkToWorld(); native final void UnlinkFromWorld(); native final bool CanSee(Entity Other); native final Entity RoughMonsterSearch(int distance); //=========================================================================== // // OnMapSpawn // //=========================================================================== void OnMapSpawn(mthing_t* mthing) { } //========================================================================== // // BeginPlay // //========================================================================== void BeginPlay() { } //========================================================================== // // Destroyed // //========================================================================== void Destroyed() { if (TID) { // Remove from TID list RemoveFromTIDList(); } } //========================================================================== // // Touch // //========================================================================== bool Touch(Entity Other) { return !Other.bSolid; } //========================================================================== // // BlockedByLine // //========================================================================== void BlockedByLine(line_t * ld) { } //========================================================================== // // PushLine // //========================================================================== void PushLine(tmtrace_t* tmtrace) { } //========================================================================== // // HandleFloorclip // //========================================================================== void HandleFloorclip() { } //========================================================================== // // CrossSpecialLine // //========================================================================== void CrossSpecialLine(line_t* ld, int side) { } //========================================================================== // // ApplyFriction // //========================================================================== void ApplyFriction() { } //========================================================================== // // SectorChanged // //========================================================================== bool SectorChanged(int CrushChange) { return true; } //=========================================================================== // // RoughCheckThing // //=========================================================================== bool RoughCheckThing(Entity Other) { return false; } //=========================================================================== // // GiveInventory // //=========================================================================== void GiveInventory(name ItemName, int Amount) { } //=========================================================================== // // TakeInventory // //=========================================================================== void TakeInventory(name ItemName, int Amount) { } //=========================================================================== // // CheckInventory // //=========================================================================== int CheckInventory(name ItemName) { return 0; } //=========================================================================== // // GetSigilPieces // //=========================================================================== int GetSigilPieces() { return 0; } //=========================================================================== // // MoveThing // //=========================================================================== bool MoveThing(TVec Pos, bool Fog) { return false; } //========================================================================== // // GetStateTime // //========================================================================== float GetStateTime(state AState, float AStateTime) { return AStateTime; } //========================================================================== // // SetOrigin // //========================================================================== void SetOrigin(TVec NewOrigin) { Origin = NewOrigin; } //========================================================================== // // InsertIntoTIDList // //========================================================================== void InsertIntoTIDList(int tid) { int i; int index; index = -1; for (i = 0; Level.TIDList[i] != 0; i++) { if (Level.TIDList[i] == -1) { // Found empty slot index = i; break; } } if (index == -1) { // Append required if (i == MAX_TID_COUNT) { Error("P_InsertMobjIntoTIDList: MAX_TID_COUNT exceeded."); } index = i; Level.TIDList[index + 1] = 0; } TID = tid; Level.TIDList[index] = tid; Level.TIDMobj[index] = self; } //========================================================================== // // RemoveFromTIDList // //========================================================================== void RemoveFromTIDList() { int i; for (i = 0; Level.TIDList[i] != 0; i++) { if (Level.TIDMobj[i] == self) { Level.TIDList[i] = -1; Level.TIDMobj[i] = none; TID = 0; return; } } TID = 0; } //========================================================================== // // Activate // //========================================================================== bool Activate() { return false; } //========================================================================== // // Deactivate // //========================================================================== bool Deactivate() { return false; } //========================================================================== // // RemoveThing // //========================================================================== void RemoveThing() { Destroy(); } //========================================================================== // // DistTo // //========================================================================== float DistTo(Entity Other) { return Length(Other.GetCentre() - GetCentre()); } //========================================================================== // // DistTo2 // //========================================================================== float DistTo2(Entity Other) { TVec dir; dir = Other.Origin - Origin; dir.z = 0.0; return Length(dir); } //========================================================================== // // GetCentre // //========================================================================== TVec GetCentre() { return Origin + vector(0.0, 0.0, Height * 0.5 - FloorClip); } defaultproperties { Alpha = 1.0; bColideWithThings = true; bColideWithWorld = true; MaxDropoffHeight = 24.0; Gravity = 1.0; SoundClass = 'player'; SoundGender = 'male'; }