diff --git a/src/client/refresh/files/models.c b/src/client/refresh/files/models.c index 961b7ccc..9a3ac14f 100644 --- a/src/client/refresh/files/models.c +++ b/src/client/refresh/files/models.c @@ -1138,7 +1138,7 @@ Mod_LoadAliasModel ================= */ void * -Mod_LoadAliasModel (const char *mod_name, const void *buffer, int modfilelen, +Mod_LoadAliasModel(const char *mod_name, const void *buffer, int modfilelen, vec3_t mins, vec3_t maxs, struct image_s **skins, findimage_t find_image, modtype_t *type) { @@ -1235,17 +1235,76 @@ Mod_LoadSP2 (const char *mod_name, const void *buffer, int modfilelen, return extradata; } +static int +Mod_LoadFileWithoutExt(const char *namewe, void **buffer, const char* ext) +{ + char newname[256]; + size_t tlen; + + *buffer = NULL; + + tlen = strlen(namewe); + + if (!strcmp(ext, "fm") || + !strcmp(ext, "dkm") || + !strcmp(ext, "md2") || + !strcmp(ext, "mdl")) + { + int filesize, len; + + /* Check Heretic2 model */ + Q_strlcpy(newname, namewe, sizeof(newname)); + Q_strlcat(newname, ".fm", sizeof(newname)); + filesize = ri.FS_LoadFile(newname, buffer); + if (filesize > 0) + { + return filesize; + } + + /* Check Quake 2 model */ + Q_strlcpy(newname + tlen, ".md2", sizeof(newname)); + filesize = ri.FS_LoadFile(newname, buffer); + if (filesize > 0) + { + return filesize; + } + + /* Check Daikatana model */ + Q_strlcpy(newname + tlen, ".dkm", sizeof(newname)); + filesize = ri.FS_LoadFile(newname, buffer); + if (filesize > 0) + { + return filesize; + } + + /* Check Quake model */ + Q_strlcpy(newname + tlen, ".mdl", sizeof(newname)); + filesize = ri.FS_LoadFile(newname, buffer); + if (filesize > 0) + { + return filesize; + } + } + + Q_strlcpy(newname, namewe, sizeof(newname)); + Q_strlcat(newname, ".", sizeof(newname)); + Q_strlcat(newname, ext, sizeof(newname)); + + return ri.FS_LoadFile(newname, buffer); +} + /* ================= Mod_LoadFile ================= */ int -Mod_LoadFile(char *name, void **buffer) +Mod_LoadFile(const char *name, void **buffer) { + char namewe[256]; const char* ext; - - *buffer = NULL; + int filesize, len; + size_t tlen; if (!name) { @@ -1259,59 +1318,46 @@ Mod_LoadFile(char *name, void **buffer) return -1; } - if (!strcmp(ext, "fm") || - !strcmp(ext, "dkm") || - !strcmp(ext, "md2") || - !strcmp(ext, "mdl")) + len = strlen(name); + if (len < 5) { - char namewe[256], newname[256]; - int filesize, len; - - len = strlen(name); - if (len < 5) - { - return -1; - } - - /* Remove the extension */ - size_t tlen = len - (strlen(ext) + 1); - memset(namewe, 0, 256); - memcpy(namewe, name, tlen); - - /* Check Heretic2 model */ - Q_strlcpy(newname, namewe, sizeof(newname)); - Q_strlcat(newname, ".fm", sizeof(newname)); - filesize = ri.FS_LoadFile (newname, buffer); - if (filesize > 0) - { - return filesize; - } - - /* Check Quake 2 model */ - Q_strlcpy(newname + tlen, ".md2", sizeof(newname)); - filesize = ri.FS_LoadFile (newname, buffer); - if (filesize > 0) - { - return filesize; - } - - /* Check Daikatana model */ - Q_strlcpy(newname + tlen, ".dkm", sizeof(newname)); - filesize = ri.FS_LoadFile (newname, buffer); - if (filesize > 0) - { - return filesize; - } - - /* Check Quake model */ - Q_strlcpy(newname + tlen, ".mdl", sizeof(newname)); - filesize = ri.FS_LoadFile (newname, buffer); - if (filesize > 0) - { - return filesize; - } + return -1; } - return ri.FS_LoadFile (name, buffer); + + /* Remove the extension */ + tlen = len - (strlen(ext) + 1); + memset(namewe, 0, 256); + memcpy(namewe, name, tlen); + + filesize = Mod_LoadFileWithoutExt(namewe, buffer, ext); + if (filesize > 0) + { + return filesize; + } + + /* Replacement of ReRelease models */ + if (!strcmp(namewe, "models/monsters/soldierh/tris")) + { + filesize = Mod_LoadFileWithoutExt("models/monsters/soldier/tris", + buffer, ext); + } + else if (!strcmp(namewe, "models/monsters/gladb/tris")) + { + filesize = Mod_LoadFileWithoutExt("models/monsters/gladiatr/tris", + buffer, ext); + } + else if (!strcmp(namewe, "models/monsters/boss5/tris")) + { + filesize = Mod_LoadFileWithoutExt("models/monsters/boss1/tris", + buffer, ext); + } + else if (!strcmp(namewe, "models/monsters/bitch2/tris")) + { + filesize = Mod_LoadFileWithoutExt("models/monsters/bitch/tris", + buffer, ext); + } + + return filesize; } /* diff --git a/src/client/refresh/ref_shared.h b/src/client/refresh/ref_shared.h index c990cb1c..a55adf08 100644 --- a/src/client/refresh/ref_shared.h +++ b/src/client/refresh/ref_shared.h @@ -358,7 +358,7 @@ extern const void *Mod_LoadBSPXFindLump(const bspx_header_t *bspx_header, const char *lumpname, int *plumpsize, const byte *mod_base); extern const bspx_header_t *Mod_LoadBSPX(int filesize, const byte *mod_base); extern int Mod_LoadBSPXDecoupledLM(const dlminfo_t* lminfos, int surfnum, msurface_t *out); -extern int Mod_LoadFile(char *name, void **buffer); +extern int Mod_LoadFile(const char *name, void **buffer); /* Surface logic */ #define DLIGHT_CUTOFF 64 diff --git a/src/game/g_spawn.c b/src/game/g_spawn.c index bc6d47e1..162436fb 100644 --- a/src/game/g_spawn.c +++ b/src/game/g_spawn.c @@ -131,6 +131,7 @@ void SP_misc_easterchick2(edict_t *self); void SP_monster_berserk(edict_t *self); void SP_monster_gladiator(edict_t *self); void SP_monster_gunner(edict_t *self); +void SP_monster_guncmdr(edict_t *self); void SP_monster_infantry(edict_t *self); void SP_monster_soldier_light(edict_t *self); void SP_monster_soldier(edict_t *self); @@ -316,6 +317,7 @@ static spawn_t spawns[] = { {"monster_berserk", SP_monster_berserk}, {"monster_gladiator", SP_monster_gladiator}, {"monster_gunner", SP_monster_gunner}, + {"monster_guncmdr", SP_monster_guncmdr}, {"monster_infantry", SP_monster_infantry}, {"monster_soldier_light", SP_monster_soldier_light}, {"monster_soldier", SP_monster_soldier}, diff --git a/src/game/monster/chick/chick.c b/src/game/monster/chick/chick.c index 3046a398..a79e217b 100644 --- a/src/game/monster/chick/chick.c +++ b/src/game/monster/chick/chick.c @@ -1206,7 +1206,7 @@ SP_monster_chick(edict_t *self) self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; - self->s.modelindex = gi.modelindex("models/monsters/bitch/tris.md2"); + self->s.modelindex = gi.modelindex("models/monsters/bitch2/tris.md2"); VectorSet(self->mins, -16, -16, 0); VectorSet(self->maxs, 16, 16, 56); diff --git a/src/game/monster/gunner/gunner.c b/src/game/monster/gunner/gunner.c index 377bc83d..e09a301e 100644 --- a/src/game/monster/gunner/gunner.c +++ b/src/game/monster/gunner/gunner.c @@ -1410,3 +1410,71 @@ SP_monster_gunner(edict_t *self) self->monsterinfo.blindfire = true; walkmonster_start(self); } + +/* + * QUAKED monster_guncmdr (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight NoJumping + */ +void +SP_monster_guncmdr(edict_t *self) +{ + if (!self) + { + return; + } + + if (deathmatch->value) + { + G_FreeEdict(self); + return; + } + + // Force recaching at next footstep to ensure + // that the sound indices are correct. + sound_step = 0; + sound_step2 = 0; + + sound_death = gi.soundindex("guncmdr/gcdrdeath1.wav"); + sound_pain = gi.soundindex("guncmdr/gcdrpain2.wav"); + sound_pain2 = gi.soundindex("guncmdr/gcdrpain1.wav"); + sound_idle = gi.soundindex("guncmdr/gcdridle1.wav"); + sound_open = gi.soundindex("guncmdr/gcdratck1.wav"); + sound_search = gi.soundindex("guncmdr/gcdrsrch1.wav"); + sound_sight = gi.soundindex("guncmdr/sight1.wav"); + + gi.soundindex("guncmdr/gcdratck2.wav"); + gi.soundindex("guncmdr/gcdratck3.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + self->s.modelindex = gi.modelindex("models/monsters/gunner/tris.md2"); + VectorSet(self->mins, -16, -16, -24); + VectorSet(self->maxs, 16, 16, 32); + + self->health = 175; + self->gib_health = -70; + self->mass = 200; + + self->pain = gunner_pain; + self->die = gunner_die; + + self->monsterinfo.stand = gunner_stand; + self->monsterinfo.walk = gunner_walk; + self->monsterinfo.run = gunner_run; + self->monsterinfo.dodge = gunner_dodge; + self->monsterinfo.duck = gunner_duck; + self->monsterinfo.unduck = monster_duck_up; + self->monsterinfo.sidestep = gunner_sidestep; + self->monsterinfo.attack = gunner_attack; + self->monsterinfo.melee = NULL; + self->monsterinfo.sight = gunner_sight; + self->monsterinfo.search = gunner_search; + self->monsterinfo.blocked = gunner_blocked; + + gi.linkentity(self); + + self->monsterinfo.currentmove = &gunner_move_stand; + self->monsterinfo.scale = MODEL_SCALE; + + self->monsterinfo.blindfire = true; + walkmonster_start(self); +} diff --git a/src/game/savegame/tables/gamefunc_decs.h b/src/game/savegame/tables/gamefunc_decs.h index 9f5d51a4..65c903b3 100644 --- a/src/game/savegame/tables/gamefunc_decs.h +++ b/src/game/savegame/tables/gamefunc_decs.h @@ -639,6 +639,7 @@ extern void hover_reattack ( edict_t * self ) ; extern void hover_search ( edict_t * self ) ; extern void hover_sight ( edict_t * self , edict_t * other ) ; extern void SP_monster_gunner ( edict_t * self ) ; +extern void SP_monster_guncmdr ( edict_t * self ) ; extern void gunner_footstep( edict_t *self ) ; extern void gunner_sidestep ( edict_t * self ) ; extern void gunner_duck ( edict_t * self , float eta ) ; diff --git a/src/game/savegame/tables/gamefunc_list.h b/src/game/savegame/tables/gamefunc_list.h index eef7c473..3c8d632c 100644 --- a/src/game/savegame/tables/gamefunc_list.h +++ b/src/game/savegame/tables/gamefunc_list.h @@ -641,6 +641,7 @@ {"hover_search", (byte *)hover_search}, {"hover_sight", (byte *)hover_sight}, {"SP_monster_gunner", (byte *)SP_monster_gunner}, +{"SP_monster_guncmdr", (byte *)SP_monster_guncmdr}, {"gunner_footstep", (byte *)gunner_footstep}, {"gunner_sidestep", (byte *)gunner_sidestep}, {"gunner_duck", (byte *)gunner_duck},