X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fmutators%2Fmutator_nades.qc;h=515d3901dea02fb65ecb11fb2d12b493799558ab;hp=f3a1d65d6e822f9da239b513713e4bd053802c22;hb=f8287888da112f1cd5d711903be8f840ff9f0d70;hpb=6d4676deaeb394208f035725157e0c5c429f4da9 diff --git a/qcsrc/server/mutators/mutator_nades.qc b/qcsrc/server/mutators/mutator_nades.qc index f3a1d65d6..515d3901d 100644 --- a/qcsrc/server/mutators/mutator_nades.qc +++ b/qcsrc/server/mutators/mutator_nades.qc @@ -1,20 +1,16 @@ -.entity nade; -.entity fake_nade; -.float nade_refire; - void nade_timer_think() { self.skin = 8 - (self.owner.wait - time) / (autocvar_g_nades_nade_lifetime / 10); self.nextthink = time; if(!self.owner || wasfreed(self.owner)) remove(self); - + } void nade_burn_spawn(entity _nade) { float p; - + switch(_nade.realowner.team) { case NUM_TEAM_1: p = PROJECTILE_NADE_RED_BURN; break; @@ -23,7 +19,7 @@ void nade_burn_spawn(entity _nade) case NUM_TEAM_4: p = PROJECTILE_NADE_PINK_BURN; break; default: p = PROJECTILE_NADE_BURN; break; } - + CSQCProjectile(_nade, TRUE, p, TRUE); } @@ -39,9 +35,9 @@ void nade_spawn(entity _nade) timer.think = nade_timer_think; timer.nextthink = time; timer.wait = _nade.wait; - timer.owner = _nade; + timer.owner = _nade; timer.skin = 10; - + switch(_nade.realowner.team) { case NUM_TEAM_1: p = PROJECTILE_NADE_RED; break; @@ -50,15 +46,15 @@ void nade_spawn(entity _nade) case NUM_TEAM_4: p = PROJECTILE_NADE_PINK; break; default: p = PROJECTILE_NADE; break; } - + CSQCProjectile(_nade, TRUE, p, TRUE); - + } -void nade_boom() // TODO: DamageInfo +void nade_boom() { string expef; - + switch(self.realowner.team) { case NUM_TEAM_1: expef = "nade_red_explode"; break; @@ -67,14 +63,16 @@ void nade_boom() // TODO: DamageInfo case NUM_TEAM_4: expef = "nade_pink_explode"; break; default: expef = "nade_explode"; break; } - - sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTN_NORM); - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); + + sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM); + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); pointparticles(particleeffectnum(expef), self.origin + '0 0 1', '0 0 0', 1); + Damage_DamageInfo(self.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, self.projectiledeathtype, 0, self); + self.takedamage = DAMAGE_NO; RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, - autocvar_g_nades_nade_radius, self, autocvar_g_nades_nade_force, self.projectiledeathtype, self.enemy); + autocvar_g_nades_nade_radius, self, world, autocvar_g_nades_nade_force, self.projectiledeathtype, self.enemy); remove(self); } @@ -82,11 +80,11 @@ void nade_boom() // TODO: DamageInfo void nade_touch() { PROJECTILE_TOUCH; - setsize(self, '-2 -2 -2', '2 2 2'); - UpdateCSQCProjectile(self); - if(self.health == autocvar_g_nades_nade_health) + //setsize(self, '-2 -2 -2', '2 2 2'); + //UpdateCSQCProjectile(self); + if(self.health == self.max_health) { - spamsound(self, CH_SHOTS, strcat("weapons/grenade_bounce", ftos(1 + rint(random() * 5)), ".wav"), VOL_BASE, ATTN_NORM); + spamsound(self, CH_SHOTS, strcat("weapons/grenade_bounce", ftos(1 + rint(random() * 5)), ".wav"), VOL_BASE, ATTEN_NORM); return; } @@ -96,42 +94,42 @@ void nade_touch() void nade_beep() { - sound(self, CH_SHOTS_SINGLE, "overkill/grenadebip.ogg", VOL_BASE, 0.5 *(ATTN_LARGE + ATTN_MAX)); + sound(self, CH_SHOTS_SINGLE, "overkill/grenadebip.ogg", VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX)); self.think = nade_boom; self.nextthink = max(self.wait, time); } void nade_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) { - if(DEATH_ISWEAPON(deathtype, WEP_LASER)) + if(DEATH_ISWEAPON(deathtype, WEP_BLASTER)) return; - if(DEATH_ISWEAPON(deathtype, WEP_NEX) || DEATH_ISWEAPON(deathtype, WEP_MINSTANEX)) + if(DEATH_ISWEAPON(deathtype, WEP_VORTEX) || DEATH_ISWEAPON(deathtype, WEP_VAPORIZER)) { force *= 6; - damage = autocvar_g_nades_nade_health * 0.55; + damage = self.max_health * 0.55; } - if(DEATH_ISWEAPON(deathtype, WEP_UZI)) - damage = autocvar_g_nades_nade_health * 0.1; + if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN)) + damage = self.max_health * 0.1; - if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN) && !(deathtype & HITTYPE_SECONDARY)) - damage = autocvar_g_nades_nade_health * 1.1; - - if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN) && (deathtype & HITTYPE_SECONDARY)) + if((DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) && !(deathtype & HITTYPE_SECONDARY)) // WEAPONTODO + damage = self.max_health * 1.1; + + if((DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) && (deathtype & HITTYPE_SECONDARY)) { - damage = autocvar_g_nades_nade_health * 0.1; + damage = self.max_health * 0.1; force *= 15; } - + self.velocity += force; - if(!damage) + if(!damage || (self.flags & FL_ONGROUND && IS_PLAYER(attacker))) return; - if(self.health == autocvar_g_nades_nade_health) + if(self.health == self.max_health) { - sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, 0.5 *(ATTN_LARGE + ATTN_MAX)); + sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX)); self.nextthink = max(time + autocvar_g_nades_nade_lifetime, time); self.think = nade_beep; } @@ -149,36 +147,49 @@ void toss_nade(entity e, vector _velocity, float _time) { entity _nade = e.nade; e.nade = world; - + remove(e.fake_nade); e.fake_nade = world; - + makevectors(e.v_angle); - + + W_SetupShot(e, FALSE, FALSE, "", CH_WEAPON_A, 0); + Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_NADES); - - setorigin(_nade, CENTER_OR_VIEWOFS(e) + (v_right * 10) * -1); + + //setorigin(_nade, CENTER_OR_VIEWOFS(e) + (v_right * 10) * -1); + setorigin(_nade, w_shotorg + (v_right * 25) * -1); setmodel(_nade, "models/weapons/v_ok_grenade.md3"); setattachment(_nade, world, ""); PROJECTILE_MAKETRIGGER(_nade); setsize(_nade, '-16 -16 -16', '16 16 16'); _nade.movetype = MOVETYPE_BOUNCE; - - if(e.crouch) - _nade.velocity = '0 0 -10'; + + tracebox(_nade.origin, _nade.mins, _nade.maxs, _nade.origin, FALSE, _nade); + if (trace_startsolid) + setorigin(_nade, e.origin); + + if(self.v_angle_x >= 70 && self.v_angle_x <= 110) + _nade.velocity = '0 0 100'; else if(autocvar_g_nades_nade_newton_style == 1) _nade.velocity = e.velocity + _velocity; else if(autocvar_g_nades_nade_newton_style == 2) _nade.velocity = _velocity; else - _nade.velocity = W_CalculateProjectileVelocity(e.velocity, _velocity, FALSE); - - _nade.solid = SOLID_BBOX; + _nade.velocity = W_CalculateProjectileVelocity(e.velocity, _velocity, TRUE); + _nade.touch = nade_touch; _nade.health = autocvar_g_nades_nade_health; + _nade.max_health = _nade.health; _nade.takedamage = DAMAGE_AIM; _nade.event_damage = nade_damage; _nade.teleportable = TRUE; + _nade.pushable = TRUE; + _nade.gravity = 1; + _nade.missile_flags = MIF_SPLASH | MIF_ARC; + _nade.damagedbycontents = TRUE; + _nade.angles = vectoangles(_nade.velocity); + _nade.flags = FL_PROJECTILE; nade_spawn(_nade); @@ -195,10 +206,10 @@ void nade_prime() { if(self.nade) remove(self.nade); - + if(self.fake_nade) remove(self.fake_nade); - + self.nade = spawn(); setmodel(self.nade, "null"); setattachment(self.nade, self, "bip01 l hand"); @@ -207,7 +218,7 @@ void nade_prime() self.nade.colormap = self.colormap; self.nade.glowmod = self.glowmod; self.nade.wait = time + autocvar_g_nades_nade_lifetime; - self.nade.cnt = time; + self.nade.lifetime = time; self.nade.think = nade_beep; self.nade.nextthink = max(self.nade.wait - 3, time); self.nade.projectiledeathtype = DEATH_NADE; @@ -228,33 +239,30 @@ float CanThrowNade() { if(self.vehicle) return FALSE; - + if(gameover) return FALSE; - + if(self.deadflag != DEAD_NO) return FALSE; - - if not(autocvar_g_nades) + + if (!autocvar_g_nades) return FALSE; // allow turning them off mid match - + if(forbidWeaponUse()) return FALSE; - - if not(IS_PLAYER(self)) + + if (!IS_PLAYER(self)) return FALSE; - + return TRUE; } -MUTATOR_HOOKFUNCTION(nades_ForbidThrowing) +void nades_CheckThrow() { - if(!g_weaponarena || !g_minstagib) - return FALSE; // TODO: fix this to support all modes that don't disable weapon dropping - if(!CanThrowNade()) - return FALSE; - + return; + if(!self.nade) { if(self.nade_refire < time) @@ -266,35 +274,33 @@ MUTATOR_HOOKFUNCTION(nades_ForbidThrowing) } else { - if(time - self.nade.cnt >= 1) + if(time - self.nade.lifetime >= 1) { makevectors(self.v_angle); - float _force = time - self.nade.cnt; + float _force = time - self.nade.lifetime; _force /= autocvar_g_nades_nade_lifetime; _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce)); toss_nade(self, (v_forward * 0.75 + v_up * 0.2 + v_right * 0.05) * _force, 0); } } - - return TRUE; } MUTATOR_HOOKFUNCTION(nades_VehicleEnter) { if(other.nade) toss_nade(other, '0 0 100', max(other.nade.wait, time + 0.05)); - + return FALSE; } MUTATOR_HOOKFUNCTION(nades_PlayerPreThink) { - float key_pressed = ((g_grappling_hook) ? self.button16 : self.BUTTON_HOOK); - + float key_pressed = ((g_grappling_hook || client_hasweapon(self, WEP_HOOK, FALSE, FALSE) || (weaponsInMap & WEPSET_HOOK)) ? self.button16 : self.BUTTON_HOOK); + if(self.nade) if(self.nade.wait - 0.1 <= time) toss_nade(self, '0 0 0', time + 0.05); - + if(CanThrowNade()) if(self.nade_refire < time) { @@ -303,14 +309,14 @@ MUTATOR_HOOKFUNCTION(nades_PlayerPreThink) if(!self.nade) nade_prime(); } - else if(time - self.nade.cnt >= 1) + else if(time - self.nade.lifetime >= 1) { if(self.nade) { makevectors(self.v_angle); - float _force = time - self.nade.cnt; + float _force = time - self.nade.lifetime; _force /= autocvar_g_nades_nade_lifetime; - _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce)); + _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce)); toss_nade(self, (v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0); } } @@ -333,7 +339,7 @@ MUTATOR_HOOKFUNCTION(nades_PlayerDies) { if(self.nade) toss_nade(self, '0 0 100', max(self.nade.wait, time + 0.05)); - + return FALSE; } @@ -344,7 +350,7 @@ MUTATOR_HOOKFUNCTION(nades_RemovePlayer) if(self.fake_nade) remove(self.fake_nade); - + return FALSE; } @@ -362,7 +368,6 @@ MUTATOR_HOOKFUNCTION(nades_BuildMutatorsPrettyString) MUTATOR_DEFINITION(mutator_nades) { - MUTATOR_HOOK(ForbidThrowCurrentWeapon, nades_ForbidThrowing, CBC_ORDER_ANY); MUTATOR_HOOK(VehicleEnter, nades_VehicleEnter, CBC_ORDER_ANY); MUTATOR_HOOK(PlayerPreThink, nades_PlayerPreThink, CBC_ORDER_ANY); MUTATOR_HOOK(PlayerSpawn, nades_PlayerSpawn, CBC_ORDER_ANY); @@ -371,11 +376,11 @@ MUTATOR_DEFINITION(mutator_nades) MUTATOR_HOOK(ClientDisconnect, nades_RemovePlayer, CBC_ORDER_ANY); MUTATOR_HOOK(BuildMutatorsString, nades_BuildMutatorsString, CBC_ORDER_ANY); MUTATOR_HOOK(BuildMutatorsPrettyString, nades_BuildMutatorsPrettyString, CBC_ORDER_ANY); - + MUTATOR_ONADD { precache_model("models/ok_nade_counter/ok_nade_counter.md3"); - + precache_model("models/weapons/h_ok_grenade.iqm"); precache_model("models/weapons/v_ok_grenade.md3"); precache_sound("weapons/rocket_impact.wav");