From 79055f935812ce658d821cc913fb13f8581a51fb Mon Sep 17 00:00:00 2001 From: div0 Date: Tue, 21 Oct 2008 17:21:36 +0000 Subject: [PATCH] func_breakable: more cleanups, assault merge, entities.def docs hook: onhand hook now is turned off by offhand hook git-svn-id: svn://svn.icculus.org/nexuiz/trunk@4796 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/server/arena.qc | 5 +++ data/qcsrc/server/assault.qc | 55 ++--------------------- data/qcsrc/server/func_breakable.qc | 67 ++++++++++++++++++++++++----- data/qcsrc/server/miscfunctions.qc | 6 +++ data/qcsrc/server/w_hook.qc | 6 +++ data/scripts/entities.def | 19 +++++++- 6 files changed, 95 insertions(+), 63 deletions(-) diff --git a/data/qcsrc/server/arena.qc b/data/qcsrc/server/arena.qc index 972f4475d..bdd2ceac4 100644 --- a/data/qcsrc/server/arena.qc +++ b/data/qcsrc/server/arena.qc @@ -17,6 +17,7 @@ void(entity e) removedecor; void dom_controlpoint_setup(); void onslaught_generator_reset(); void onslaught_controlpoint_reset(); +void func_breakable_reset(); /** * Resets the state of all clients, items, flags, runes, keys, weapons, waypoints, ... of the map. @@ -107,6 +108,10 @@ void reset_map() { self.team = self.team_saved; } + else if(self.classname == "func_breakable" || self.classname == "func_assault_destructible") + { + func_breakable_reset(); + } } // Waypoints come LAST (keyhunt keys reference them) diff --git a/data/qcsrc/server/assault.qc b/data/qcsrc/server/assault.qc index bd4f1ecec..fb2d161a9 100644 --- a/data/qcsrc/server/assault.qc +++ b/data/qcsrc/server/assault.qc @@ -1,3 +1,5 @@ +void spawnfunc_func_breakable(); + //============================================================================= /*QUAKED spawnfunc_info_player_attacker (1 0 0) (-16 -16 -24) (16 16 45) INITIAL @@ -194,59 +196,10 @@ void assault_destructible_reset() { } } -void assault_destructible_use() { - self.cnt = 1; // mark active - self.takedamage = DAMAGE_YES; -} - -void assault_destructible_destroy() { - self.model = ""; - self.takedamage = DAMAGE_NO; - self.solid = SOLID_NOT; - SUB_UseTargets(); -} - -void assault_destructible_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) { - - if(self.cnt > 0 && assault_attacker_team == attacker.team) { - self.health = self.health - damage; - if(self.health / self.max_health < 0.25) - self.colormod = '1 0 0'; - else if(self.health / self.max_health < 0.375) - self.colormod = '1 0.25 0'; - else if(self.health / self.max_health < 0.50) - self.colormod = '1 0.5 0'; - else if(self.health / self.max_health < 0.625) - self.colormod = '1 0.75 0'; - else if(self.health / self.max_health < 0.75) - self.colormod = '1 1 0'; - else - self.colormod = '1 1 1'; - } - - if(self.health < 0) { - activator = attacker; - assault_destructible_destroy(); - } -} - // destructible walls that can be used to trigger target_objective_decrease void spawnfunc_func_assault_destructible() { - if(!self.health) - self.health = 100; - - self.max_health = self.health; - - self.cnt = 0; // not yet activated - - self.classname = "func_assault_destructible"; - self.mdl = self.model; - setmodel(self, self.mdl); - - self.solid = SOLID_BSP; - self.use = assault_destructible_use; - self.event_damage = assault_destructible_damage; - + self.spawnflags = 3; + spawnfunc_func_breakable(); } void assault_wall_think() { diff --git a/data/qcsrc/server/func_breakable.qc b/data/qcsrc/server/func_breakable.qc index c0c8614e5..5c6ff6f39 100644 --- a/data/qcsrc/server/func_breakable.qc +++ b/data/qcsrc/server/func_breakable.qc @@ -8,6 +8,10 @@ // count = particle effect multiplier // targetname = target to trigger to unbreak the model // target = targets to trigger when broken +// health = amount of damage it can take +// spawnflags: +// 1 = start disabled (needs to be triggered to activate) +// 2 = indicate damage // notes: // for mdl_dead to work, origin must be set (using a common/origin brush). // Otherwise mdl_dead will be displayed at the map origin, and nobody would @@ -43,7 +47,21 @@ void LaunchDebris (string debrisname) = SUB_SetFade(dbr, time + 1 + random() * 5, 1); }; -void func_breakable_make_destroyed() +void func_breakable_colormod() +{ + float h; + if not(self.spawnflags & 2) + return; + h = self.health / self.max_health; + if(h < 0.25) + self.colormod = '1 0 0'; + else if(h <= 0.75) + self.colormod = '1 0 0' + '0 1 0' * (2 * h - 0.5); + else + self.colormod = '1 1 1'; +} + +void func_breakable_look_destroyed() { if(self.mdl_dead == "") { @@ -55,28 +73,50 @@ void func_breakable_make_destroyed() setmodel(self, self.mdl_dead); self.solid = SOLID_BSP; } +} + +void func_breakable_look_restore() +{ + setmodel(self, self.mdl); + self.solid = SOLID_BSP; +} + +void func_breakable_behave_destroyed() +{ self.health = self.max_health; self.takedamage = DAMAGE_NO; self.event_damage = SUB_Null; self.state = 1; setsize(self, '0 0 0', '0 0 0'); + func_breakable_colormod(); } -void func_breakable_restore() +void func_breakable_behave_restore() { - setmodel(self, self.mdl); - self.solid = SOLID_BSP; self.health = self.max_health; self.takedamage = DAMAGE_AIM; self.event_damage = func_breakable_damage; self.state = 0; setsize(self, self.mins_save, self.maxs_save); + func_breakable_colormod(); +} + +void func_breakable_destroyed() +{ + func_breakable_look_destroyed(); + func_breakable_behave_destroyed(); +} + +void func_breakable_restore() +{ + func_breakable_look_restore(); + func_breakable_behave_restore(); } void func_breakable_destroy() { float n, i; - func_breakable_make_destroyed(); + func_breakable_destroyed(); // now throw around the debris n = tokenize_sane(self.debris); @@ -99,6 +139,16 @@ void func_breakable_damage(entity inflictor, entity attacker, float damage, floa activator = attacker; func_breakable_destroy(); } + func_breakable_colormod(); +} + +void func_breakable_reset() +{ + func_breakable_look_restore(); + if(self.spawnflags & 1) + func_breakable_behave_destroyed(); + else + func_breakable_behave_restore(); } // destructible walls that can be used to trigger target_objective_decrease @@ -127,10 +177,5 @@ void spawnfunc_func_breakable() { for(i = 0; i < n; ++i) precache_model(argv(i)); - self.event_damage = func_breakable_damage; - - if(self.state) - func_breakable_make_destroyed(); - else - func_breakable_restore(); + func_breakable_reset(); } diff --git a/data/qcsrc/server/miscfunctions.qc b/data/qcsrc/server/miscfunctions.qc index 3ac46262c..31723dc62 100644 --- a/data/qcsrc/server/miscfunctions.qc +++ b/data/qcsrc/server/miscfunctions.qc @@ -840,6 +840,12 @@ void readplayerstartcvars() } } } + + if(g_grappling_hook) // offhand hook + { + start_weapons (-) WEP_HOOK; + warmup_start_weapons (-) WEP_HOOK; + } } void readlevelcvars(void) diff --git a/data/qcsrc/server/w_hook.qc b/data/qcsrc/server/w_hook.qc index 023b787ed..69156726d 100644 --- a/data/qcsrc/server/w_hook.qc +++ b/data/qcsrc/server/w_hook.qc @@ -58,6 +58,12 @@ void W_Hook_Attack2() void spawnfunc_weapon_hook (void) { + if(g_grappling_hook) // offhand hook + { + startitem_failed = TRUE; + remove(self); + return; + } weapon_defaultspawnfunc(WEP_HOOK); } diff --git a/data/scripts/entities.def b/data/scripts/entities.def index b5135ee7d..08a5d68d8 100644 --- a/data/scripts/entities.def +++ b/data/scripts/entities.def @@ -1059,7 +1059,7 @@ FLOATING: the item will float in air, instead of aligning to the floor by fallin model="models/weapons/g_porto.md3" */ -/*QUAKED target_items (0 0 1) ? AND OR ANDNOT +/*QUAKED target_items (0 0 1) (-8 -8 -8) (8 8 8) AND OR ANDNOT Sets the items of any player who triggers this. For the number fields, not specifying a value means not changing it. To clear armor, you need to explicitly set "armor" to "-1". You may want to target this by a race checkpoint, a teleporter, or a trigger_multiple with ALLENTS set (so it removes weapons thrown through the field to avoid getting a weapon through it). @@ -1115,3 +1115,20 @@ target: when set, target_spawn edits entities, instead of creating new ones -------- SPAWNFLAGS -------- ONLOAD: create a first entity on map load */ + +/*QUAKED func_breakable (1 0 0) ? DISABLED INDICATE +This is a brush model which can be damaged. +Once all health is consumed it'll disappear and trigger the targeted entity/entities. +When triggered, it resets to full health, and unbreaks. +-------- KEYS -------- +health: The damage this trigger can take +target: The entity/entities to be triggered once this entity gets invisible +targetname: The name other entities can use to target this entity +mdl: particle effect name to show when destroyed +count: particle effect multiplier +mdl_dead: optional replacement model to show when destroyed +debris: names of debris models to show when destroyed, separated by spaces +-------- SPAWNFLAGS -------- +DISABLED: do not allow damaging this until it is first activated +INDICATE: indicate amount of damage already taken by coloring +*/ -- 2.39.2