/* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers Copyright (C) 2019 Alison G. Watson 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef spingle__pr_edict_h #define spingle__pr_edict_h #define EDICT_FROM_AREA(l) (edict_t *)((byte *)(l) - offsetof(edict_t, area)) #define ED_Float(e, o) (((float *)((edict_t *)e)->fields)[o]) #define ED_Int(e, o) (((int32_t *)((edict_t *)e)->fields)[o]) #define ED_Edict(e, o) ProgEdict(ED_Int(e, o)) #define ED_EdictNum(e, o) NumForEdict(ED_Edict(e, o)) #define ED_Vector(e, o) (&ED_Float(e, o)) #define ED_String(e, o) PR_GetString(ED_RString(e, o)) #define ED_RString(e, o) (*(string_t *)&ED_Int(e, o)) #define ED_Func(e, o) (*(func_t *)&ED_Int(e, o)) #define ED_PEdict(e, o) (*(pedict_t *)&ED_Int(e, o)) #define ED_PField(e, o) (*(pfield_t *)&ED_Int(e, o)) #define ED_Eval(e, o) ((eval_t *)&ED_Int(e, o)) #define ED_Void(e, o) ((void *)&ED_Int(o)) enum { MAX_ENT_LEAFS = 32 }; enum { ED_modelindex, ED_absmin, ED_absmax = ED_absmin + 3, ED_ltime = ED_absmax + 3, ED_movetype, ED_solid, ED_origin, ED_oldorigin = ED_origin + 3, ED_velocity = ED_oldorigin + 3, ED_angles = ED_velocity + 3, ED_avelocity = ED_angles + 3, ED_punchangle = ED_avelocity + 3, ED_classname = ED_punchangle + 3, ED_model, ED_frame, ED_skin, ED_effects, ED_mins, ED_maxs = ED_mins + 3, ED_size = ED_maxs + 3, ED_touch = ED_size + 3, ED_use, ED_think, ED_blocked, ED_nextthink, ED_groundentity, ED_health, ED_frags, ED_weapon, ED_weaponmodel, ED_weaponframe, ED_currentammo, ED_ammo_shells, ED_ammo_nails, ED_ammo_rockets, ED_ammo_cells, ED_items, ED_takedamage, ED_chain, ED_deadflag, ED_view_ofs, ED_button0 = ED_view_ofs + 3, ED_button1, ED_button2, ED_impulse, ED_fixangle, ED_v_angle, ED_idealpitch = ED_v_angle + 3, ED_netname, ED_enemy, ED_flags, ED_colormap, ED_team, ED_max_health, ED_teleport_time, ED_armortype, ED_armorvalue, ED_waterlevel, ED_watertype, ED_ideal_yaw, ED_yaw_speed, ED_aiment, ED_goalentity, ED_spawnflags, ED_target, ED_targetname, ED_dmg_take, ED_dmg_save, ED_dmg_inflictor, ED_owner, ED_movedir, ED_message = ED_movedir + 3, ED_sounds, ED_noise, ED_noise1, ED_noise2, ED_noise3, ED_SYSTEM_END, }; typedef struct edict_s { bool free; link_t area; /* linked to a division node or leaf */ int32_t num_leafs; int32_t leafnums[MAX_ENT_LEAFS]; entity_state_t baseline; uint8_t alpha; bool sendinterval; /* johnfitz -- send time until nextthink to client for better lerp timing */ float freetime; /* sv.time when the object was freed */ byte fields[]; } edict_t; extern ddef_t *pr_fielddefs; extern int32_t pr_edict_size; edict_t *ED_Alloc(void); void ED_Free(edict_t *ed); void ED_Print(edict_t *ed); void ED_Write(FILE *f, edict_t *ed); const char *ED_ParseEdict(const char *data, edict_t *ent); void ED_WriteGlobals(FILE *f); const char *ED_ParseGlobals(const char *data); void ED_LoadFromFile(const char *data); ddef_t *ED_GlobalAtOfs(int32_t ofs); ddef_t *ED_FieldAtOfs(int32_t ofs); bool ED_ParseEpair(void *base, ddef_t *key, const char *s); void ED_Init(void); void ED_Load(void); void ED_PrintEdicts(void); void ED_PrintNum(int32_t ent); eval_t *GetEdictFieldValue(edict_t *ed, const char *field); static inline edict_t *NextEdict(edict_t *e) { return (edict_t *)((byte *)e + pr_edict_size); } pedict_t EdictProg(void *e); void *ProgEdict(pedict_t e); edict_t *EdictNum(int32_t n); int32_t NumForEdict(edict_t *e); #endif