From 4e22fc255dee9de1d5ae0e9f71b49a240ab7a5be Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 26 Dec 2024 00:35:09 +0200 Subject: [PATCH] game: add misc_player_mannequin from ReRelease code Based on: https://github.com/Paril/quake2-rerelease-dll.git --- README.md | 1 - src/game/g_misc.c | 214 ++++++++++++++++++++++ src/game/header/local.h | 3 + src/game/savegame/tables/fields.h | 13 +- src/game/savegame/tables/gamefunc_decs.h | 2 + src/game/savegame/tables/gamefunc_list.h | 2 + src/game/savegame/tables/spawnfunc_decs.h | 1 + src/game/savegame/tables/spawnfunc_list.h | 1 + 8 files changed, 231 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 93491e02a..384409a2a 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,6 @@ Goals, fully finished goals could be checked in [here](CHANGELOG): * [ ] Rearange surfaces in vulkan render before render, * [ ] Fully implement `target_camera`, * [ ] Fully implement `misc_flare`, -* [ ] Fully implement `misc_player_mannequin`, * [ ] Single player ReRelease support, * [ ] Support effects and additional flags for ReRelease when possible. * [ ] Use shared model cache in client code insted reimplemnet in each render, diff --git a/src/game/g_misc.c b/src/game/g_misc.c index 56a0594df..bdbcec23b 100644 --- a/src/game/g_misc.c +++ b/src/game/g_misc.c @@ -26,6 +26,7 @@ */ #include "header/local.h" +#include "monster/misc/player.h" int debristhisframe; int gibsthisframe; @@ -3351,6 +3352,219 @@ SP_misc_flare(edict_t* ent) gi.linkentity(ent); } +void +misc_player_mannequin_use(edict_t * self, edict_t * other, edict_t * activator) +{ + self->monsterinfo.aiflags |= AI_TARGET_ANGER; + self->enemy = activator; + + switch ( self->count ) + { + case GESTURE_FLIP_OFF: + self->s.frame = FRAME_flip01; + self->monsterinfo.nextframe = FRAME_flip12; + break; + + case GESTURE_SALUTE: + self->s.frame = FRAME_salute01; + self->monsterinfo.nextframe = FRAME_salute11; + break; + + case GESTURE_TAUNT: + self->s.frame = FRAME_taunt01; + self->monsterinfo.nextframe = FRAME_taunt17; + break; + + case GESTURE_WAVE: + self->s.frame = FRAME_wave01; + self->monsterinfo.nextframe = FRAME_wave11; + break; + + case GESTURE_POINT: + self->s.frame = FRAME_point01; + self->monsterinfo.nextframe = FRAME_point12; + break; + } +} + +void +misc_player_mannequin_think(edict_t * self) +{ + if (self->last_sound_time <= level.time) + { + self->s.frame++; + + if ((self->monsterinfo.aiflags & AI_TARGET_ANGER) == 0) + { + if (self->s.frame > FRAME_stand40) + { + self->s.frame = FRAME_stand01; + } + } + else + { + if (self->s.frame > self->monsterinfo.nextframe) + { + self->s.frame = FRAME_stand01; + self->monsterinfo.aiflags &= ~AI_TARGET_ANGER; + self->enemy = NULL; + } + } + + self->last_sound_time = level.time + FRAMETIME; + } + + if (self->enemy) + { + vec3_t vec; + + VectorSubtract(self->enemy->s.origin, self->s.origin, vec); + self->ideal_yaw = vectoyaw(vec); + M_ChangeYaw(self); + } + + self->nextthink = level.time + FRAMETIME; +} + +void +SetupMannequinModel(edict_t * self, int modelType, const char *weapon, const char *skin) +{ + const char *model_name = NULL; + const char *default_skin = NULL; + + switch (modelType) + { + case 1: + { + self->s.skinnum = (MAX_CLIENTS - 1); + model_name = "female"; + default_skin = "venus"; + break; + } + + case 2: + { + self->s.skinnum = (MAX_CLIENTS - 2); + model_name = "male"; + default_skin = "rampage"; + break; + } + + case 3: + { + self->s.skinnum = (MAX_CLIENTS - 3); + model_name = "cyborg"; + default_skin = "oni911"; + break; + } + + default: + { + self->s.skinnum = (MAX_CLIENTS - 1); + model_name = "female"; + default_skin = "venus"; + break; + } + } + + if (model_name) + { + char line[MAX_QPATH] = {0}; + + snprintf(line, sizeof(line), "players/%s/tris.md2", model_name); + self->model = ED_NewString(line, true); + + if (weapon) + { + snprintf(line, sizeof(line), "players/%s/%s.md2", model_name, weapon); + } + else + { + snprintf(line, sizeof(line), "players/%s/w_hyperblaster.md2", model_name); + } + self->s.modelindex2 = gi.modelindex(line); + + if (skin) + { + snprintf(line, sizeof(line), "%s/%s", model_name, skin); + } + else + { + snprintf(line, sizeof(line), "%s/%s", model_name, default_skin); + } + gi.configstring(CS_PLAYERSKINS + self->s.skinnum, line); + } +} + +/* + * QUAKED misc_player_mannequin (1.0 1.0 0.0) (-32 -32 -32) (32 32 32) + * Creates a player mannequin that stands around. + * + * NOTE: this is currently very limited, and only allows one unique model + * from each of the three player model types. + * + * + * "distance" - Sets the type of gesture mannequin when use when triggered + * "height" - Sets the type of model to use ( valid numbers: 1 - 3 ) + * "goals" - Name of the weapon to use. + * "image" - Name of the player skin to use. + * "radius" - How much to scale the model in-game + */ +void +SP_misc_player_mannequin(edict_t * self) +{ + int i; + + self->movetype = MOVETYPE_NONE; + self->solid = SOLID_BBOX; + if (!st.effects) + { + self->s.effects = 0; + } + + if (!st.renderfx) + { + self->s.renderfx = RF_MINLIGHT; + } + + VectorSet(self->mins, -16, -16, -24); + VectorSet(self->maxs, 16, 16, 32); + self->yaw_speed = 30; + self->ideal_yaw = 0; + self->last_sound_time = level.time + FRAMETIME; + self->s.modelindex = CUSTOM_PLAYER_MODEL; + self->count = st.distance; + + SetupMannequinModel(self, st.height, st.goals, st.image); + + VectorSet(self->rrs.scale, 1.0f, 1.0f, 1.0f); + if (ai_model_scale->value > 0.0f) + { + VectorSet(self->rrs.scale, + ai_model_scale->value, ai_model_scale->value, ai_model_scale->value); + } + else if (st.radius > 0.0f) + { + VectorSet(self->rrs.scale, + st.radius, st.radius, st.radius); + } + + for (i = 0;i < 3; i++) + { + self->mins[i] *= self->rrs.scale[i]; + self->maxs[i] *= self->rrs.scale[i]; + } + + self->think = misc_player_mannequin_think; + self->nextthink = level.time + FRAMETIME; + + if (self->targetname) + { + self->use = misc_player_mannequin_use; + } + + gi.linkentity(self); +} /* * QUAKED misc_model (1 0 0) (-8 -8 -8) (8 8 8) diff --git a/src/game/header/local.h b/src/game/header/local.h index 3fdf2a2dc..00d8207fd 100644 --- a/src/game/header/local.h +++ b/src/game/header/local.h @@ -422,6 +422,9 @@ typedef struct float fade_end_dist; char *image; unsigned rgba; + char *goals; + int effects; + int renderfx; /* Addional fields for models */ vec3_t scale; diff --git a/src/game/savegame/tables/fields.h b/src/game/savegame/tables/fields.h index 402560105..11d7ae591 100644 --- a/src/game/savegame/tables/fields.h +++ b/src/game/savegame/tables/fields.h @@ -58,14 +58,17 @@ {"origin", FOFS(s.origin), F_VECTOR}, {"angles", FOFS(s.angles), F_VECTOR}, {"angle", FOFS(s.angles), F_ANGLEHACK}, +{"effects", STOFS(effects), F_INT, FFL_SPAWNTEMP}, +{"fade_end_dist", STOFS(fade_end_dist), F_FLOAT, FFL_SPAWNTEMP}, +{"fade_start_dist", STOFS(fade_start_dist), F_FLOAT, FFL_SPAWNTEMP}, +{"goals", STOFS(goals), F_LRAWSTRING, FFL_SPAWNTEMP}, {"health_multiplier", STOFS(health_multiplier), F_FLOAT, FFL_SPAWNTEMP}, -{"rgb", STOFS(rgba), F_RGBA, FFL_SPAWNTEMP}, +{"image", STOFS(image), F_LRAWSTRING, FFL_SPAWNTEMP}, +{"radius", STOFS(radius), F_FLOAT, FFL_SPAWNTEMP}, +{"renderfx", STOFS(renderfx), F_INT, FFL_SPAWNTEMP}, {"rgba", STOFS(rgba), F_RGBA, FFL_SPAWNTEMP}, +{"rgb", STOFS(rgba), F_RGBA, FFL_SPAWNTEMP}, {"scale", STOFS(scale), F_VECTOR, FFL_SPAWNTEMP}, -{"radius", STOFS(radius), F_FLOAT, FFL_SPAWNTEMP}, -{"fade_start_dist", STOFS(fade_start_dist), F_FLOAT, FFL_SPAWNTEMP}, -{"fade_end_dist", STOFS(fade_end_dist), F_FLOAT, FFL_SPAWNTEMP}, -{"image", STOFS(image), F_LRAWSTRING, FFL_SPAWNTEMP}, {"goalentity", FOFS(goalentity), F_EDICT, FFL_NOSPAWN}, {"movetarget", FOFS(movetarget), F_EDICT, FFL_NOSPAWN}, {"enemy", FOFS(enemy), F_EDICT, FFL_NOSPAWN}, diff --git a/src/game/savegame/tables/gamefunc_decs.h b/src/game/savegame/tables/gamefunc_decs.h index 0b8183ecc..d3112635d 100644 --- a/src/game/savegame/tables/gamefunc_decs.h +++ b/src/game/savegame/tables/gamefunc_decs.h @@ -1031,6 +1031,8 @@ extern void misc_easterchick_think ( edict_t * self ) ; extern void misc_eastertank_think ( edict_t * self ) ; extern void misc_nuke_core_use ( edict_t * self , edict_t * other , edict_t * activator ) ; extern void misc_flare_use ( edict_t * self , edict_t * other , edict_t * activator ) ; +extern void misc_player_mannequin_use ( edict_t * self , edict_t * other , edict_t * activator ) ; +extern void misc_player_mannequin_think ( edict_t * self ) ; extern void misc_satellite_dish_think ( edict_t * self ) ; extern void misc_satellite_dish_use ( edict_t * self , edict_t * other , edict_t * activator ) ; extern void misc_strogg_ship_use ( edict_t * self , edict_t * other , edict_t * activator ) ; diff --git a/src/game/savegame/tables/gamefunc_list.h b/src/game/savegame/tables/gamefunc_list.h index 9033225b9..b8f93a5dc 100644 --- a/src/game/savegame/tables/gamefunc_list.h +++ b/src/game/savegame/tables/gamefunc_list.h @@ -1009,6 +1009,8 @@ {"misc_eastertank_think", (byte *)misc_eastertank_think}, {"misc_nuke_core_use", (byte *)misc_nuke_core_use}, {"misc_flare_use", (byte *)misc_flare_use}, +{"misc_player_mannequin_use", (byte *)misc_player_mannequin_use}, +{"misc_player_mannequin_think", (byte *)misc_player_mannequin_think}, {"misc_satellite_dish_think", (byte *)misc_satellite_dish_think}, {"misc_satellite_dish_use", (byte *)misc_satellite_dish_use}, {"misc_strogg_ship_use", (byte *)misc_strogg_ship_use}, diff --git a/src/game/savegame/tables/spawnfunc_decs.h b/src/game/savegame/tables/spawnfunc_decs.h index b56313fc0..b13bd17a9 100644 --- a/src/game/savegame/tables/spawnfunc_decs.h +++ b/src/game/savegame/tables/spawnfunc_decs.h @@ -93,6 +93,7 @@ extern void SP_misc_nuke ( edict_t * ent ) ; extern void SP_misc_nuke_core ( edict_t * ent ) ; extern void SP_misc_flare ( edict_t * ent ) ; extern void SP_misc_model ( edict_t * ent ) ; +extern void SP_misc_player_mannequin ( edict_t * ent ) ; extern void SP_misc_satellite_dish ( edict_t * ent ) ; extern void SP_misc_strogg_ship ( edict_t * ent ) ; extern void SP_misc_teleporter ( edict_t * ent ) ; diff --git a/src/game/savegame/tables/spawnfunc_list.h b/src/game/savegame/tables/spawnfunc_list.h index 69c99f84b..0ecbbe36c 100644 --- a/src/game/savegame/tables/spawnfunc_list.h +++ b/src/game/savegame/tables/spawnfunc_list.h @@ -98,6 +98,7 @@ {"misc_nuke_core", SP_misc_nuke_core}, {"misc_flare", SP_misc_flare}, {"misc_model", SP_misc_model}, +{"misc_player_mannequin", SP_misc_player_mannequin}, {"misc_satellite_dish", SP_misc_satellite_dish}, {"misc_strogg_ship", SP_misc_strogg_ship}, {"misc_teleporter", SP_misc_teleporter},