/* * Copyright (C) 1997-2001 Id Software, Inc. * * 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. * * ======================================================================= * * Main header file for the game module. * * ======================================================================= */ #ifndef GAME_LOCAL_H #define GAME_LOCAL_H #include "../../common/header/shared.h" /* define GAME_INCLUDE so that game.h does not define the short, server-visible gclient_t and edict_t structures, because we define the full size ones in this file */ #define GAME_INCLUDE #include "game.h" /* the "gameversion" client command will print this plus compile date */ #define GAMEVERSION "baseq2" /* protocol bytes that can be directly added to messages */ #define svc_muzzleflash 1 #define svc_muzzleflash2 2 #define svc_temp_entity 3 #define svc_layout 4 #define svc_inventory 5 #define svc_stufftext 11 /* ================================================================== */ /* view pitching times */ #define DAMAGE_TIME 0.5 #define FALL_TIME 0.3 /* these are set with checkboxes on each entity in the map editor */ #define SPAWNFLAG_NOT_EASY 0x00000100 #define SPAWNFLAG_NOT_MEDIUM 0x00000200 #define SPAWNFLAG_NOT_HARD 0x00000400 #define SPAWNFLAG_NOT_DEATHMATCH 0x00000800 #define SPAWNFLAG_NOT_COOP 0x00001000 #define FL_FLY 0x00000001 #define FL_SWIM 0x00000002 /* implied immunity to drowining */ #define FL_IMMUNE_LASER 0x00000004 #define FL_INWATER 0x00000008 #define FL_GODMODE 0x00000010 #define FL_NOTARGET 0x00000020 #define FL_IMMUNE_SLIME 0x00000040 #define FL_IMMUNE_LAVA 0x00000080 #define FL_PARTIALGROUND 0x00000100 /* not all corners are valid */ #define FL_WATERJUMP 0x00000200 /* player jumping out of water */ #define FL_TEAMSLAVE 0x00000400 /* not the first on the team */ #define FL_NO_KNOCKBACK 0x00000800 #define FL_POWER_ARMOR 0x00001000 /* power armor (if any) is active */ #define FL_RESPAWN 0x80000000 /* used for item respawning */ #define FRAMETIME 0.1 /* memory tags to allow dynamic memory to be cleaned up */ #define TAG_GAME 765 /* clear when unloading the dll */ #define TAG_LEVEL 766 /* clear when loading a new level */ #define MELEE_DISTANCE 80 #define BODY_QUEUE_SIZE 8 typedef enum { DAMAGE_NO, DAMAGE_YES, /* will take damage if hit */ DAMAGE_AIM /* auto targeting recognizes this */ } damage_t; typedef enum { WEAPON_READY, WEAPON_ACTIVATING, WEAPON_DROPPING, WEAPON_FIRING } weaponstate_t; typedef enum { AMMO_BULLETS, AMMO_SHELLS, AMMO_ROCKETS, AMMO_GRENADES, AMMO_CELLS, AMMO_SLUGS } ammo_t; /* deadflag */ #define DEAD_NO 0 #define DEAD_DYING 1 #define DEAD_DEAD 2 #define DEAD_RESPAWNABLE 3 /* range */ #define RANGE_MELEE 0 #define RANGE_NEAR 1 #define RANGE_MID 2 #define RANGE_FAR 3 /* gib types */ #define GIB_ORGANIC 0 #define GIB_METALLIC 1 /* monster ai flags */ #define AI_STAND_GROUND 0x00000001 #define AI_TEMP_STAND_GROUND 0x00000002 #define AI_SOUND_TARGET 0x00000004 #define AI_LOST_SIGHT 0x00000008 #define AI_PURSUIT_LAST_SEEN 0x00000010 #define AI_PURSUE_NEXT 0x00000020 #define AI_PURSUE_TEMP 0x00000040 #define AI_HOLD_FRAME 0x00000080 #define AI_GOOD_GUY 0x00000100 #define AI_BRUTAL 0x00000200 #define AI_NOSTEP 0x00000400 #define AI_DUCKED 0x00000800 #define AI_COMBAT_POINT 0x00001000 #define AI_MEDIC 0x00002000 #define AI_RESURRECTING 0x00004000 /* monster attack state */ #define AS_STRAIGHT 1 #define AS_SLIDING 2 #define AS_MELEE 3 #define AS_MISSILE 4 /* armor types */ #define ARMOR_NONE 0 #define ARMOR_JACKET 1 #define ARMOR_COMBAT 2 #define ARMOR_BODY 3 #define ARMOR_SHARD 4 /* power armor types */ #define POWER_ARMOR_NONE 0 #define POWER_ARMOR_SCREEN 1 #define POWER_ARMOR_SHIELD 2 /* handedness values */ #define RIGHT_HANDED 0 #define LEFT_HANDED 1 #define CENTER_HANDED 2 /* game.serverflags values */ #define SFL_CROSS_TRIGGER_1 0x00000001 #define SFL_CROSS_TRIGGER_2 0x00000002 #define SFL_CROSS_TRIGGER_3 0x00000004 #define SFL_CROSS_TRIGGER_4 0x00000008 #define SFL_CROSS_TRIGGER_5 0x00000010 #define SFL_CROSS_TRIGGER_6 0x00000020 #define SFL_CROSS_TRIGGER_7 0x00000040 #define SFL_CROSS_TRIGGER_8 0x00000080 #define SFL_CROSS_TRIGGER_MASK 0x000000ff /* noise types for PlayerNoise */ #define PNOISE_SELF 0 #define PNOISE_WEAPON 1 #define PNOISE_IMPACT 2 /* edict->movetype values */ typedef enum { MOVETYPE_NONE, /* never moves */ MOVETYPE_NOCLIP, /* origin and angles change with no interaction */ MOVETYPE_PUSH, /* no clip to world, push on box contact */ MOVETYPE_STOP, /* no clip to world, stops on box contact */ MOVETYPE_WALK, /* gravity */ MOVETYPE_STEP, /* gravity, special edge handling */ MOVETYPE_FLY, MOVETYPE_TOSS, /* gravity */ MOVETYPE_FLYMISSILE, /* extra size to monsters */ MOVETYPE_BOUNCE } movetype_t; typedef struct { int base_count; int max_count; float normal_protection; float energy_protection; int armor; } gitem_armor_t; #define IT_WEAPON 1 /* use makes active weapon */ #define IT_AMMO 2 #define IT_ARMOR 4 #define IT_STAY_COOP 8 #define IT_KEY 16 #define IT_POWERUP 32 /* gitem_t->weapmodel for weapons indicates model index */ #define WEAP_BLASTER 1 #define WEAP_SHOTGUN 2 #define WEAP_SUPERSHOTGUN 3 #define WEAP_MACHINEGUN 4 #define WEAP_CHAINGUN 5 #define WEAP_GRENADES 6 #define WEAP_GRENADELAUNCHER 7 #define WEAP_ROCKETLAUNCHER 8 #define WEAP_HYPERBLASTER 9 #define WEAP_RAILGUN 10 #define WEAP_BFG 11 typedef struct gitem_s { char *classname; /* spawning name */ qboolean (*pickup)(struct edict_s *ent, struct edict_s *other); void (*use)(struct edict_s *ent, struct gitem_s *item); void (*drop)(struct edict_s *ent, struct gitem_s *item); void (*weaponthink)(struct edict_s *ent); char *pickup_sound; char *world_model; int world_model_flags; char *view_model; /* client side info */ char *icon; char *pickup_name; /* for printing on pickup */ int count_width; /* number of digits to display by icon */ int quantity; /* for ammo how much, for weapons how much is used per shot */ char *ammo; /* for weapons */ int flags; /* IT_* flags */ int weapmodel; /* weapon model index (for weapons) */ void *info; int tag; char *precaches; /* string of all models, sounds, and images this item will use */ } gitem_t; /* this structure is left intact through an entire game it should be initialized at dll load time, and read/written to the server.ssv file for savegames */ typedef struct { char helpmessage1[512]; char helpmessage2[512]; int helpchanged; /* flash F1 icon if non 0, play sound and increment only if 1, 2, or 3 */ gclient_t *clients; /* [maxclients] */ /* can't store spawnpoint in level, because it would get overwritten by the savegame restore */ char spawnpoint[512]; /* needed for coop respawns */ /* store latched cvars here that we want to get at often */ int maxclients; int maxentities; /* cross level triggers */ int serverflags; /* items */ int num_items; qboolean autosaved; } game_locals_t; /* this structure is cleared as each map is entered it is read/written to the level.sav file for savegames */ typedef struct { int framenum; float time; char level_name[MAX_QPATH]; /* the descriptive name (Outer Base, etc) */ char mapname[MAX_QPATH]; /* the server name (base1, etc) */ char nextmap[MAX_QPATH]; /* go here when fraglimit is hit */ /* intermission state */ float intermissiontime; /* time the intermission was started */ char *changemap; int exitintermission; vec3_t intermission_origin; vec3_t intermission_angle; edict_t *sight_client; /* changed once each frame for coop games */ edict_t *sight_entity; int sight_entity_framenum; edict_t *sound_entity; int sound_entity_framenum; edict_t *sound2_entity; int sound2_entity_framenum; int pic_health; int total_secrets; int found_secrets; int total_goals; int found_goals; int total_monsters; int killed_monsters; edict_t *current_entity; /* entity running from G_RunFrame */ int body_que; /* dead bodies */ int power_cubes; /* ugly necessity for coop */ } level_locals_t; /* spawn_temp_t is only used to hold entity field values that can be set from the editor, but aren't actualy present in edict_t during gameplay */ typedef struct { /* world vars */ char *sky; float skyrotate; vec3_t skyaxis; char *nextmap; int lip; int distance; int height; char *noise; float pausetime; char *item; char *gravity; float minyaw; float maxyaw; float minpitch; float maxpitch; } spawn_temp_t; typedef struct { /* fixed data */ vec3_t start_origin; vec3_t start_angles; vec3_t end_origin; vec3_t end_angles; int sound_start; int sound_middle; int sound_end; float accel; float speed; float decel; float distance; float wait; /* state data */ int state; vec3_t dir; float current_speed; float move_speed; float next_speed; float remaining_distance; float decel_distance; void (*endfunc)(edict_t *); } moveinfo_t; typedef struct { void (*aifunc)(edict_t *self, float dist); float dist; void (*thinkfunc)(edict_t *self); } mframe_t; typedef struct { int firstframe; int lastframe; mframe_t *frame; void (*endfunc)(edict_t *self); } mmove_t; typedef struct { mmove_t *currentmove; int aiflags; int nextframe; float scale; void (*stand)(edict_t *self); void (*idle)(edict_t *self); void (*search)(edict_t *self); void (*walk)(edict_t *self); void (*run)(edict_t *self); void (*dodge)(edict_t *self, edict_t *other, float eta); void (*attack)(edict_t *self); void (*melee)(edict_t *self); void (*sight)(edict_t *self, edict_t *other); qboolean (*checkattack)(edict_t *self); float pausetime; float attack_finished; vec3_t saved_goal; float search_time; float trail_time; vec3_t last_sighting; int attack_state; int lefty; float idle_time; int linkcount; int power_armor_type; int power_armor_power; } monsterinfo_t; extern game_locals_t game; extern level_locals_t level; extern game_import_t gi; extern game_export_t globals; extern spawn_temp_t st; extern int sm_meat_index; extern int snd_fry; /* means of death */ #define MOD_UNKNOWN 0 #define MOD_BLASTER 1 #define MOD_SHOTGUN 2 #define MOD_SSHOTGUN 3 #define MOD_MACHINEGUN 4 #define MOD_CHAINGUN 5 #define MOD_GRENADE 6 #define MOD_G_SPLASH 7 #define MOD_ROCKET 8 #define MOD_R_SPLASH 9 #define MOD_HYPERBLASTER 10 #define MOD_RAILGUN 11 #define MOD_BFG_LASER 12 #define MOD_BFG_BLAST 13 #define MOD_BFG_EFFECT 14 #define MOD_HANDGRENADE 15 #define MOD_HG_SPLASH 16 #define MOD_WATER 17 #define MOD_SLIME 18 #define MOD_LAVA 19 #define MOD_CRUSH 20 #define MOD_TELEFRAG 21 #define MOD_FALLING 22 #define MOD_SUICIDE 23 #define MOD_HELD_GRENADE 24 #define MOD_EXPLOSIVE 25 #define MOD_BARREL 26 #define MOD_BOMB 27 #define MOD_EXIT 28 #define MOD_SPLASH 29 #define MOD_TARGET_LASER 30 #define MOD_TRIGGER_HURT 31 #define MOD_HIT 32 #define MOD_TARGET_BLASTER 33 #define MOD_FRIENDLY_FIRE 0x8000000 extern int meansOfDeath; extern edict_t *g_edicts; #define FOFS(x) (size_t)&(((edict_t *)NULL)->x) #define STOFS(x) (size_t)&(((spawn_temp_t *)NULL)->x) #define LLOFS(x) (size_t)&(((level_locals_t *)NULL)->x) #define CLOFS(x) (size_t)&(((gclient_t *)NULL)->x) #define random() ((rand() & 0x7fff) / ((float)0x7fff)) #define crandom() (2.0 * (random() - 0.5)) extern cvar_t *maxentities; extern cvar_t *deathmatch; extern cvar_t *coop; extern cvar_t *dmflags; extern cvar_t *skill; extern cvar_t *fraglimit; extern cvar_t *timelimit; extern cvar_t *password; extern cvar_t *spectator_password; extern cvar_t *needpass; extern cvar_t *g_select_empty; extern cvar_t *dedicated; extern cvar_t *filterban; extern cvar_t *sv_gravity; extern cvar_t *sv_maxvelocity; extern cvar_t *gun_x, *gun_y, *gun_z; extern cvar_t *sv_rollspeed; extern cvar_t *sv_rollangle; extern cvar_t *run_pitch; extern cvar_t *run_roll; extern cvar_t *bob_up; extern cvar_t *bob_pitch; extern cvar_t *bob_roll; extern cvar_t *sv_cheats; extern cvar_t *maxclients; extern cvar_t *maxspectators; extern cvar_t *flood_msgs; extern cvar_t *flood_persecond; extern cvar_t *flood_waitdelay; extern cvar_t *sv_maplist; #define world (&g_edicts[0]) /* item spawnflags */ #define ITEM_TRIGGER_SPAWN 0x00000001 #define ITEM_NO_TOUCH 0x00000002 /* 6 bits reserved for editor flags */ /* 8 bits used as power cube id bits for coop games */ #define DROPPED_ITEM 0x00010000 #define DROPPED_PLAYER_ITEM 0x00020000 #define ITEM_TARGETS_USED 0x00040000 /* fields are needed for spawning from the entity string and saving / loading games */ #define FFL_SPAWNTEMP 1 #define FFL_NOSPAWN 2 typedef enum { F_INT, F_FLOAT, F_LSTRING, /* string on disk, pointer in memory, TAG_LEVEL */ F_GSTRING, /* string on disk, pointer in memory, TAG_GAME */ F_VECTOR, F_ANGLEHACK, F_EDICT, /* index on disk, pointer in memory */ F_ITEM, /* index on disk, pointer in memory */ F_CLIENT, /* index on disk, pointer in memory */ F_FUNCTION, F_MMOVE, F_IGNORE } fieldtype_t; typedef struct { char *name; int ofs; fieldtype_t type; int flags; } field_t; extern field_t fields[]; extern gitem_t itemlist[]; /* g_cmds.c */ void Cmd_Help_f(edict_t *ent); void Cmd_Score_f(edict_t *ent); /* g_items.c */ void PrecacheItem(gitem_t *it); void InitItems(void); void SetItemNames(void); gitem_t *FindItem(char *pickup_name); gitem_t *FindItemByClassname(char *classname); #define ITEM_INDEX(x) ((x) - itemlist) edict_t *Drop_Item(edict_t *ent, gitem_t *item); void SetRespawn(edict_t *ent, float delay); void ChangeWeapon(edict_t *ent); void SpawnItem(edict_t *ent, gitem_t *item); void Think_Weapon(edict_t *ent); int ArmorIndex(edict_t *ent); int PowerArmorType(edict_t *ent); gitem_t *GetItemByIndex(int index); qboolean Add_Ammo(edict_t *ent, gitem_t *item, int count); void Touch_Item(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf); /* g_utils.c */ qboolean KillBox(edict_t *ent); void G_ProjectSource(vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result); edict_t *G_Find(edict_t *from, int fieldofs, char *match); edict_t *findradius(edict_t *from, vec3_t org, float rad); edict_t *G_PickTarget(char *targetname); void G_UseTargets(edict_t *ent, edict_t *activator); void G_SetMovedir(vec3_t angles, vec3_t movedir); void G_InitEdict(edict_t *e); edict_t *G_Spawn(void); void G_FreeEdict(edict_t *e); void G_TouchTriggers(edict_t *ent); void G_TouchSolids(edict_t *ent); char *G_CopyString(char *in); float *tv(float x, float y, float z); char *vtos(vec3_t v); float vectoyaw(vec3_t vec); void vectoangles(vec3_t vec, vec3_t angles); /* g_combat.c */ qboolean OnSameTeam(edict_t *ent1, edict_t *ent2); qboolean CanDamage(edict_t *targ, edict_t *inflictor); void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod); void T_RadiusDamage(edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod); /* damage flags */ #define DAMAGE_RADIUS 0x00000001 /* damage was indirect */ #define DAMAGE_NO_ARMOR 0x00000002 /* armour does not protect from this damage */ #define DAMAGE_ENERGY 0x00000004 /* damage is from an energy based weapon */ #define DAMAGE_NO_KNOCKBACK 0x00000008 /* do not affect velocity, just view angles */ #define DAMAGE_BULLET 0x00000010 /* damage is from a bullet (used for ricochets) */ #define DAMAGE_NO_PROTECTION 0x00000020 /* armor, shields, invulnerability, and godmode have no effect */ #define DEFAULT_BULLET_HSPREAD 300 #define DEFAULT_BULLET_VSPREAD 500 #define DEFAULT_SHOTGUN_HSPREAD 1000 #define DEFAULT_SHOTGUN_VSPREAD 500 #define DEFAULT_DEATHMATCH_SHOTGUN_COUNT 12 #define DEFAULT_SHOTGUN_COUNT 12 #define DEFAULT_SSHOTGUN_COUNT 20 /* g_monster.c */ void monster_fire_bullet(edict_t *self, vec3_t start, vec3_t dir, int damage, int kick, int hspread, int vspread, int flashtype); void monster_fire_shotgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int flashtype); void monster_fire_blaster(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype, int effect); void monster_fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int flashtype); void monster_fire_rocket(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype); void monster_fire_railgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int flashtype); void monster_fire_bfg(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int kick, float damage_radius, int flashtype); void M_droptofloor(edict_t *ent); void monster_think(edict_t *self); void walkmonster_start(edict_t *self); void swimmonster_start(edict_t *self); void flymonster_start(edict_t *self); void AttackFinished(edict_t *self, float time); void monster_death_use(edict_t *self); void M_CatagorizePosition(edict_t *ent); qboolean M_CheckAttack(edict_t *self); void M_FlyCheck(edict_t *self); void M_CheckGround(edict_t *ent); /* g_misc.c */ void ThrowHead(edict_t *self, char *gibname, int damage, int type); void ThrowClientHead(edict_t *self, int damage); void ThrowGib(edict_t *self, char *gibname, int damage, int type); void BecomeExplosion1(edict_t *self); /* g_ai.c */ void AI_SetSightClient(void); void ai_stand(edict_t *self, float dist); void ai_move(edict_t *self, float dist); void ai_walk(edict_t *self, float dist); void ai_turn(edict_t *self, float dist); void ai_run(edict_t *self, float dist); void ai_charge(edict_t *self, float dist); int range(edict_t *self, edict_t *other); void FoundTarget(edict_t *self); qboolean infront(edict_t *self, edict_t *other); qboolean visible(edict_t *self, edict_t *other); qboolean FacingIdeal(edict_t *self); /* g_weapon.c */ void ThrowDebris(edict_t *self, char *modelname, float speed, vec3_t origin); qboolean fire_hit(edict_t *self, vec3_t aim, int damage, int kick); void fire_bullet(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod); void fire_shotgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int mod); void fire_blaster(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int effect, qboolean hyper); void fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius); void fire_grenade2(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean held); void fire_rocket(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage); void fire_rail(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick); void fire_bfg(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius); /* g_ptrail.c */ void PlayerTrail_Init(void); void PlayerTrail_Add(vec3_t spot); void PlayerTrail_New(vec3_t spot); edict_t *PlayerTrail_PickFirst(edict_t *self); edict_t *PlayerTrail_PickNext(edict_t *self); edict_t *PlayerTrail_LastSpot(void); /* g_client.c */ void respawn(edict_t *ent); void BeginIntermission(edict_t *targ); void PutClientInServer(edict_t *ent); void InitClientPersistant(gclient_t *client); void InitClientResp(gclient_t *client); void InitBodyQue(void); void ClientBeginServerFrame(edict_t *ent); /* g_player.c */ void player_pain(edict_t *self, edict_t *other, float kick, int damage); void player_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); /* g_svcmds.c */ void ServerCommand(void); qboolean SV_FilterPacket(char *from); /* p_view.c */ void ClientEndServerFrame(edict_t *ent); /* p_hud.c */ void MoveClientToIntermission(edict_t *client); void G_SetStats(edict_t *ent); void G_SetSpectatorStats(edict_t *ent); void G_CheckChaseStats(edict_t *ent); void ValidateSelectedItem(edict_t *ent); void DeathmatchScoreboardMessage(edict_t *client, edict_t *killer); /* g_pweapon.c */ void PlayerNoise(edict_t *who, vec3_t where, int type); /* m_move.c */ qboolean M_CheckBottom(edict_t *ent); qboolean M_walkmove(edict_t *ent, float yaw, float dist); void M_MoveToGoal(edict_t *ent, float dist); void M_ChangeYaw(edict_t *ent); /* g_phys.c */ void G_RunEntity(edict_t *ent); /* g_main.c */ void SaveClientData(void); void FetchClientEntData(edict_t *ent); /* g_chase.c */ void UpdateChaseCam(edict_t *ent); void ChaseNext(edict_t *ent); void ChasePrev(edict_t *ent); void GetChaseTarget(edict_t *ent); /* ============================================================================ */ /* client_t->anim_priority */ #define ANIM_BASIC 0 /* stand / run */ #define ANIM_WAVE 1 #define ANIM_JUMP 2 #define ANIM_PAIN 3 #define ANIM_ATTACK 4 #define ANIM_DEATH 5 #define ANIM_REVERSE 6 /* client data that stays across multiple level loads */ typedef struct { char userinfo[MAX_INFO_STRING]; char netname[16]; int hand; qboolean connected; /* a loadgame will leave valid entities that just don't have a connection yet */ /* values saved and restored from edicts when changing levels */ int health; int max_health; int savedFlags; int selected_item; int inventory[MAX_ITEMS]; /* ammo capacities */ int max_bullets; int max_shells; int max_rockets; int max_grenades; int max_cells; int max_slugs; gitem_t *weapon; gitem_t *lastweapon; int power_cubes; /* used for tracking the cubes in coop games */ int score; /* for calculating total unit score in coop games */ int game_helpchanged; int helpchanged; qboolean spectator; /* client is a spectator */ } client_persistant_t; /* client data that stays across deathmatch respawns */ typedef struct { client_persistant_t coop_respawn; /* what to set client->pers to on a respawn */ int enterframe; /* level.framenum the client entered the game */ int score; /* frags, etc */ vec3_t cmd_angles; /* angles sent over in the last command */ qboolean spectator; /* client is a spectator */ } client_respawn_t; /* this structure is cleared on each PutClientInServer(), except for 'client->pers' */ struct gclient_s { /* known to server */ player_state_t ps; /* communicated by server to clients */ int ping; /* private to game */ client_persistant_t pers; client_respawn_t resp; pmove_state_t old_pmove; /* for detecting out-of-pmove changes */ qboolean showscores; /* set layout stat */ qboolean showinventory; /* set layout stat */ qboolean showhelp; qboolean showhelpicon; int ammo_index; int buttons; int oldbuttons; int latched_buttons; qboolean weapon_thunk; gitem_t *newweapon; /* sum up damage over an entire frame, so shotgun blasts give a single big kick */ int damage_armor; /* damage absorbed by armor */ int damage_parmor; /* damage absorbed by power armor */ int damage_blood; /* damage taken out of health */ int damage_knockback; /* impact damage */ vec3_t damage_from; /* origin for vector calculation */ float killer_yaw; /* when dead, look at killer */ weaponstate_t weaponstate; vec3_t kick_angles; /* weapon kicks */ vec3_t kick_origin; float v_dmg_roll, v_dmg_pitch, v_dmg_time; /* damage kicks */ float fall_time, fall_value; /* for view drop on fall */ float damage_alpha; float bonus_alpha; vec3_t damage_blend; vec3_t v_angle; /* aiming direction */ float bobtime; /* so off-ground doesn't change it */ vec3_t oldviewangles; vec3_t oldvelocity; float next_drown_time; int old_waterlevel; int breather_sound; int machinegun_shots; /* for weapon raising */ /* animation vars */ int anim_end; int anim_priority; qboolean anim_duck; qboolean anim_run; /* powerup timers */ float quad_framenum; float invincible_framenum; float breather_framenum; float enviro_framenum; qboolean grenade_blew_up; float grenade_time; int silencer_shots; int weapon_sound; float pickup_msg_time; float flood_locktill; /* locked from talking */ float flood_when[10]; /* when messages were said */ int flood_whenhead; /* head pointer for when said */ float respawn_time; /* can respawn when time > this */ edict_t *chase_target; /* player we are chasing */ qboolean update_chase; /* need to update chase info? */ }; struct edict_s { entity_state_t s; struct gclient_s *client; /* NULL if not a player the server expects the first part of gclient_s to be a player_state_t but the rest of it is opaque */ qboolean inuse; int linkcount; link_t area; /* linked to a division node or leaf */ int num_clusters; /* if -1, use headnode instead */ int clusternums[MAX_ENT_CLUSTERS]; int headnode; /* unused if num_clusters != -1 */ int areanum, areanum2; /* ================================ */ int svflags; vec3_t mins, maxs; vec3_t absmin, absmax, size; solid_t solid; int clipmask; edict_t *owner; /* DO NOT MODIFY ANYTHING ABOVE THIS, THE SERVER */ /* EXPECTS THE FIELDS IN THAT ORDER! */ /* ================================ */ int movetype; int flags; char *model; float freetime; /* sv.time when the object was freed */ /* only used locally in game, not by server */ char *message; char *classname; int spawnflags; float timestamp; float angle; /* set in qe3, -1 = up, -2 = down */ char *target; char *targetname; char *killtarget; char *team; char *pathtarget; char *deathtarget; char *combattarget; edict_t *target_ent; float speed, accel, decel; vec3_t movedir; vec3_t pos1, pos2; vec3_t velocity; vec3_t avelocity; int mass; float air_finished; float gravity; /* per entity gravity multiplier (1.0 is normal) use for lowgrav artifact, flares */ edict_t *goalentity; edict_t *movetarget; float yaw_speed; float ideal_yaw; float nextthink; void (*prethink)(edict_t *ent); void (*think)(edict_t *self); void (*blocked)(edict_t *self, edict_t *other); void (*touch)(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf); void (*use)(edict_t *self, edict_t *other, edict_t *activator); void (*pain)(edict_t *self, edict_t *other, float kick, int damage); void (*die)(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); float touch_debounce_time; float pain_debounce_time; float damage_debounce_time; float fly_sound_debounce_time; float last_move_time; int health; int max_health; int gib_health; int deadflag; qboolean show_hostile; float powerarmor_time; char *map; /* target_changelevel */ int viewheight; /* height above origin where eyesight is determined */ int takedamage; int dmg; int radius_dmg; float dmg_radius; int sounds; /* make this a spawntemp var? */ int count; edict_t *chain; edict_t *enemy; edict_t *oldenemy; edict_t *activator; edict_t *groundentity; int groundentity_linkcount; edict_t *teamchain; edict_t *teammaster; edict_t *mynoise; /* can go in client only */ edict_t *mynoise2; int noise_index; int noise_index2; float volume; float attenuation; /* timing variables */ float wait; float delay; /* before firing targets */ float random; float teleport_time; int watertype; int waterlevel; vec3_t move_origin; vec3_t move_angles; /* move this to clientinfo? */ int light_level; int style; /* also used as areaportal number */ gitem_t *item; /* for bonus items */ /* common data blocks */ moveinfo_t moveinfo; monsterinfo_t monsterinfo; }; #endif /* GAME_LOCAL_H */