1 /** @file p_object.h World map objects. 2 * 3 * @authors Copyright © 2003-2017 Jaakko Keränen <jaakko.keranen@iki.fi> 4 * @authors Copyright © 2005-2015 Daniel Swanson <danij@dengine.net> 5 * @authors Copyright © 2006 Jamie Jones <jamie_jones_au@yahoo.com.au> 6 * 7 * @par License 8 * GPL: http://www.gnu.org/licenses/gpl.html 9 * 10 * <small>This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by the 12 * Free Software Foundation; either version 2 of the License, or (at your 13 * option) any later version. This program is distributed in the hope that it 14 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 16 * Public License for more details. You should have received a copy of the GNU 17 * General Public License along with this program; if not, see: 18 * http://www.gnu.org/licenses</small> 19 */ 20 21 #ifndef WORLD_P_OBJECT_H 22 #define WORLD_P_OBJECT_H 23 24 #if defined(__JDOOM__) || defined(__JHERETIC__) || defined(__JHEXEN__) 25 # error Attempted to include internal Doomsday p_object.h from a game 26 #endif 27 28 #include <de/aabox.h> 29 #include <de/Record> 30 #include <de/Vector> 31 #include <doomsday/defs/ded.h> 32 #include <doomsday/world/thinker.h> 33 #include <doomsday/world/mobj.h> 34 35 #include "world/bspleaf.h" 36 #include "api_map.h" 37 #include "dd_def.h" 38 #ifdef __CLIENT__ 39 # include "resource/framemodeldef.h" 40 #endif 41 42 namespace world { 43 class Subsector; 44 } 45 class Plane; 46 47 #define MOBJ_SIZE gx.GetInteger(DD_MOBJ_SIZE) 48 49 class MobjThinker : public ThinkerT<mobj_t> 50 { 51 public: ThinkerT(MOBJ_SIZE,alloc)52 MobjThinker(AllocMethod alloc = AllocateStandard) : ThinkerT(MOBJ_SIZE, alloc) {} MobjThinker(mobj_t const & existingToCopy)53 MobjThinker(mobj_t const &existingToCopy) : ThinkerT(existingToCopy, MOBJ_SIZE) {} MobjThinker(mobj_t * existingToTake)54 MobjThinker(mobj_t *existingToTake) : ThinkerT(existingToTake, MOBJ_SIZE) {} 55 zap(mobj_t & mob)56 static void zap(mobj_t &mob) { ThinkerT::zap(mob, MOBJ_SIZE); } 57 }; 58 59 #define DEFAULT_FRICTION FIX2FLT(0xe800) 60 #define NOMOMENTUM_THRESHOLD (0.0001) 61 62 #define IS_BLOCK_LINKED(mo) ((mo)->bNext != 0) 63 64 DENG_EXTERN_C de::dint useSRVO, useSRVOAngle; 65 66 void P_InitUnusedMobjList(); 67 68 /** 69 * To be called to register the commands and variables of this module. 70 */ 71 void Mobj_ConsoleRegister(); 72 73 mobj_t *P_MobjCreate(thinkfunc_t function, de::Vector3d const &origin, angle_t angle, 74 coord_t radius, coord_t height, de::dint ddflags); 75 76 void P_MobjRecycle(mobj_t *mob); 77 78 /** 79 * Returns the map in which the map-object exists. Note that a map-object may exist in a 80 * map while not being @em linked into data structures such as the blockmap and sectors. 81 * To determine whether the map-object is linked, call @ref Mobj_IsLinked(). 82 * 83 * @see Thinker_Map() 84 */ 85 world::Map &Mobj_Map(mobj_t const &mob); 86 87 /** 88 * Returns @c true if the map-object has been linked into the map. The only time this is 89 * not true is if @ref Mobj_SetOrigin() has not yet been called. 90 * 91 * @param mob Map-object. 92 * 93 * @todo Automatically link all new mobjs into the map (making this redundant). 94 */ 95 bool Mobj_IsLinked(mobj_t const &mob); 96 97 /** 98 * Returns a copy of the map-object's origin in map space. 99 */ 100 de::Vector3d Mobj_Origin(mobj_t const &mob); 101 102 /** 103 * Returns the map-object's visual center (i.e., origin plus z-height offset). 104 */ 105 de::Vector3d Mobj_Center(mobj_t &mob); 106 107 /** 108 * Set the origin of the map-object in map space. 109 * 110 * @return @c true if successful, @c false otherwise. The object's position is not changed 111 * if the move fails. 112 * 113 * @note Internal to the engine. 114 */ 115 dd_bool Mobj_SetOrigin(mobj_t *mob, coord_t x, coord_t y, coord_t z); 116 117 /** 118 * Returns the map BSP leaf at the origin of the map-object. Note that the mobj must be 119 * linked in the map (i.e., @ref Mobj_SetOrigin() has been called). 120 * 121 * @param mob Map-object. 122 * 123 * @see Mobj_IsLinked(), Mobj_SetOrigin() 124 */ 125 world::BspLeaf &Mobj_BspLeafAtOrigin(mobj_t const &mob); 126 127 /** 128 * Returns @c true if the BSP leaf at the map-object's origin is known (i.e., it has been 129 * linked into the map by calling @ref Mobj_SetOrigin() and has a convex geometry). 130 * 131 * @param mob Map-object. 132 */ 133 bool Mobj_HasSubsector(mobj_t const &mob); 134 135 /** 136 * Returns the subsector in which the map-object currently resides. 137 * 138 * @param mob Map-object. 139 * 140 * @see Mobj_HasSubsector() 141 */ 142 world::Subsector &Mobj_Subsector(mobj_t const &mob); 143 144 /** 145 * Returns a pointer to subsector in which the mobj currently resides, or @c nullptr 146 * if not linked or the BSP leaf at the origin has no convex geometry. 147 * 148 * @param mob Map-object. 149 * 150 * @see Mobj_HasSubsector() 151 */ 152 world::Subsector *Mobj_SubsectorPtr(mobj_t const &mob); 153 154 /** 155 * Creates a new map-object triggered particle generator based on the given definition. 156 * The generator is added to the list of active ptcgens. 157 */ 158 void Mobj_SpawnParticleGen(mobj_t *source, ded_ptcgen_t const *def); 159 160 #ifdef __CLIENT__ 161 162 /** 163 * Determines whether the Z origin of the mobj lies above the visual ceiling, or below the 164 * visual floor plane of the BSP leaf at the origin. This can be used to determine whether 165 * this origin should be adjusted with respect to smoothed plane movement. 166 */ 167 dd_bool Mobj_OriginBehindVisPlane(mobj_t *mob); 168 169 /** 170 * To be called when Lumobjs are disabled to perform necessary bookkeeping. 171 */ 172 void Mobj_UnlinkLumobjs(mobj_t *mob); 173 174 /** 175 * Generates Lumobjs for the map-object. 176 * @note: This is called each frame for each luminous object! 177 */ 178 void Mobj_GenerateLumobjs(mobj_t *mob); 179 180 void Mobj_AnimateHaloOcclussion(mobj_t &mob); 181 182 /** 183 * Calculate the strength of the shadow this map-object should cast. 184 * 185 * @note Implemented using a greatly simplified version of the lighting equation; 186 * no light diminishing or light range compression. 187 */ 188 de::dfloat Mobj_ShadowStrength(mobj_t const &mob); 189 190 /** 191 * Determines which of the available sprites is in effect for the current map-object state 192 * and frame. May return @c nullptr if the state and/or frame is not valid. 193 */ 194 de::Record const *Mobj_SpritePtr(mobj_t const &mob); 195 196 /** 197 * Determines which of the available model definitions (if any), are in effect for the 198 * current map-object state and frame. (Interlinks are resolved). 199 * 200 * @param nextModef If non-zero the model definition for the @em next frame is written here. 201 * @param interp If non-zero and both model definitions are found the current interpolation 202 * point between the two is written here. 203 * 204 * @return Active model definition for the current frame (if any). 205 */ 206 FrameModelDef *Mobj_ModelDef(mobj_t const &mob, FrameModelDef **nextModef = nullptr, 207 de::dfloat *interp = nullptr); 208 209 /** 210 * Calculates the shadow radius of the map-object. Falls back to Mobj_VisualRadius(). 211 * 212 * @param mob Map-object. 213 * 214 * @return Radius for shadow. 215 */ 216 coord_t Mobj_ShadowRadius(mobj_t const &mob); 217 218 #endif // __CLIENT__ 219 220 coord_t Mobj_ApproxPointDistance(mobj_t const *mob, coord_t const *point); 221 222 /** 223 * Returns @c true if the map-object is physically inside (and @em presently linked to) 224 * some Sector of the owning Map. 225 */ 226 bool Mobj_IsSectorLinked(mobj_t const &mob); 227 228 /** 229 * Returns the current "float bob" offset (if enabled); otherwise @c 0. 230 */ 231 coord_t Mobj_BobOffset(mobj_t const &mob); 232 233 de::dfloat Mobj_Alpha(mobj_t const &mob); 234 235 /** 236 * Returns the physical radius of the mobj. 237 * 238 * @param mob Map-object. 239 * 240 * @see Mobj_VisualRadius() 241 */ 242 coord_t Mobj_Radius(mobj_t const &mob); 243 244 /** 245 * Returns the radius of the mobj as it would visually appear to be, according 246 * to the current visualization (either a sprite or a 3D model). 247 * 248 * @param mob Map-object. 249 * 250 * @see Mobj_Radius() 251 */ 252 coord_t Mobj_VisualRadius(mobj_t const &mob); 253 254 /** 255 * Returns an axis-aligned bounding box for the mobj in map space, centered 256 * on the origin with dimensions equal to @code radius * 2 @endcode. 257 * 258 * @param mob Map-object. 259 * 260 * @see Mobj_Radius() 261 */ 262 AABoxd Mobj_Bounds(mobj_t const &mob); 263 264 #endif // WORLD_P_OBJECT_H 265