diff --git a/README.md b/README.md index 94fca28..4271d12 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ A legendary 90s era Quake 3 Arena mod. - [x] ~~Bind key to toggle speed (ki boost). HINT: HASTE POWERUP~~ - [x] ~~Replace ammo to ki energy stamina~~ - [x] ~~Third person traceable crosshair~~ +- [x] ~~Breakable map entities ("func_breakable")~~ - [ ] Make ki energy regeneration, ki use, attacks, charging balance indicated on old docs - [ ] Powerlevel and Power Tiers indicated on old docs - [x] ~~Hit Stun (makes player can't use ki, melee, block and charge)~~ diff --git a/source/game/g_combat.c b/source/game/g_combat.c index d02469e..4e54411 100644 --- a/source/game/g_combat.c +++ b/source/game/g_combat.c @@ -676,6 +676,14 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, if ( targ->use && targ->moverState == MOVER_POS1 ) { targ->use( targ, inflictor, attacker ); } + // BFP - For breakable map entities + if ( targ->takedamage && targ->health > 0 ) { + if ( damage < 1 ) { + damage = 1; + } + take = damage; + targ->health = targ->health - take; + } return; } // reduce damage by the attacker's handicap value diff --git a/source/game/g_mover.c b/source/game/g_mover.c index c496b10..4a9bd27 100644 --- a/source/game/g_mover.c +++ b/source/game/g_mover.c @@ -1574,3 +1574,20 @@ void SP_func_pendulum(gentity_t *ent) { ent->s.apos.trType = TR_SINE; ent->s.apos.trDelta[2] = speed; } + + +// BFP - Breakable map entities +void func_breakable_use( gentity_t *ent, gentity_t *other, gentity_t *activator ) { + if ( ent->health <= 0 ) { + G_FreeEntity( ent ); + } +} + +void SP_func_breakable( gentity_t *ent ) { + trap_SetBrushModel( ent, ent->model ); + ent->s.eType = ET_MOVER; + ent->r.contents = CONTENTS_SOLID; + ent->health = 100; + ent->takedamage = qtrue; + ent->use = func_breakable_use; +} diff --git a/source/game/g_spawn.c b/source/game/g_spawn.c index dfd193c..217c361 100644 --- a/source/game/g_spawn.c +++ b/source/game/g_spawn.c @@ -143,6 +143,7 @@ void SP_func_button (gentity_t *ent); void SP_func_door (gentity_t *ent); void SP_func_train (gentity_t *ent); void SP_func_timer (gentity_t *self); +void SP_func_breakable (gentity_t *ent); // BFP - Breakable map entities void SP_trigger_always (gentity_t *ent); void SP_trigger_multiple (gentity_t *ent); @@ -186,7 +187,7 @@ void SP_team_CTF_blueplayer( gentity_t *ent ); void SP_team_CTF_redspawn( gentity_t *ent ); void SP_team_CTF_bluespawn( gentity_t *ent ); -void SP_item_botroam( gentity_t *ent ) {}; +void SP_item_botroam( gentity_t *ent ) { (void)ent; } spawn_t spawns[] = { // info entities don't do anything at all, but provide positional @@ -207,6 +208,7 @@ spawn_t spawns[] = { {"func_pendulum", SP_func_pendulum}, {"func_train", SP_func_train}, {"func_group", SP_info_null}, + {"func_breakable", SP_func_breakable}, // BFP - Breakable map entities {"func_timer", SP_func_timer}, // rename trigger_timer? // Triggers are brush objects that cause an effect when contacted diff --git a/source/game/g_weapon.c b/source/game/g_weapon.c index b7190e0..a4671db 100644 --- a/source/game/g_weapon.c +++ b/source/game/g_weapon.c @@ -177,6 +177,12 @@ qboolean CheckMeleeAttack( gentity_t *attacker ) { // BFP - Melee return qfalse; } + // avoid if the entity isn't a player (e.g. a breakable map entity) + if ( traceTarget->s.eType != ET_PLAYER ) { + attacker->client->ps.pm_flags &= ~PMF_MELEE; + return qfalse; + } + // the target's corpse is starting to sink, avoid interacting with a sinking corpse, nothing special happens if ( traceTarget->physicsObject ) { attacker->client->ps.pm_flags &= ~PMF_MELEE;