2016-01-10 16:52:41 +00:00
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// DESCRIPTION:
// Map Objects, MObj, definition and handling.
//
//-----------------------------------------------------------------------------
# ifndef __P_MOBJ_H__
# define __P_MOBJ_H__
// Basics.
2016-03-19 23:54:18 +00:00
# include "templates.h"
2016-01-10 16:52:41 +00:00
// We need the thinker_t stuff.
# include "dthinker.h"
// States are tied to finite states are tied to animation frames.
# include "info.h"
# include "doomdef.h"
# include "textures/textures.h"
# include "r_data/renderstyle.h"
# include "s_sound.h"
# include "memarena.h"
# include "g_level.h"
# include "tflags.h"
2016-02-19 13:08:41 +00:00
# include "portal.h"
2016-01-10 16:52:41 +00:00
struct subsector_t ;
2016-02-04 21:15:29 +00:00
class PClassAmmo ;
2016-02-15 01:14:34 +00:00
struct FBlockNode ;
2016-02-16 11:51:10 +00:00
struct FPortalGroupArray ;
2016-02-04 21:15:29 +00:00
2016-01-10 16:52:41 +00:00
//
// NOTES: AActor
//
// Actors 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 next and prev 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 almost always set
// from state_t structures.
// The statescr.exe utility generates the states.h and states.c
// files that contain the sprite/frame numbers from the
// statescr.txt source file.
// 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 sometimes z fields
// to do stereo positioning of any sound emitted by the actor.
//
// The play simulation uses the blocklinks, x,y,z, radius, height
// to determine when AActors are touching each other,
// touching lines in the map, or hit by trace lines (gunshots,
// lines of sight, etc).
// The AActor->flags element has various bit flags
// used by the simulation.
//
// Every actor 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 actor 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 actor that has its origin contained.
//
// A valid actor is an actor 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?
//
2016-09-19 01:36:51 +00:00
2016-01-10 16:52:41 +00:00
// --- mobj.flags ---
enum ActorFlag
{
MF_SPECIAL = 0x00000001 , // call P_SpecialThing when touched
MF_SOLID = 0x00000002 ,
MF_SHOOTABLE = 0x00000004 ,
MF_NOSECTOR = 0x00000008 , // don't use the sector links
// (invisible but touchable)
MF_NOBLOCKMAP = 0x00000010 , // don't use the blocklinks
// (inert but displayable)
MF_AMBUSH = 0x00000020 , // not activated by sound; deaf monster
MF_JUSTHIT = 0x00000040 , // try to attack right back
MF_JUSTATTACKED = 0x00000080 , // take at least one step before attacking
MF_SPAWNCEILING = 0x00000100 , // hang from ceiling instead of floor
MF_NOGRAVITY = 0x00000200 , // don't apply gravity every tic
// movement flags
MF_DROPOFF = 0x00000400 , // allow jumps from high places
MF_PICKUP = 0x00000800 , // for players to pick up items
MF_NOCLIP = 0x00001000 , // player cheat
MF_INCHASE = 0x00002000 , // [RH] used by A_Chase and A_Look to avoid recursion
MF_FLOAT = 0x00004000 , // allow moves to any height, no gravity
MF_TELEPORT = 0x00008000 , // don't cross lines or look at heights
MF_MISSILE = 0x00010000 , // don't hit same species, explode on block
MF_DROPPED = 0x00020000 , // dropped by a demon, not level spawned
MF_SHADOW = 0x00040000 , // actor is hard for monsters to see
MF_NOBLOOD = 0x00080000 , // don't bleed when shot (use puff)
MF_CORPSE = 0x00100000 , // don't stop moving halfway off a step
MF_INFLOAT = 0x00200000 , // floating to a height for a move, don't
// auto float to target's height
MF_INBOUNCE = 0x00200000 , // used by Heretic bouncing missiles
MF_COUNTKILL = 0x00400000 , // count towards intermission kill total
MF_COUNTITEM = 0x00800000 , // count towards intermission item total
MF_SKULLFLY = 0x01000000 , // skull in flight
MF_NOTDMATCH = 0x02000000 , // don't spawn in death match (key cards)
MF_SPAWNSOUNDSOURCE = 0x04000000 , // Plays missile's see sound at spawning object.
MF_FRIENDLY = 0x08000000 , // [RH] Friendly monsters for Strife (and MBF)
MF_UNMORPHED = 0x10000000 , // [RH] Actor is the unmorphed version of something else
MF_NOLIFTDROP = 0x20000000 , // [RH] Used with MF_NOGRAVITY to avoid dropping with lifts
MF_STEALTH = 0x40000000 , // [RH] Andy Baker's stealth monsters
MF_ICECORPSE = 0x80000000 , // a frozen corpse (for blasting) [RH] was 0x800000
// --- dummies for unknown/unimplemented Strife flags ---
MF_STRIFEx8000000 = 0 , // seems related to MF_SHADOW
} ;
// --- mobj.flags2 ---
enum ActorFlag2
{
MF2_DONTREFLECT = 0x00000001 , // this projectile cannot be reflected
MF2_WINDTHRUST = 0x00000002 , // gets pushed around by the wind specials
MF2_DONTSEEKINVISIBLE = 0x00000004 , // For seeker missiles: Don't home in on invisible/shadow targets
MF2_BLASTED = 0x00000008 , // actor will temporarily take damage from impact
MF2_FLY = 0x00000010 , // fly mode is active
MF2_FLOORCLIP = 0x00000020 , // if feet are allowed to be clipped
MF2_SPAWNFLOAT = 0x00000040 , // spawn random float z
MF2_NOTELEPORT = 0x00000080 , // does not teleport
MF2_RIP = 0x00000100 , // missile rips through solid targets
MF2_PUSHABLE = 0x00000200 , // can be pushed by other moving actors
MF2_SLIDE = 0x00000400 , // slides against walls
MF2_ONMOBJ = 0x00000800 , // actor is resting on top of another actor
MF2_PASSMOBJ = 0x00001000 , // Enable z block checking. If on,
// this flag will allow the actor to
// pass over/under other actors.
MF2_CANNOTPUSH = 0x00002000 , // cannot push other pushable mobjs
MF2_THRUGHOST = 0x00004000 , // missile will pass through ghosts [RH] was 8
MF2_BOSS = 0x00008000 , // mobj is a major boss
MF2_DONTTRANSLATE = 0x00010000 , // Don't apply palette translations
MF2_NODMGTHRUST = 0x00020000 , // does not thrust target when damaging
MF2_TELESTOMP = 0x00040000 , // mobj can stomp another
MF2_FLOATBOB = 0x00080000 , // use float bobbing z movement
MF2_THRUACTORS = 0x00100000 , // performs no actor<->actor collision checks
MF2_IMPACT = 0x00200000 , // an MF_MISSILE mobj can activate SPAC_IMPACT
MF2_PUSHWALL = 0x00400000 , // mobj can push walls
MF2_MCROSS = 0x00800000 , // can activate monster cross lines
MF2_PCROSS = 0x01000000 , // can activate projectile cross lines
MF2_CANTLEAVEFLOORPIC = 0x02000000 , // stay within a certain floor type
MF2_NONSHOOTABLE = 0x04000000 , // mobj is totally non-shootable,
// but still considered solid
MF2_INVULNERABLE = 0x08000000 , // mobj is invulnerable
MF2_DORMANT = 0x10000000 , // thing is dormant
MF2_ARGSDEFINED = 0x20000000 , // Internal flag used by DECORATE to signal that the
// args should not be taken from the mapthing definition
MF2_SEEKERMISSILE = 0x40000000 , // is a seeker (for reflection)
MF2_REFLECTIVE = 0x80000000 , // reflects missiles
} ;
// --- mobj.flags3 ---
enum ActorFlag3
{
MF3_FLOORHUGGER = 0x00000001 , // Missile stays on floor
MF3_CEILINGHUGGER = 0x00000002 , // Missile stays on ceiling
MF3_NORADIUSDMG = 0x00000004 , // Actor does not take radius damage
MF3_GHOST = 0x00000008 , // Actor is a ghost
MF3_ALWAYSPUFF = 0x00000010 , // Puff always appears, even when hit nothing
MF3_SPECIALFLOORCLIP = 0x00000020 , // Actor uses floorclip for special effect (e.g. Wraith)
MF3_DONTSPLASH = 0x00000040 , // Thing doesn't make a splash
MF3_NOSIGHTCHECK = 0x00000080 , // Go after first acceptable target without checking sight
MF3_DONTOVERLAP = 0x00000100 , // Don't pass over/under other things with this bit set
MF3_DONTMORPH = 0x00000200 , // Immune to arti_egg
MF3_DONTSQUASH = 0x00000400 , // Death ball can't squash this actor
MF3_EXPLOCOUNT = 0x00000800 , // Don't explode until special2 counts to special1
MF3_FULLVOLACTIVE = 0x00001000 , // Active sound is played at full volume
MF3_ISMONSTER = 0x00002000 , // Actor is a monster
MF3_SKYEXPLODE = 0x00004000 , // Explode missile when hitting sky
MF3_STAYMORPHED = 0x00008000 , // Monster cannot unmorph
MF3_DONTBLAST = 0x00010000 , // Actor cannot be pushed by blasting
MF3_CANBLAST = 0x00020000 , // Actor is not a monster but can be blasted
MF3_NOTARGET = 0x00040000 , // This actor not targetted when it hurts something else
MF3_DONTGIB = 0x00080000 , // Don't gib this corpse
MF3_NOBLOCKMONST = 0x00100000 , // Can cross ML_BLOCKMONSTERS lines
MF3_CRASHED = 0x00200000 , // Actor entered its crash state
MF3_FULLVOLDEATH = 0x00400000 , // DeathSound is played full volume (for missiles)
MF3_AVOIDMELEE = 0x00800000 , // Avoids melee attacks (same as MBF's monster_backing but must be explicitly set)
MF3_SCREENSEEKER = 0x01000000 , // Fails the IsOkayToAttack test if potential target is outside player FOV
MF3_FOILINVUL = 0x02000000 , // Actor can hurt MF2_INVULNERABLE things
MF3_NOTELEOTHER = 0x04000000 , // Monster is unaffected by teleport other artifact
MF3_BLOODLESSIMPACT = 0x08000000 , // Projectile does not leave blood
MF3_NOEXPLODEFLOOR = 0x10000000 , // Missile stops at floor instead of exploding
MF3_WARNBOT = 0x20000000 , // Missile warns bot
MF3_PUFFONACTORS = 0x40000000 , // Puff appears even when hit bleeding actors
MF3_HUNTPLAYERS = 0x80000000 , // Used with TIDtoHate, means to hate players too
} ;
// --- mobj.flags4 ---
enum ActorFlag4
{
MF4_NOHATEPLAYERS = 0x00000001 , // Ignore player attacks
MF4_QUICKTORETALIATE = 0x00000002 , // Always switch targets when hurt
MF4_NOICEDEATH = 0x00000004 , // Actor never enters an ice death, not even the generic one
MF4_BOSSDEATH = 0x00000008 , // A_FreezeDeathChunks calls A_BossDeath
MF4_RANDOMIZE = 0x00000010 , // Missile has random initial tic count
MF4_NOSKIN = 0x00000020 , // Player cannot use skins
MF4_FIXMAPTHINGPOS = 0x00000040 , // Fix this actor's position when spawned as a map thing
MF4_ACTLIKEBRIDGE = 0x00000080 , // Pickups can "stand" on this actor / cannot be moved by any sector action.
MF4_STRIFEDAMAGE = 0x00000100 , // Strife projectiles only do up to 4x damage, not 8x
MF4_CANUSEWALLS = 0x00000200 , // Can activate 'use' specials
MF4_MISSILEMORE = 0x00000400 , // increases the chance of a missile attack
MF4_MISSILEEVENMORE = 0x00000800 , // significantly increases the chance of a missile attack
MF4_FORCERADIUSDMG = 0x00001000 , // if put on an object it will override MF3_NORADIUSDMG
MF4_DONTFALL = 0x00002000 , // Doesn't have NOGRAVITY disabled when dying.
MF4_SEESDAGGERS = 0x00004000 , // This actor can see you striking with a dagger
MF4_INCOMBAT = 0x00008000 , // Don't alert others when attacked by a dagger
MF4_LOOKALLAROUND = 0x00010000 , // Monster has eyes in the back of its head
MF4_STANDSTILL = 0x00020000 , // Monster should not chase targets unless attacked?
MF4_SPECTRAL = 0x00040000 ,
MF4_SCROLLMOVE = 0x00080000 , // velocity has been applied by a scroller
MF4_NOSPLASHALERT = 0x00100000 , // Splashes don't alert this monster
MF4_SYNCHRONIZED = 0x00200000 , // For actors spawned at load-time only: Do not randomize tics
MF4_NOTARGETSWITCH = 0x00400000 , // monster never switches target until current one is dead
MF4_VFRICTION = 0x00800000 , // Internal flag used by A_PainAttack to push a monster down
MF4_DONTHARMCLASS = 0x01000000 , // Don't hurt one's own kind with explosions (hitscans, too?)
MF4_SHIELDREFLECT = 0x02000000 ,
MF4_DEFLECT = 0x04000000 , // different projectile reflection styles
MF4_ALLOWPARTICLES = 0x08000000 , // this puff type can be replaced by particles
MF4_NOEXTREMEDEATH = 0x10000000 , // this projectile or weapon never gibs its victim
MF4_EXTREMEDEATH = 0x20000000 , // this projectile or weapon always gibs its victim
MF4_FRIGHTENED = 0x40000000 , // Monster runs away from player
MF4_BOSSSPAWNED = 0x80000000 , // Spawned by a boss spawn cube
} ;
// --- mobj.flags5 ---
enum ActorFlag5
{
MF5_DONTDRAIN = 0x00000001 , // cannot be drained health from.
2016-09-04 13:53:20 +00:00
MF5_GETOWNER = 0x00000002 ,
2016-01-10 16:52:41 +00:00
MF5_NODROPOFF = 0x00000004 , // cannot drop off under any circumstances.
MF5_NOFORWARDFALL = 0x00000008 , // Does not make any actor fall forward by being damaged by this
MF5_COUNTSECRET = 0x00000010 , // From Doom 64: actor acts like a secret
MF5_AVOIDINGDROPOFF = 0x00000020 , // Used to move monsters away from dropoffs
MF5_NODAMAGE = 0x00000040 , // Actor can be shot and reacts to being shot but takes no damage
MF5_CHASEGOAL = 0x00000080 , // Walks to goal instead of target if a valid goal is set.
MF5_BLOODSPLATTER = 0x00000100 , // Blood splatter like in Raven's games.
MF5_OLDRADIUSDMG = 0x00000200 , // Use old radius damage code (for barrels and boss brain)
MF5_DEHEXPLOSION = 0x00000400 , // Use the DEHACKED explosion options when this projectile explodes
MF5_PIERCEARMOR = 0x00000800 , // Armor doesn't protect against damage from this actor
MF5_NOBLOODDECALS = 0x00001000 , // Actor bleeds but doesn't spawn blood decals
MF5_USESPECIAL = 0x00002000 , // Actor executes its special when being 'used'.
MF5_NOPAIN = 0x00004000 , // If set the pain state won't be entered
MF5_ALWAYSFAST = 0x00008000 , // always uses 'fast' attacking logic
MF5_NEVERFAST = 0x00010000 , // never uses 'fast' attacking logic
MF5_ALWAYSRESPAWN = 0x00020000 , // always respawns, regardless of skill setting
MF5_NEVERRESPAWN = 0x00040000 , // never respawns, regardless of skill setting
MF5_DONTRIP = 0x00080000 , // Ripping projectiles explode when hitting this actor
MF5_NOINFIGHTING = 0x00100000 , // This actor doesn't switch target when it's hurt
MF5_NOINTERACTION = 0x00200000 , // Thing is completely excluded from any gameplay related checks
MF5_NOTIMEFREEZE = 0x00400000 , // Actor is not affected by time freezer
MF5_PUFFGETSOWNER = 0x00800000 , // [BB] Sets the owner of the puff to the player who fired it
MF5_SPECIALFIREDAMAGE = 0x01000000 , // Special treatment of PhoenixFX1 turned into a flag to remove
// dependence of main engine code of specific actor types.
MF5_SUMMONEDMONSTER = 0x02000000 , // To mark the friendly Minotaur. Hopefully to be generalized later.
MF5_NOVERTICALMELEERANGE = 0x04000000 , // Does not check vertical distance for melee range
MF5_BRIGHT = 0x08000000 , // Actor is always rendered fullbright
MF5_CANTSEEK = 0x10000000 , // seeker missiles cannot home in on this actor
MF5_INCONVERSATION = 0x20000000 , // Actor is having a conversation
MF5_PAINLESS = 0x40000000 , // Actor always inflicts painless damage.
MF5_MOVEWITHSECTOR = 0x80000000 , // P_ChangeSector() will still process this actor if it has MF_NOBLOCKMAP
} ;
// --- mobj.flags6 ---
enum ActorFlag6
{
MF6_NOBOSSRIP = 0x00000001 , // For rippermissiles: Don't rip through bosses.
MF6_THRUSPECIES = 0x00000002 , // Actors passes through other of the same species.
MF6_MTHRUSPECIES = 0x00000004 , // Missile passes through actors of its shooter's species.
MF6_FORCEPAIN = 0x00000008 , // forces target into painstate (unless it has the NOPAIN flag)
MF6_NOFEAR = 0x00000010 , // Not scared of frightening players
MF6_BUMPSPECIAL = 0x00000020 , // Actor executes its special when being collided (as the ST flag)
MF6_DONTHARMSPECIES = 0x00000040 , // Don't hurt one's own species with explosions (hitscans, too?)
MF6_STEPMISSILE = 0x00000080 , // Missile can "walk" up steps
MF6_NOTELEFRAG = 0x00000100 , // [HW] Actor can't be telefragged
MF6_TOUCHY = 0x00000200 , // From MBF: killough 11/98: dies when solids touch it
MF6_CANJUMP = 0x00000400 , // From MBF: a dedicated flag instead of the BOUNCES+FLOAT+sentient combo
MF6_JUMPDOWN = 0x00000800 , // From MBF: generalization of dog behavior wrt. dropoffs.
MF6_VULNERABLE = 0x00001000 , // Actor can be damaged (even if not shootable).
MF6_ARMED = 0x00002000 , // From MBF: Object is armed (for MF6_TOUCHY objects)
MF6_FALLING = 0x00004000 , // From MBF: Object is falling (for pseudotorque simulation)
MF6_LINEDONE = 0x00008000 , // From MBF: Object has already run a line effect
MF6_NOTRIGGER = 0x00010000 , // actor cannot trigger any line actions
MF6_SHATTERING = 0x00020000 , // marks an ice corpse for forced shattering
MF6_KILLED = 0x00040000 , // Something that was killed (but not necessarily a corpse)
MF6_BLOCKEDBYSOLIDACTORS = 0x00080000 , // Blocked by solid actors, even if not solid itself
MF6_ADDITIVEPOISONDAMAGE = 0x00100000 ,
MF6_ADDITIVEPOISONDURATION = 0x00200000 ,
MF6_NOMENU = 0x00400000 , // Player class should not appear in the class selection menu.
MF6_BOSSCUBE = 0x00800000 , // Actor spawned by A_BrainSpit, flagged for timefreeze reasons.
MF6_SEEINVISIBLE = 0x01000000 , // Monsters can see invisible player.
MF6_DONTCORPSE = 0x02000000 , // [RC] Don't autoset MF_CORPSE upon death and don't force Crash state change.
MF6_POISONALWAYS = 0x04000000 , // Always apply poison, even when target can't take the damage.
MF6_DOHARMSPECIES = 0x08000000 , // Do hurt one's own species with projectiles.
MF6_INTRYMOVE = 0x10000000 , // Executing P_TryMove
MF6_NOTAUTOAIMED = 0x20000000 , // Do not subject actor to player autoaim.
MF6_NOTONAUTOMAP = 0x40000000 , // will not be shown on automap with the 'scanner' powerup.
MF6_RELATIVETOFLOOR = 0x80000000 , // [RC] Make flying actors be affected by lifts.
} ;
// --- mobj.flags7 ---
enum ActorFlag7
{
MF7_NEVERTARGET = 0x00000001 , // can not be targetted at all, even if monster friendliness is considered.
MF7_NOTELESTOMP = 0x00000002 , // cannot telefrag under any circumstances (even when set by MAPINFO)
MF7_ALWAYSTELEFRAG = 0x00000004 , // will unconditionally be telefragged when in the way. Overrides all other settings.
MF7_HANDLENODELAY = 0x00000008 , // respect NoDelay state flag
MF7_WEAPONSPAWN = 0x00000010 , // subject to DF_NO_COOP_WEAPON_SPAWN dmflag
MF7_HARMFRIENDS = 0x00000020 , // is allowed to harm friendly monsters.
MF7_BUDDHA = 0x00000040 , // Behaves just like the buddha cheat.
MF7_FOILBUDDHA = 0x00000080 , // Similar to FOILINVUL, foils buddha mode.
MF7_DONTTHRUST = 0x00000100 , // Thrusting functions do not take, and do not give thrust (damage) to actors with this flag.
MF7_ALLOWPAIN = 0x00000200 , // Invulnerable or immune (via damagefactors) actors can still react to taking damage even if they don't.
MF7_CAUSEPAIN = 0x00000400 , // Damage sources with this flag can cause similar effects like ALLOWPAIN.
MF7_THRUREFLECT = 0x00000800 , // Actors who are reflective cause the missiles to not slow down or change angles.
MF7_MIRRORREFLECT = 0x00001000 , // Actor is turned directly 180 degrees around when reflected.
MF7_AIMREFLECT = 0x00002000 , // Actor is directly reflected straight back at the one who fired the projectile.
MF7_HITTARGET = 0x00004000 , // The actor the projectile dies on is set to target, provided it's targetable anyway.
MF7_HITMASTER = 0x00008000 , // Same as HITTARGET, except it's master instead of target.
MF7_HITTRACER = 0x00010000 , // Same as HITTARGET, but for tracer.
MF7_FLYCHEAT = 0x00020000 , // must be part of the actor so that it can be tracked properly
MF7_NODECAL = 0x00040000 , // [ZK] Forces puff to have no impact decal
MF7_FORCEDECAL = 0x00080000 , // [ZK] Forces puff's decal to override the weapon's.
MF7_LAXTELEFRAGDMG = 0x00100000 , // [MC] Telefrag damage can be reduced.
MF7_ICESHATTER = 0x00200000 , // [MC] Shatters ice corpses regardless of damagetype.
2016-04-23 15:16:37 +00:00
MF7_ALLOWTHRUFLAGS = 0x00400000 , // [MC] Allow THRUACTORS and the likes on puffs to prevent mod breakage.
2016-07-23 08:21:04 +00:00
MF7_USEKILLSCRIPTS = 0x00800000 , // [JM] Use "KILL" Script on death if not forced by GameInfo.
MF7_NOKILLSCRIPTS = 0x01000000 , // [JM] No "KILL" Script on death whatsoever, even if forced by GameInfo.
2016-07-28 20:52:20 +00:00
MF7_SPRITEANGLE = 0x02000000 , // [MC] Utilize the SpriteAngle property and lock the rotation to the degrees specified.
2016-01-10 16:52:41 +00:00
} ;
// --- mobj.renderflags ---
enum ActorRenderFlag
{
RF_XFLIP = 0x0001 , // Flip sprite horizontally
RF_YFLIP = 0x0002 , // Flip sprite vertically
RF_ONESIDED = 0x0004 , // Wall/floor sprite is visible from front only
RF_FULLBRIGHT = 0x0010 , // Sprite is drawn at full brightness
RF_RELMASK = 0x0300 , // ---Relative z-coord for bound actors (these obey texture pegging)
RF_RELABSOLUTE = 0x0000 , // Actor z is absolute
RF_RELUPPER = 0x0100 , // Actor z is relative to upper part of wall
RF_RELLOWER = 0x0200 , // Actor z is relative to lower part of wall
RF_RELMID = 0x0300 , // Actor z is relative to middle part of wall
RF_CLIPMASK = 0x0c00 , // ---Clipping for bound actors
RF_CLIPFULL = 0x0000 , // Clip sprite to full height of wall
RF_CLIPUPPER = 0x0400 , // Clip sprite to upper part of wall
RF_CLIPMID = 0x0800 , // Clip sprite to mid part of wall
RF_CLIPLOWER = 0x0c00 , // Clip sprite to lower part of wall
RF_DECALMASK = RF_RELMASK | RF_CLIPMASK ,
RF_SPRITETYPEMASK = 0x7000 , // ---Different sprite types, not all implemented
RF_FACESPRITE = 0x0000 , // Face sprite
RF_WALLSPRITE = 0x1000 , // Wall sprite
2016-05-01 13:45:50 +00:00
RF_FLATSPRITE = 0x2000 , // Flat sprite
2016-01-10 16:52:41 +00:00
RF_VOXELSPRITE = 0x3000 , // Voxel object
RF_INVISIBLE = 0x8000 , // Don't bother drawing this actor
2016-06-05 20:21:19 +00:00
RF_ROLLSPRITE = 0x40000 , //[marrub]roll the sprite billboard
RF_DONTFLIP = 0x80000 , // Don't flip it when viewed from behind.
2016-07-04 18:58:49 +00:00
RF_ROLLCENTER = 0x100000 , // Rotate from the center of sprite instead of offsets
2016-01-10 16:52:41 +00:00
RF_FORCEYBILLBOARD = 0x10000 , // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting)
RF_FORCEXYBILLBOARD = 0x20000 , // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting)
} ;
// This translucency value produces the closest match to Heretic's TINTTAB.
// ~40% of the value of the overlaid image shows through.
2016-03-21 11:18:46 +00:00
const double HR_SHADOW = ( 0x6800 / 65536. ) ;
2016-01-10 16:52:41 +00:00
// Hexen's TINTTAB is the same as Heretic's, just reversed.
2016-03-21 11:18:46 +00:00
const double HX_SHADOW = ( 0x9800 / 65536. ) ;
const double HX_ALTSHADOW = ( 0x6800 / 65536. ) ;
2016-01-10 16:52:41 +00:00
// This could easily be a bool but then it'd be much harder to find later. ;)
enum replace_t
{
NO_REPLACE = 0 ,
ALLOW_REPLACE = 1
} ;
enum ActorBounceFlag
{
BOUNCE_Walls = 1 < < 0 , // bounces off of walls
BOUNCE_Floors = 1 < < 1 , // bounces off of floors
BOUNCE_Ceilings = 1 < < 2 , // bounces off of ceilings
BOUNCE_Actors = 1 < < 3 , // bounces off of some actors
BOUNCE_AllActors = 1 < < 4 , // bounces off of all actors (requires BOUNCE_Actors to be set, too)
BOUNCE_AutoOff = 1 < < 5 , // when bouncing off a sector plane, if the new Z velocity is below 3.0, disable further bouncing
BOUNCE_HereticType = 1 < < 6 , // goes into Death state when bouncing on floors or ceilings
BOUNCE_UseSeeSound = 1 < < 7 , // compatibility fallback. This will only be set by
// the compatibility handlers for the old bounce flags.
BOUNCE_NoWallSound = 1 < < 8 , // don't make noise when bouncing off a wall
BOUNCE_Quiet = 1 < < 9 , // Strife's grenades don't make a bouncing sound
BOUNCE_ExplodeOnWater = 1 < < 10 , // explodes when hitting a water surface
BOUNCE_CanBounceWater = 1 < < 11 , // can bounce on water
// MBF bouncing is a bit different from other modes as Killough coded many special behavioral cases
// for them that are not present in ZDoom, so it is necessary to identify it properly.
BOUNCE_MBF = 1 < < 12 , // This in itself is not a valid mode, but replaces MBF's MF_BOUNCE flag.
BOUNCE_AutoOffFloorOnly = 1 < < 13 , // like BOUNCE_AutoOff, but only on floors
BOUNCE_UseBounceState = 1 < < 14 , // Use Bounce[.*] states
BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType | BOUNCE_MBF ,
// The three "standard" types of bounciness are:
// HERETIC - Missile will only bounce off the floor once and then enter
// its death state. It does not bounce off walls at all.
// HEXEN - Missile bounces off of walls and floors indefinitely.
// DOOM - Like Hexen, but the bounce turns off if its vertical velocity
// is too low.
BOUNCE_None = 0 ,
BOUNCE_Heretic = BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_HereticType ,
BOUNCE_Doom = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff ,
BOUNCE_Hexen = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors ,
BOUNCE_Grenade = BOUNCE_MBF | BOUNCE_Doom , // Bounces on walls and flats like ZDoom bounce.
BOUNCE_Classic = BOUNCE_MBF | BOUNCE_Floors | BOUNCE_Ceilings , // Bounces on flats only, but
// does not die when bouncing.
// combined types
BOUNCE_DoomCompat = BOUNCE_Doom | BOUNCE_UseSeeSound ,
BOUNCE_HereticCompat = BOUNCE_Heretic | BOUNCE_UseSeeSound ,
BOUNCE_HexenCompat = BOUNCE_Hexen | BOUNCE_UseSeeSound
// The distinction between BOUNCE_Actors and BOUNCE_AllActors: A missile with
// BOUNCE_Actors set will bounce off of reflective and "non-sentient" actors.
// A missile that also has BOUNCE_AllActors set will bounce off of any actor.
// For compatibility reasons when BOUNCE_Actors was implied by the bounce type
// being "Doom" or "Hexen" and BOUNCE_AllActors was the separate
// MF5_BOUNCEONACTORS, you must set BOUNCE_Actors for BOUNCE_AllActors to have
// an effect.
} ;
// [TP] Flagset definitions
typedef TFlags < ActorFlag > ActorFlags ;
typedef TFlags < ActorFlag2 > ActorFlags2 ;
typedef TFlags < ActorFlag3 > ActorFlags3 ;
typedef TFlags < ActorFlag4 > ActorFlags4 ;
typedef TFlags < ActorFlag5 > ActorFlags5 ;
typedef TFlags < ActorFlag6 > ActorFlags6 ;
typedef TFlags < ActorFlag7 > ActorFlags7 ;
typedef TFlags < ActorRenderFlag > ActorRenderFlags ;
typedef TFlags < ActorBounceFlag , WORD > ActorBounceFlags ;
DEFINE_TFLAGS_OPERATORS ( ActorFlags )
DEFINE_TFLAGS_OPERATORS ( ActorFlags2 )
DEFINE_TFLAGS_OPERATORS ( ActorFlags3 )
DEFINE_TFLAGS_OPERATORS ( ActorFlags4 )
DEFINE_TFLAGS_OPERATORS ( ActorFlags5 )
DEFINE_TFLAGS_OPERATORS ( ActorFlags6 )
DEFINE_TFLAGS_OPERATORS ( ActorFlags7 )
DEFINE_TFLAGS_OPERATORS ( ActorRenderFlags )
DEFINE_TFLAGS_OPERATORS ( ActorBounceFlags )
// Used to affect the logic for thing activation through death, USESPECIAL and BUMPSPECIAL
// "thing" refers to what has the flag and the special, "trigger" refers to what used or bumped it
enum EThingSpecialActivationType
{
THINGSPEC_Default = 0 , // Normal behavior: a player must be the trigger, and is the activator
THINGSPEC_ThingActs = 1 , // The thing itself is the activator of the special
THINGSPEC_ThingTargets = 1 < < 1 , // The thing changes its target to the trigger
THINGSPEC_TriggerTargets = 1 < < 2 , // The trigger changes its target to the thing
THINGSPEC_MonsterTrigger = 1 < < 3 , // The thing can be triggered by a monster
THINGSPEC_MissileTrigger = 1 < < 4 , // The thing can be triggered by a projectile
THINGSPEC_ClearSpecial = 1 < < 5 , // Clears special after successful activation
THINGSPEC_NoDeathSpecial = 1 < < 6 , // Don't activate special on death
THINGSPEC_TriggerActs = 1 < < 7 , // The trigger is the activator of the special
// (overrides LEVEL_ACTOWNSPECIAL Hexen hack)
THINGSPEC_Activate = 1 < < 8 , // The thing is activated when triggered
THINGSPEC_Deactivate = 1 < < 9 , // The thing is deactivated when triggered
THINGSPEC_Switch = 1 < < 10 , // The thing is alternatively activated and deactivated when triggered
} ;
2016-03-20 09:52:10 +00:00
# define ONFLOORZ FIXED_MIN
# define ONCEILINGZ FIXED_MAX
# define FLOATRANDZ (FIXED_MAX-1)
2016-01-10 16:52:41 +00:00
class FDecalBase ;
class AInventory ;
inline AActor * GetDefaultByName ( const char * name )
{
return ( AActor * ) ( PClass : : FindClass ( name ) - > Defaults ) ;
}
inline AActor * GetDefaultByType ( const PClass * type )
{
return ( AActor * ) ( type - > Defaults ) ;
}
template < class T >
inline T * GetDefault ( )
{
2016-02-04 21:15:29 +00:00
return ( T * ) ( RUNTIME_CLASS_CASTLESS ( T ) - > Defaults ) ;
2016-01-10 16:52:41 +00:00
}
struct line_t ;
struct secplane_t ;
struct FStrifeDialogueNode ;
2016-02-04 21:15:29 +00:00
class DDropItem : public DObject
{
DECLARE_CLASS ( DDropItem , DObject )
HAS_OBJECT_POINTERS
public :
DDropItem * Next ;
FName Name ;
int Probability ;
int Amount ;
} ;
2016-01-10 16:52:41 +00:00
2016-03-31 14:52:25 +00:00
const double MinVel = EQUAL_EPSILON ;
2016-01-10 16:52:41 +00:00
// Map Object definition.
class AActor : public DThinker
{
2016-02-04 21:15:29 +00:00
DECLARE_CLASS_WITH_META ( AActor , DThinker , PClassActor )
2016-01-10 16:52:41 +00:00
HAS_OBJECT_POINTERS
public :
AActor ( ) throw ( ) ;
AActor ( const AActor & other ) throw ( ) ;
AActor & operator = ( const AActor & other ) ;
void Destroy ( ) ;
~ AActor ( ) ;
void Serialize ( FArchive & arc ) ;
2016-09-18 11:26:34 +00:00
void Serialize ( FSerializer & arc ) ;
2016-09-19 08:34:54 +00:00
void PostSerialize ( ) ;
2016-09-18 11:26:34 +00:00
2016-03-23 09:42:41 +00:00
static AActor * StaticSpawn ( PClassActor * type , const DVector3 & pos , replace_t allowreplacement , bool SpawningMapThing = false ) ;
2016-01-10 16:52:41 +00:00
inline AActor * GetDefault ( ) const
{
2016-02-04 21:15:29 +00:00
return ( AActor * ) ( this - > GetClass ( ) - > Defaults ) ;
2016-01-10 16:52:41 +00:00
}
2016-02-04 21:15:29 +00:00
DDropItem * GetDropItems ( ) const ;
2016-01-10 16:52:41 +00:00
// Return true if the monster should use a missile attack, false for melee
2016-03-24 19:56:59 +00:00
bool SuggestMissileAttack ( double dist ) ;
2016-01-10 16:52:41 +00:00
// Adjusts the angle for deflection/reflection of incoming missiles
// Returns true if the missile should be allowed to explode anyway
2016-03-16 11:41:26 +00:00
bool AdjustReflectionAngle ( AActor * thing , DAngle & angle ) ;
2016-01-10 16:52:41 +00:00
// Returns true if this actor is within melee range of its target
bool CheckMeleeRange ( ) ;
2016-02-09 04:11:42 +00:00
bool CheckNoDelay ( ) ;
2016-01-10 16:52:41 +00:00
virtual void BeginPlay ( ) ; // Called immediately after the actor is created
virtual void PostBeginPlay ( ) ; // Called immediately before the actor's first tick
virtual void LevelSpawned ( ) ; // Called after BeginPlay if this actor was spawned by the world
virtual void HandleSpawnFlags ( ) ; // Translates SpawnFlags into in-game flags.
virtual void MarkPrecacheSounds ( ) const ; // Marks sounds used by this actor for precaching.
virtual void Activate ( AActor * activator ) ;
virtual void Deactivate ( AActor * activator ) ;
virtual void Tick ( ) ;
// Called when actor dies
virtual void Die ( AActor * source , AActor * inflictor , int dmgflags = 0 ) ;
// Perform some special damage action. Returns the amount of damage to do.
// Returning -1 signals the damage routine to exit immediately
virtual int DoSpecialDamage ( AActor * target , int damage , FName damagetype ) ;
// Like DoSpecialDamage, but called on the actor receiving the damage.
virtual int TakeSpecialDamage ( AActor * inflictor , AActor * source , int damage , FName damagetype ) ;
// Centaurs and ettins squeal when electrocuted, poisoned, or "holy"-ed
// Made a metadata property so no longer virtual
void Howl ( ) ;
// Actor just hit the floor
virtual void HitFloor ( ) ;
// plays bouncing sound
void PlayBounceSound ( bool onfloor ) ;
// Called when an actor with MF_MISSILE and MF2_FLOORBOUNCE hits the floor
virtual bool FloorBounceMissile ( secplane_t & plane ) ;
// Called when an actor is to be reflected by a disc of repulsion.
// Returns true to continue normal blast processing.
2016-03-21 13:00:05 +00:00
virtual bool SpecialBlastHandling ( AActor * source , double strength ) ;
2016-01-10 16:52:41 +00:00
// Called by RoughBlockCheck
bool IsOkayToAttack ( AActor * target ) ;
// Plays the actor's ActiveSound if its voice isn't already making noise.
void PlayActiveSound ( ) ;
// Actor had MF_SKULLFLY set and rammed into something
// Returns false to stop moving and true to keep moving
virtual bool Slam ( AActor * victim ) ;
// Called by PIT_CheckThing() and needed for some Hexen things.
// Returns -1 for normal behavior, 0 to return false, and 1 to return true.
// I'm not sure I like it this way, but it will do for now.
virtual int SpecialMissileHit ( AActor * victim ) ;
// Returns true if it's okay to switch target to "other" after being attacked by it.
virtual bool OkayToSwitchTarget ( AActor * other ) ;
// Something just touched this actor.
virtual void Touch ( AActor * toucher ) ;
// Adds the item to this actor's inventory and sets its Owner.
virtual void AddInventory ( AInventory * item ) ;
2016-04-21 13:28:51 +00:00
// Give an item to the actor and pick it up.
// Returns true if the item pickup succeeded.
virtual bool GiveInventory ( PClassInventory * type , int amount , bool givecheat = false ) ;
2016-01-10 16:52:41 +00:00
// Removes the item from the inventory list.
virtual void RemoveInventory ( AInventory * item ) ;
// Take the amount value of an item from the inventory list.
// If nothing is left, the item may be destroyed.
// Returns true if the initial item count is positive.
2016-02-04 21:15:29 +00:00
virtual bool TakeInventory ( PClassActor * itemclass , int amount , bool fromdecorate = false , bool notakeinfinite = false ) ;
2016-01-10 16:52:41 +00:00
// Uses an item and removes it from the inventory.
virtual bool UseInventory ( AInventory * item ) ;
// Tosses an item out of the inventory.
virtual AInventory * DropInventory ( AInventory * item ) ;
// Removes all items from the inventory.
void ClearInventory ( ) ;
// Returns true if this view is considered "local" for the player.
bool CheckLocalView ( int playernum ) const ;
// Finds the first item of a particular type.
2016-02-04 21:15:29 +00:00
AInventory * FindInventory ( PClassActor * type , bool subclass = false ) ;
2016-01-10 16:52:41 +00:00
AInventory * FindInventory ( FName type ) ;
template < class T > T * FindInventory ( )
{
2016-02-04 21:15:29 +00:00
return static_cast < T * > ( FindInventory ( RUNTIME_TEMPLATE_CLASS ( T ) ) ) ;
2016-01-10 16:52:41 +00:00
}
// Adds one item of a particular type. Returns NULL if it could not be added.
2016-02-04 21:15:29 +00:00
AInventory * GiveInventoryType ( PClassActor * type ) ;
2016-01-10 16:52:41 +00:00
// Returns the first item held with IF_INVBAR set.
AInventory * FirstInv ( ) ;
// Tries to give the actor some ammo.
2016-02-04 21:15:29 +00:00
bool GiveAmmo ( PClassAmmo * type , int amount ) ;
2016-01-10 16:52:41 +00:00
// Destroys all the inventory the actor is holding.
void DestroyAllInventory ( ) ;
// Set the alphacolor field properly
void SetShade ( DWORD rgb ) ;
void SetShade ( int r , int g , int b ) ;
// Plays a conversation animation
void ConversationAnimation ( int animnum ) ;
// Make this actor hate the same things as another actor
void CopyFriendliness ( AActor * other , bool changeTarget , bool resetHealth = true ) ;
// Moves the other actor's inventory to this one
void ObtainInventory ( AActor * other ) ;
// Die. Now.
virtual bool Massacre ( ) ;
// Transforms the actor into a finely-ground paste
virtual bool Grind ( bool items ) ;
// Get this actor's team
int GetTeam ( ) ;
// Is the other actor on my team?
bool IsTeammate ( AActor * other ) ;
// Is the other actor my friend?
bool IsFriend ( AActor * other ) ;
// Do I hate the other actor?
bool IsHostile ( AActor * other ) ;
inline bool IsNoClip2 ( ) const ;
2016-02-24 09:08:23 +00:00
void CheckPortalTransition ( bool islinked ) ;
2016-03-28 08:01:24 +00:00
DVector3 GetPortalTransition ( double byoffset , sector_t * * pSec = NULL ) ;
2016-01-10 16:52:41 +00:00
// What species am I?
virtual FName GetSpecies ( ) ;
2016-03-25 15:25:25 +00:00
double GetBobOffset ( double ticfrac = 0 ) const
2016-03-23 11:21:52 +00:00
{
if ( ! ( flags2 & MF2_FLOATBOB ) )
{
return 0 ;
}
2016-03-25 15:25:25 +00:00
return BobSin ( FloatBobPhase + level . maptime + ticfrac ) ;
2016-03-23 11:21:52 +00:00
}
2016-01-10 16:52:41 +00:00
// Enter the crash state
void Crash ( ) ;
// Return starting health adjusted by skill level
2016-02-04 21:15:29 +00:00
int SpawnHealth ( ) const ;
int GetGibHealth ( ) const ;
2016-03-20 19:55:06 +00:00
double GetCameraHeight ( ) const ;
2016-01-10 16:52:41 +00:00
inline bool isMissile ( bool precise = true )
{
return ( flags & MF_MISSILE ) | | ( precise & & GetDefault ( ) - > flags & MF_MISSILE ) ;
}
// Check for monsters that count as kill but excludes all friendlies.
bool CountsAsKill ( ) const
{
return ( flags & MF_COUNTKILL ) & & ! ( flags & MF_FRIENDLY ) ;
}
PalEntry GetBloodColor ( ) const
{
2016-02-04 21:15:29 +00:00
return GetClass ( ) - > BloodColor ;
2016-01-10 16:52:41 +00:00
}
// These also set CF_INTERPVIEW for players.
2016-03-16 11:41:26 +00:00
void SetPitch ( DAngle p , bool interpolate , bool forceclamp = false ) ;
void SetAngle ( DAngle ang , bool interpolate ) ;
void SetRoll ( DAngle roll , bool interpolate ) ;
2016-01-10 16:52:41 +00:00
2016-02-04 21:15:29 +00:00
PClassActor * GetBloodType ( int type = 0 ) const
2016-01-10 16:52:41 +00:00
{
2016-02-04 21:15:29 +00:00
PClassActor * bloodcls ;
2016-01-10 16:52:41 +00:00
if ( type = = 0 )
{
2016-02-04 21:15:29 +00:00
bloodcls = PClass : : FindActor ( GetClass ( ) - > BloodType ) ;
2016-01-10 16:52:41 +00:00
}
else if ( type = = 1 )
{
2016-02-04 21:15:29 +00:00
bloodcls = PClass : : FindActor ( GetClass ( ) - > BloodType2 ) ;
2016-01-10 16:52:41 +00:00
}
else if ( type = = 2 )
{
2016-02-04 21:15:29 +00:00
bloodcls = PClass : : FindActor ( GetClass ( ) - > BloodType3 ) ;
}
else
{
return NULL ;
2016-01-10 16:52:41 +00:00
}
if ( bloodcls ! = NULL )
{
bloodcls = bloodcls - > GetReplacement ( ) ;
}
return bloodcls ;
}
2016-04-12 17:44:12 +00:00
double Distance2DSquared ( AActor * other , bool absolute = false )
{
DVector2 otherpos = absolute ? other - > Pos ( ) : other - > PosRelative ( this ) ;
return ( Pos ( ) . XY ( ) - otherpos ) . LengthSquared ( ) ;
}
2016-03-17 10:38:56 +00:00
double Distance2D ( AActor * other , bool absolute = false )
2016-01-10 16:52:41 +00:00
{
2016-03-25 15:25:25 +00:00
DVector2 otherpos = absolute ? other - > Pos ( ) : other - > PosRelative ( this ) ;
return ( Pos ( ) . XY ( ) - otherpos ) . Length ( ) ;
2016-01-10 16:52:41 +00:00
}
2016-03-20 15:51:42 +00:00
double Distance2D ( double x , double y ) const
{
return DVector2 ( X ( ) - x , Y ( ) - y ) . Length ( ) ;
}
2016-03-25 23:34:56 +00:00
double Distance2D ( AActor * other , double xadd , double yadd , bool absolute = false )
2016-01-10 16:52:41 +00:00
{
2016-03-25 15:25:25 +00:00
DVector3 otherpos = absolute ? other - > Pos ( ) : other - > PosRelative ( this ) ;
2016-03-25 23:34:56 +00:00
return DVector2 ( X ( ) - otherpos . X + xadd , Y ( ) - otherpos . Y + yadd ) . Length ( ) ;
2016-01-10 16:52:41 +00:00
}
2016-01-10 19:46:26 +00:00
2016-03-25 23:34:56 +00:00
// a full 3D version of the above
double Distance3D ( AActor * other , bool absolute = false )
2016-01-10 19:46:26 +00:00
{
2016-03-25 23:34:56 +00:00
DVector3 otherpos = absolute ? other - > Pos ( ) : other - > PosRelative ( this ) ;
return ( Pos ( ) - otherpos ) . Length ( ) ;
2016-01-10 19:46:26 +00:00
}
2016-03-16 23:07:37 +00:00
DAngle AngleTo ( AActor * other , bool absolute = false )
2016-03-16 11:41:26 +00:00
{
2016-03-25 15:25:25 +00:00
DVector2 otherpos = absolute ? other - > Pos ( ) : other - > PosRelative ( this ) ;
return VecToAngle ( otherpos - Pos ( ) . XY ( ) ) ;
2016-03-16 11:41:26 +00:00
}
2016-03-20 22:42:27 +00:00
DAngle AngleTo ( AActor * other , double oxofs , double oyofs , bool absolute = false ) const
{
2016-03-25 15:25:25 +00:00
DVector2 otherpos = absolute ? other - > Pos ( ) : other - > PosRelative ( this ) ;
return VecToAngle ( otherpos - Pos ( ) + DVector2 ( oxofs , oyofs ) ) ;
2016-03-20 22:42:27 +00:00
}
2016-03-19 23:54:18 +00:00
DVector2 Vec2To ( AActor * other ) const
{
2016-03-25 15:25:25 +00:00
return other - > PosRelative ( this ) - Pos ( ) ;
2016-03-19 23:54:18 +00:00
}
DVector3 Vec3To ( AActor * other ) const
{
2016-03-25 15:25:25 +00:00
return other - > PosRelative ( this ) - Pos ( ) ;
2016-03-19 23:54:18 +00:00
}
2016-03-20 09:52:10 +00:00
DVector2 Vec2Offset ( double dx , double dy , bool absolute = false )
{
if ( absolute )
{
return { X ( ) + dx , Y ( ) + dy } ;
}
else
{
2016-03-28 08:01:24 +00:00
return P_GetOffsetPosition ( X ( ) , Y ( ) , dx , dy ) ;
2016-03-20 09:52:10 +00:00
}
}
2016-03-21 13:00:05 +00:00
2016-03-20 09:52:10 +00:00
DVector3 Vec2OffsetZ ( double dx , double dy , double atz , bool absolute = false )
{
if ( absolute )
{
return { X ( ) + dx , Y ( ) + dy , atz } ;
}
else
{
2016-03-28 08:01:24 +00:00
DVector2 v = P_GetOffsetPosition ( X ( ) , Y ( ) , dx , dy ) ;
return DVector3 ( v , atz ) ;
2016-03-20 09:52:10 +00:00
}
}
2016-01-18 11:37:39 +00:00
2016-03-21 13:00:05 +00:00
DVector2 Vec2Angle ( double length , DAngle angle , bool absolute = false )
{
if ( absolute )
{
return { X ( ) + length * angle . Cos ( ) , Y ( ) + length * angle . Sin ( ) } ;
}
else
{
2016-03-28 08:01:24 +00:00
return P_GetOffsetPosition ( X ( ) , Y ( ) , length * angle . Cos ( ) , length * angle . Sin ( ) ) ;
2016-03-21 13:00:05 +00:00
}
}
2016-03-20 09:52:10 +00:00
DVector3 Vec3Offset ( double dx , double dy , double dz , bool absolute = false )
{
if ( absolute )
{
return { X ( ) + dx , Y ( ) + dy , Z ( ) + dz } ;
}
else
{
2016-03-28 08:01:24 +00:00
DVector2 v = P_GetOffsetPosition ( X ( ) , Y ( ) , dx , dy ) ;
return DVector3 ( v , Z ( ) + dz ) ;
2016-03-20 09:52:10 +00:00
}
}
2016-03-22 11:42:27 +00:00
DVector3 Vec3Offset ( const DVector3 & ofs , bool absolute = false )
{
return Vec3Offset ( ofs . X , ofs . Y , ofs . Z , absolute ) ;
}
2016-03-19 23:54:18 +00:00
DVector3 Vec3Angle ( double length , DAngle angle , double dz , bool absolute = false )
{
if ( absolute )
{
return { X ( ) + length * angle . Cos ( ) , Y ( ) + length * angle . Sin ( ) , Z ( ) + dz } ;
}
else
{
2016-03-28 08:01:24 +00:00
DVector2 v = P_GetOffsetPosition ( X ( ) , Y ( ) , length * angle . Cos ( ) , length * angle . Sin ( ) ) ;
return DVector3 ( v , Z ( ) + dz ) ;
2016-03-19 23:54:18 +00:00
}
}
2016-03-17 10:38:56 +00:00
double AccuracyFactor ( )
{
return 1. / ( 1 < < ( accuracy * 5 / 100 ) ) ;
}
2016-02-24 23:41:31 +00:00
void ClearInterpolation ( ) ;
2016-03-25 23:34:56 +00:00
void Move ( const DVector3 & vel )
{
SetOrigin ( Pos ( ) + vel , true ) ;
}
2016-03-31 19:20:45 +00:00
virtual void SetOrigin ( double x , double y , double z , bool moving ) ;
2016-03-19 23:54:18 +00:00
void SetOrigin ( const DVector3 & npos , bool moving )
{
2016-03-31 19:13:32 +00:00
SetOrigin ( npos . X , npos . Y , npos . Z , moving ) ;
2016-03-19 23:54:18 +00:00
}
2016-01-10 16:52:41 +00:00
inline void SetFriendPlayer ( player_t * player ) ;
bool IsVisibleToPlayer ( ) const ;
// Calculate amount of missile damage
virtual int GetMissileDamage ( int mask , int add ) ;
bool CanSeek ( AActor * target ) const ;
2016-03-19 23:54:18 +00:00
double GetGravity ( ) const ;
2016-01-10 16:52:41 +00:00
bool IsSentient ( ) const ;
const char * GetTag ( const char * def = NULL ) const ;
void SetTag ( const char * def ) ;
// Triggers SECSPAC_Exit/SECSPAC_Enter and related events if oldsec != current sector
void CheckSectorTransition ( sector_t * oldsec ) ;
2016-04-17 21:48:04 +00:00
void UpdateRenderSectorList ( ) ;
void ClearRenderSectorList ( ) ;
2016-04-21 20:59:07 +00:00
void ClearRenderLineList ( ) ;
2016-01-10 16:52:41 +00:00
// info for drawing
2016-01-20 14:12:51 +00:00
// NOTE: The first member variable *must* be snext.
2016-01-10 16:52:41 +00:00
AActor * snext , * * sprev ; // links in sector (if needed)
2016-03-25 15:25:25 +00:00
DVector3 __Pos ; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
2016-04-17 21:48:04 +00:00
DVector3 OldRenderPos ;
2016-03-16 11:41:26 +00:00
2016-07-28 20:52:20 +00:00
DAngle SpriteAngle ;
DAngle SpriteRotation ;
2016-03-16 11:41:26 +00:00
DRotator Angles ;
2016-03-19 23:54:18 +00:00
DVector3 Vel ;
double Speed ;
double FloatSpeed ;
2016-03-16 11:41:26 +00:00
2016-01-10 16:52:41 +00:00
WORD sprite ; // used to find patch_t and flip value
BYTE frame ; // sprite frame to draw
2016-03-20 11:13:00 +00:00
DVector2 Scale ; // Scaling values; 1 is normal size
2016-01-10 16:52:41 +00:00
FRenderStyle RenderStyle ; // Style to draw this actor with
ActorRenderFlags renderflags ; // Different rendering flags
FTextureID picnum ; // Draw this instead of sprite if valid
DWORD effects ; // [RH] see p_effect.h
2016-03-21 11:18:46 +00:00
double Alpha ; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double.
2016-01-10 16:52:41 +00:00
DWORD fillcolor ; // Color to draw when STYLE_Shaded
// interaction info
FBlockNode * BlockNode ; // links in blocks (if needed)
struct sector_t * Sector ;
subsector_t * subsector ;
2016-03-20 18:52:35 +00:00
double floorz , ceilingz ; // closest together of contacted secs
2016-03-23 11:21:52 +00:00
double dropoffz ; // killough 11/98: the lowest floor over all contacted Sectors.
2016-03-20 12:32:53 +00:00
2016-01-10 16:52:41 +00:00
struct sector_t * floorsector ;
FTextureID floorpic ; // contacted sec floorpic
int floorterrain ;
struct sector_t * ceilingsector ;
FTextureID ceilingpic ; // contacted sec ceilingpic
2016-03-20 19:55:06 +00:00
double radius , Height ; // for movement checking
2016-03-20 14:04:13 +00:00
2016-03-20 19:55:06 +00:00
double projectilepassheight ; // height for clipping projectile movement against this actor
2016-03-20 20:51:09 +00:00
2016-01-10 16:52:41 +00:00
SDWORD tics ; // state tic counter
FState * state ;
2016-09-19 01:36:51 +00:00
//VMFunction *Damage; // For missiles and monster railgun
int DamageVal ;
VMFunction * DamageFunc ;
2016-01-10 16:52:41 +00:00
int projectileKickback ;
ActorFlags flags ;
ActorFlags2 flags2 ; // Heretic flags
ActorFlags3 flags3 ; // [RH] Hexen/Heretic actor-dependant behavior made flaggable
ActorFlags4 flags4 ; // [RH] Even more flags!
ActorFlags5 flags5 ; // OMG! We need another one.
ActorFlags6 flags6 ; // Shit! Where did all the flags go?
ActorFlags7 flags7 ; // WHO WANTS TO BET ON 8!?
// [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it.
DWORD VisibleToTeam ;
int special1 ; // Special info
int special2 ; // Special info
2016-03-20 20:51:09 +00:00
double specialf1 ; // With floats we cannot use the int versions for storing position or angle data without reverting to fixed point (which we do not want.)
double specialf2 ;
2016-01-10 16:52:41 +00:00
int weaponspecial ; // Special info for weapons.
int health ;
BYTE movedir ; // 0-7
SBYTE visdir ;
SWORD movecount ; // when 0, select a new dir
SWORD strafecount ; // for MF3_AVOIDMELEE
TObjPtr < AActor > target ; // thing being chased/attacked (or NULL)
// also the originator for missiles
TObjPtr < AActor > lastenemy ; // Last known enemy -- killough 2/15/98
TObjPtr < AActor > LastHeard ; // [RH] Last actor this one heard
SDWORD reactiontime ; // if non 0, don't attack yet; used by
// player to freeze a bit after teleporting
SDWORD threshold ; // if > 0, the target will be chased
2016-02-03 00:26:20 +00:00
SDWORD DefThreshold ; // [MC] Default threshold which the actor will reset its threshold to after switching targets
2016-01-10 16:52:41 +00:00
// no matter what (even if shot)
player_t * player ; // only valid if type of APlayerPawn
TObjPtr < AActor > LastLookActor ; // Actor last looked for (if TIDtoHate != 0)
2016-03-22 23:53:09 +00:00
DVector3 SpawnPoint ; // For nightmare respawn
2016-01-10 16:52:41 +00:00
WORD SpawnAngle ;
int StartHealth ;
BYTE WeaveIndexXY ; // Separated from special2 because it's used by globally accessible functions.
BYTE WeaveIndexZ ;
int skillrespawncount ;
int TIDtoHate ; // TID of things to hate (0 if none)
FNameNoInit Species ; // For monster families
2016-09-01 18:49:58 +00:00
TObjPtr < AActor > alternative ; // (Un)Morphed actors stored here. Those with the MF_UNMORPHED flag are the originals.
2016-01-10 16:52:41 +00:00
TObjPtr < AActor > tracer ; // Thing being chased/attacked for tracers
TObjPtr < AActor > master ; // Thing which spawned this one (prevents mutual attacks)
2016-03-20 22:42:27 +00:00
double Floorclip ; // value to use for floor clipping
2016-01-10 16:52:41 +00:00
int tid ; // thing identifier
int special ; // special
int args [ 5 ] ; // special arguments
int accuracy , stamina ; // [RH] Strife stats -- [XA] moved here for DECORATE/ACS access.
AActor * inext , * * iprev ; // Links to other mobjs in same bucket
TObjPtr < AActor > goal ; // Monster's goal if not chasing anything
int waterlevel ; // 0=none, 1=feet, 2=waist, 3=eyes
BYTE boomwaterlevel ; // splash information for non-swimmable water sectors
BYTE MinMissileChance ; // [RH] If a random # is > than this, then missile attack.
SBYTE LastLookPlayerNumber ; // Player number last looked for (if TIDtoHate == 0)
ActorBounceFlags BounceFlags ; // which bouncing type?
DWORD SpawnFlags ; // Increased to DWORD because of Doom 64
2016-03-24 20:31:04 +00:00
double meleerange ; // specifies how far a melee attack reaches.
2016-03-24 19:56:59 +00:00
double meleethreshold ; // Distance below which a monster doesn't try to shoot missiles anynore
2016-01-10 16:52:41 +00:00
// but instead tries to come closer for a melee attack.
// This is not the same as meleerange
2016-03-24 19:56:59 +00:00
double maxtargetrange ; // any target farther away cannot be attacked
2016-03-24 19:43:35 +00:00
double bouncefactor ; // Strife's grenades use 50%, Hexen's Flechettes 70.
double wallbouncefactor ; // The bounce factor for walls can be different.
2016-01-10 16:52:41 +00:00
int bouncecount ; // Strife's grenades only bounce twice before exploding
2016-03-20 23:51:19 +00:00
double Gravity ; // [GRB] Gravity factor
2016-03-24 21:50:03 +00:00
double Friction ;
2016-01-10 16:52:41 +00:00
int FastChaseStrafeCount ;
2016-03-24 20:31:04 +00:00
double pushfactor ;
2016-01-10 16:52:41 +00:00
int lastpush ;
int activationtype ; // How the thing behaves when activated with USESPECIAL or BUMPSPECIAL
int lastbump ; // Last time the actor was bumped, used to control BUMPSPECIAL
int Score ; // manipulated by score items, ACS or DECORATE. The engine doesn't use this itself for anything.
FString * Tag ; // Strife's tag name.
int DesignatedTeam ; // Allow for friendly fire cacluations to be done on non-players.
AActor * BlockingMobj ; // Actor that blocked the last move
line_t * BlockingLine ; // Line that blocked the last move
int PoisonDamage ; // Damage received per tic from poison.
FNameNoInit PoisonDamageType ; // Damage type dealt by poison.
int PoisonDuration ; // Duration left for receiving poison damage.
int PoisonPeriod ; // How often poison damage is applied. (Every X tics.)
int PoisonDamageReceived ; // Damage received per tic from poison.
FNameNoInit PoisonDamageTypeReceived ; // Damage type received by poison.
int PoisonDurationReceived ; // Duration left for receiving poison damage.
int PoisonPeriodReceived ; // How often poison damage is applied. (Every X tics.)
TObjPtr < AActor > Poisoner ; // Last source of received poison damage.
// a linked list of sectors where this object appears
struct msecnode_t * touching_sectorlist ; // phares 3/14/98
2016-04-21 20:59:07 +00:00
struct msecnode_t * render_sectorlist ; // same for cross-sectorportal rendering
struct portnode_t * render_portallist ; // and for cross-lineportal
2016-04-17 21:48:04 +00:00
2016-01-10 16:52:41 +00:00
TObjPtr < AInventory > Inventory ; // [RH] This actor's inventory
DWORD InventoryID ; // A unique ID to keep track of inventory items
BYTE smokecounter ;
BYTE FloatBobPhase ;
BYTE FriendPlayer ; // [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc)
DWORD Translation ;
// [RH] Stuff that used to be part of an Actor Info
FSoundIDNoInit SeeSound ;
FSoundIDNoInit AttackSound ;
FSoundIDNoInit PainSound ;
FSoundIDNoInit DeathSound ;
FSoundIDNoInit ActiveSound ;
FSoundIDNoInit UseSound ; // [RH] Sound to play when an actor is used.
FSoundIDNoInit BounceSound ;
FSoundIDNoInit WallBounceSound ;
FSoundIDNoInit CrushPainSound ;
2016-03-23 11:21:52 +00:00
double MaxDropOffHeight ;
2016-03-22 11:42:27 +00:00
double MaxStepHeight ;
2016-01-10 16:52:41 +00:00
SDWORD Mass ;
SWORD PainChance ;
int PainThreshold ;
FNameNoInit DamageType ;
FNameNoInit DamageTypeReceived ;
2016-03-21 23:06:58 +00:00
double DamageFactor ;
2016-03-25 15:30:31 +00:00
double DamageMultiply ;
2016-01-10 16:52:41 +00:00
FNameNoInit PainType ;
FNameNoInit DeathType ;
2016-02-04 21:15:29 +00:00
PClassActor * TeleFogSourceType ;
PClassActor * TeleFogDestType ;
2016-01-10 16:52:41 +00:00
int RipperLevel ;
int RipLevelMin ;
int RipLevelMax ;
FState * SpawnState ;
FState * SeeState ;
FState * MeleeState ;
FState * MissileState ;
int ConversationRoot ; // THe root of the current dialogue
FStrifeDialogueNode * Conversation ; // [RH] The dialogue to show when this actor is "used."
// [RH] Decal(s) this weapon/projectile generates on impact.
FDecalBase * DecalGenerator ;
// [RH] Used to interpolate the view to get >35 FPS
2016-03-25 15:25:25 +00:00
DVector3 Prev ;
2016-03-16 11:41:26 +00:00
DRotator PrevAngles ;
2016-02-24 23:41:31 +00:00
int PrevPortalGroup ;
2016-01-10 16:52:41 +00:00
// ThingIDs
static void ClearTIDHashes ( ) ;
void AddToHash ( ) ;
void RemoveFromHash ( ) ;
2016-03-20 20:51:09 +00:00
2016-01-10 16:52:41 +00:00
private :
static AActor * TIDHash [ 128 ] ;
static inline int TIDHASH ( int key ) { return key & 127 ; }
2016-09-18 11:26:34 +00:00
public :
2016-01-10 16:52:41 +00:00
static FSharedStringArena mStringPropertyData ;
2016-09-18 11:26:34 +00:00
private :
2016-01-10 16:52:41 +00:00
friend class FActorIterator ;
friend bool P_IsTIDUsed ( int tid ) ;
2016-02-16 11:51:10 +00:00
bool FixMapthingPos ( ) ;
2016-01-10 16:52:41 +00:00
public :
2016-03-08 13:41:37 +00:00
void LinkToWorld ( bool spawningmapthing = false , sector_t * sector = NULL ) ;
2016-01-10 16:52:41 +00:00
void UnlinkFromWorld ( ) ;
void AdjustFloorClip ( ) ;
bool InStateSequence ( FState * newstate , FState * basestate ) ;
int GetTics ( FState * newstate ) ;
bool SetState ( FState * newstate , bool nofunction = false ) ;
2016-03-26 00:13:36 +00:00
virtual bool UpdateWaterLevel ( bool splash = true ) ;
2016-01-10 16:52:41 +00:00
bool isFast ( ) ;
bool isSlow ( ) ;
void SetIdle ( bool nofunction = false ) ;
void ClearCounters ( ) ;
FState * GetRaiseState ( ) ;
void Revive ( ) ;
2016-09-19 01:36:51 +00:00
void SetDamage ( int dmg )
{
DamageVal = dmg ;
DamageFunc = nullptr ;
}
bool IsZeroDamage ( ) const
{
return DamageVal = = 0 & & DamageFunc = = nullptr ;
}
void RestoreDamage ( )
{
DamageVal = GetDefault ( ) - > DamageVal ;
DamageFunc = GetDefault ( ) - > DamageFunc ;
}
2016-01-10 16:52:41 +00:00
FState * FindState ( FName label ) const
{
2016-02-04 21:15:29 +00:00
return GetClass ( ) - > FindState ( 1 , & label ) ;
2016-01-10 16:52:41 +00:00
}
FState * FindState ( FName label , FName sublabel , bool exact = false ) const
{
FName names [ ] = { label , sublabel } ;
2016-02-04 21:15:29 +00:00
return GetClass ( ) - > FindState ( 2 , names , exact ) ;
2016-01-10 16:52:41 +00:00
}
FState * FindState ( int numnames , FName * names , bool exact = false ) const
{
2016-02-04 21:15:29 +00:00
return GetClass ( ) - > FindState ( numnames , names , exact ) ;
2016-01-10 16:52:41 +00:00
}
bool HasSpecialDeathStates ( ) const ;
2016-01-17 11:23:49 +00:00
2016-03-19 23:54:18 +00:00
double X ( ) const
{
2016-03-25 14:43:20 +00:00
return __Pos . X ;
2016-03-19 23:54:18 +00:00
}
double Y ( ) const
{
2016-03-25 14:43:20 +00:00
return __Pos . Y ;
2016-03-19 23:54:18 +00:00
}
double Z ( ) const
{
2016-03-25 14:43:20 +00:00
return __Pos . Z ;
2016-03-19 23:54:18 +00:00
}
DVector3 Pos ( ) const
{
2016-03-25 14:43:20 +00:00
return __Pos ;
2016-03-19 23:54:18 +00:00
}
2016-03-28 19:04:46 +00:00
// Note: Never compare z directly with a plane height if you want to know if the actor is *on* the plane. Some very minor inaccuracies may creep in. Always use these inline functions!
// Comparing with floorz is ok because those values come from the same calculations.
bool isAbove ( double checkz ) const
{
2016-03-31 14:52:25 +00:00
return Z ( ) > checkz + EQUAL_EPSILON ;
2016-03-28 19:04:46 +00:00
}
bool isBelow ( double checkz ) const
{
2016-03-31 14:52:25 +00:00
return Z ( ) < checkz - EQUAL_EPSILON ;
2016-03-28 19:04:46 +00:00
}
2016-03-30 08:08:06 +00:00
bool isAtZ ( double checkz ) const
2016-03-28 19:04:46 +00:00
{
2016-03-31 14:52:25 +00:00
return fabs ( Z ( ) - checkz ) < EQUAL_EPSILON ;
2016-03-28 19:04:46 +00:00
}
2016-03-19 23:54:18 +00:00
2016-03-25 15:25:25 +00:00
DVector3 PosRelative ( int grp ) const ;
DVector3 PosRelative ( const AActor * other ) const ;
DVector3 PosRelative ( sector_t * sec ) const ;
DVector3 PosRelative ( line_t * line ) const ;
2016-03-25 17:19:54 +00:00
FVector3 SoundPos ( ) const
2016-01-20 00:48:57 +00:00
{
2016-03-31 19:13:32 +00:00
// the sound system switches y and z axes so this function must, too.
2016-03-25 17:19:54 +00:00
// fixme: This still needs portal handling
2016-03-31 19:13:32 +00:00
return { float ( X ( ) ) , float ( Z ( ) ) , float ( Y ( ) ) } ;
2016-01-20 00:48:57 +00:00
}
2016-03-25 15:25:25 +00:00
DVector3 InterpolatedPosition ( double ticFrac ) const
2016-01-19 10:50:07 +00:00
{
2016-03-25 15:25:25 +00:00
return Prev + ( ticFrac * ( Pos ( ) - Prev ) ) ;
2016-01-19 10:50:07 +00:00
}
2016-03-20 09:52:10 +00:00
DVector3 PosPlusZ ( double zadd ) const
{
return { X ( ) , Y ( ) , Z ( ) + zadd } ;
}
DVector3 PosAtZ ( double zadd ) const
{
return { X ( ) , Y ( ) , zadd } ;
}
2016-03-19 23:54:18 +00:00
double Top ( ) const
{
2016-03-20 19:55:06 +00:00
return Z ( ) + Height ;
2016-03-19 23:54:18 +00:00
}
double Center ( ) const
{
2016-03-20 19:55:06 +00:00
return Z ( ) + Height / 2 ;
2016-03-19 23:54:18 +00:00
}
void SetZ ( double newz , bool moving = true )
{
2016-03-25 14:43:20 +00:00
__Pos . Z = newz ;
2016-03-19 23:54:18 +00:00
}
void AddZ ( double newz , bool moving = true )
{
2016-03-25 14:43:20 +00:00
__Pos . Z + = newz ;
2016-03-25 15:25:25 +00:00
if ( ! moving ) Prev . Z = Z ( ) ;
2016-03-19 23:54:18 +00:00
}
2016-01-17 11:23:49 +00:00
2016-03-21 13:00:05 +00:00
void SetXY ( const DVector2 & npos )
{
2016-03-25 14:43:20 +00:00
__Pos . X = npos . X ;
__Pos . Y = npos . Y ;
2016-03-21 13:00:05 +00:00
}
2016-03-20 09:52:10 +00:00
void SetXYZ ( double xx , double yy , double zz )
{
2016-03-25 14:43:20 +00:00
__Pos = { xx , yy , zz } ;
2016-03-20 09:52:10 +00:00
}
void SetXYZ ( const DVector3 & npos )
{
2016-03-25 14:43:20 +00:00
__Pos = npos ;
2016-03-20 09:52:10 +00:00
}
2016-03-16 11:41:26 +00:00
2016-03-19 23:54:18 +00:00
double VelXYToSpeed ( ) const
2016-03-16 11:41:26 +00:00
{
2016-03-19 23:54:18 +00:00
return DVector2 ( Vel . X , Vel . Y ) . Length ( ) ;
2016-03-16 11:41:26 +00:00
}
2016-03-19 23:54:18 +00:00
double VelToSpeed ( ) const
2016-03-16 11:41:26 +00:00
{
2016-03-19 23:54:18 +00:00
return Vel . Length ( ) ;
2016-03-16 11:41:26 +00:00
}
void AngleFromVel ( )
{
2016-03-19 23:54:18 +00:00
Angles . Yaw = VecToAngle ( Vel . X , Vel . Y ) ;
2016-03-16 11:41:26 +00:00
}
void VelFromAngle ( )
{
2016-03-19 23:54:18 +00:00
Vel . X = Speed * Angles . Yaw . Cos ( ) ;
Vel . Y = Speed * Angles . Yaw . Sin ( ) ;
}
void VelFromAngle ( double speed )
{
Vel . X = speed * Angles . Yaw . Cos ( ) ;
Vel . Y = speed * Angles . Yaw . Sin ( ) ;
}
void VelFromAngle ( DAngle angle , double speed )
{
Vel . X = speed * angle . Cos ( ) ;
Vel . Y = speed * angle . Sin ( ) ;
}
void Thrust ( )
{
Vel . X + = Speed * Angles . Yaw . Cos ( ) ;
Vel . Y + = Speed * Angles . Yaw . Sin ( ) ;
2016-03-16 11:41:26 +00:00
}
2016-03-19 23:54:18 +00:00
void Thrust ( double speed )
2016-03-16 11:41:26 +00:00
{
2016-03-19 23:54:18 +00:00
Vel . X + = speed * Angles . Yaw . Cos ( ) ;
Vel . Y + = speed * Angles . Yaw . Sin ( ) ;
2016-03-16 11:41:26 +00:00
}
2016-03-19 23:54:18 +00:00
void Thrust ( DAngle angle , double speed )
2016-03-16 11:41:26 +00:00
{
2016-03-19 23:54:18 +00:00
Vel . X + = speed * angle . Cos ( ) ;
Vel . Y + = speed * angle . Sin ( ) ;
2016-03-16 11:41:26 +00:00
}
2016-03-19 23:54:18 +00:00
void Vel3DFromAngle ( DAngle angle , DAngle pitch , double speed )
2016-03-16 11:41:26 +00:00
{
double cospitch = pitch . Cos ( ) ;
2016-03-19 23:54:18 +00:00
Vel . X = speed * cospitch * angle . Cos ( ) ;
Vel . Y = speed * cospitch * angle . Sin ( ) ;
Vel . Z = speed * - pitch . Sin ( ) ;
2016-03-16 11:41:26 +00:00
}
2016-03-19 23:54:18 +00:00
void Vel3DFromAngle ( DAngle pitch , double speed )
2016-03-16 11:41:26 +00:00
{
double cospitch = pitch . Cos ( ) ;
2016-03-19 23:54:18 +00:00
Vel . X = speed * cospitch * Angles . Yaw . Cos ( ) ;
Vel . Y = speed * cospitch * Angles . Yaw . Sin ( ) ;
Vel . Z = speed * - pitch . Sin ( ) ;
}
// This is used by many vertical velocity calculations.
// Better have it in one place, if something needs to be changed about the formula.
double DistanceBySpeed ( AActor * dest , double speed )
{
return MAX ( 1. , Distance2D ( dest ) / speed ) ;
2016-03-16 11:41:26 +00:00
}
2016-03-21 23:06:58 +00:00
int ApplyDamageFactor ( FName damagetype , int damage ) const ;
2016-01-10 16:52:41 +00:00
} ;
class FActorIterator
{
public :
FActorIterator ( int i ) : base ( NULL ) , id ( i )
{
}
FActorIterator ( int i , AActor * start ) : base ( start ) , id ( i )
{
}
AActor * Next ( )
{
if ( id = = 0 )
return NULL ;
if ( ! base )
base = AActor : : TIDHash [ id & 127 ] ;
else
base = base - > inext ;
while ( base & & base - > tid ! = id )
base = base - > inext ;
return base ;
}
private :
AActor * base ;
int id ;
} ;
template < class T >
class TActorIterator : public FActorIterator
{
public :
TActorIterator ( int id ) : FActorIterator ( id ) { }
T * Next ( )
{
AActor * actor ;
do
{
actor = FActorIterator : : Next ( ) ;
2016-02-04 21:15:29 +00:00
} while ( actor & & ! actor - > IsKindOf ( RUNTIME_TEMPLATE_CLASS ( T ) ) ) ;
2016-01-10 16:52:41 +00:00
return static_cast < T * > ( actor ) ;
}
} ;
class NActorIterator : public FActorIterator
{
const PClass * type ;
public :
NActorIterator ( const PClass * cls , int id ) : FActorIterator ( id ) { type = cls ; }
NActorIterator ( FName cls , int id ) : FActorIterator ( id ) { type = PClass : : FindClass ( cls ) ; }
NActorIterator ( const char * cls , int id ) : FActorIterator ( id ) { type = PClass : : FindClass ( cls ) ; }
AActor * Next ( )
{
AActor * actor ;
if ( type = = NULL ) return NULL ;
do
{
actor = FActorIterator : : Next ( ) ;
} while ( actor & & ! actor - > IsKindOf ( type ) ) ;
return actor ;
}
} ;
bool P_IsTIDUsed ( int tid ) ;
int P_FindUniqueTID ( int start_tid , int limit ) ;
2016-03-23 09:42:41 +00:00
PClassActor * ClassForSpawn ( FName classname ) ;
2016-03-21 13:00:05 +00:00
inline AActor * Spawn ( PClassActor * type )
{
2016-03-23 09:42:41 +00:00
return AActor : : StaticSpawn ( type , DVector3 ( 0 , 0 , 0 ) , NO_REPLACE ) ;
2016-01-17 17:36:14 +00:00
}
2016-03-19 23:54:18 +00:00
inline AActor * Spawn ( PClassActor * type , const DVector3 & pos , replace_t allowreplacement )
{
2016-03-23 09:42:41 +00:00
return AActor : : StaticSpawn ( type , pos , allowreplacement ) ;
2016-03-19 23:54:18 +00:00
}
2016-03-21 13:00:05 +00:00
inline AActor * Spawn ( FName type )
{
2016-03-23 09:42:41 +00:00
return AActor : : StaticSpawn ( ClassForSpawn ( type ) , DVector3 ( 0 , 0 , 0 ) , NO_REPLACE ) ;
2016-01-17 17:36:14 +00:00
}
2016-03-19 23:54:18 +00:00
inline AActor * Spawn ( FName type , const DVector3 & pos , replace_t allowreplacement )
{
2016-03-23 09:42:41 +00:00
return AActor : : StaticSpawn ( ClassForSpawn ( type ) , pos , allowreplacement ) ;
2016-03-19 23:54:18 +00:00
}
2016-03-23 09:42:41 +00:00
template < class T > inline T * Spawn ( const DVector3 & pos , replace_t allowreplacement )
2016-01-17 17:36:14 +00:00
{
2016-03-23 09:42:41 +00:00
return static_cast < T * > ( AActor : : StaticSpawn ( RUNTIME_TEMPLATE_CLASS ( T ) , pos , allowreplacement ) ) ;
2016-01-17 17:36:14 +00:00
}
2016-01-10 16:52:41 +00:00
2016-03-23 09:42:41 +00:00
template < class T > inline T * Spawn ( ) // for inventory items we do not need coordinates and replacement info.
2016-03-21 13:00:05 +00:00
{
2016-03-23 09:42:41 +00:00
return static_cast < T * > ( AActor : : StaticSpawn ( RUNTIME_TEMPLATE_CLASS ( T ) , DVector3 ( 0 , 0 , 0 ) , NO_REPLACE ) ) ;
2016-03-21 13:00:05 +00:00
}
2016-01-10 16:52:41 +00:00
void PrintMiscActorInfo ( AActor * query ) ;
2016-03-27 18:58:01 +00:00
AActor * P_LinePickActor ( AActor * t1 , DAngle angle , double distance , DAngle pitch , ActorFlags actorMask , DWORD wallMask ) ;
2016-01-10 16:52:41 +00:00
2016-03-01 15:38:45 +00:00
// If we want to make P_AimLineAttack capable of handling arbitrary portals, it needs to pass a lot more info than just the linetarget actor.
struct FTranslatedLineTarget
{
AActor * linetarget ;
2016-03-16 11:41:26 +00:00
DAngle angleFromSource ;
2016-03-01 15:38:45 +00:00
bool unlinked ; // found by a trace that went through an unlinked portal.
} ;
2016-01-10 16:52:41 +00:00
# define S_FREETARGMOBJ 1
# endif // __P_MOBJ_H__