X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fg_damage.qc;h=56cac627f5c7e7be76a72e57567f663fc005b7b3;hb=9a66589d6acbd35df28b897d603709b435b78710;hp=da013fc75d0eebe984ebc4a39717489d47d72f45;hpb=8c8a22011714768f8c5b3ac887d0fd099fc08d8b;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index da013fc75..56cac627f 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -544,6 +544,69 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) if(targ.killcount) { targ.killcount = 0; } } +void Ice_Think() +{ + setorigin(self, self.owner.origin - '0 0 16'); + self.nextthink = time; +} + +void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypoint) +{ + if(!IS_PLAYER(targ) && !(targ.flags & FL_MONSTER)) // only specified entities can be freezed + return; + + if(targ.frozen) + return; + + targ.frozen = frozen_type; + targ.revive_progress = 0; + targ.health = 1; + targ.revive_speed = freeze_time; + + entity ice; + ice = spawn(); + ice.owner = targ; + ice.classname = "ice"; + ice.scale = targ.scale; + ice.think = Ice_Think; + ice.nextthink = time; + ice.frame = floor(random() * 21); // ice model has 20 different looking frames + setmodel(ice, "models/ice/ice.md3"); + ice.alpha = 1; + ice.colormod = Team_ColorRGB(targ.team); + ice.glowmod = ice.colormod; + targ.iceblock = ice; + + entity oldself; + oldself = self; + self = ice; + Ice_Think(); + self = oldself; + + RemoveGrapplingHook(targ); + + // add waypoint + if(show_waypoint) + WaypointSprite_Spawn("frozen", 0, 0, targ, '0 0 64', world, targ.team, targ, waypointsprite_attached, TRUE, RADARICON_WAYPOINT, '0.25 0.90 1'); +} + +void Unfreeze (entity targ) +{ + if(targ.frozen) // only reset health if target was frozen + targ.health = ((IS_PLAYER(targ)) ? autocvar_g_balance_health_start : targ.max_health); + targ.frozen = 0; + targ.revive_progress = 0; + + WaypointSprite_Kill(targ.waypointsprite_attached); + + // remove the ice block + if(targ.iceblock) + { + remove(targ.iceblock); + targ.iceblock = world; + } +} + // these are updated by each Damage call for use in button triggering and such entity damage_targ; entity damage_inflictor; @@ -626,13 +689,10 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float { attacker.dmg_team = attacker.dmg_team + damage; complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold; - if(complainteamdamage > 0 && !g_ca) // FIXME why is g_ca ruled out here? Why not just g_mirrordamage 0 on CA servers? + if(complainteamdamage > 0) mirrordamage = autocvar_g_mirrordamage * complainteamdamage; mirrorforce = autocvar_g_mirrordamage * vlen(force); - if(g_ca) - damage = 0; - else - damage = autocvar_g_friendlyfire * damage; + damage = autocvar_g_friendlyfire * damage; // mirrordamage will be used LATER if(autocvar_g_mirrordamage_virtual) @@ -672,6 +732,12 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float mirrorforce *= g_weaponforcefactor; } + if(((targ.frozen == 2 && attacker.monsterid != MON_SPIDER) || (targ.frozen == 1)) && deathtype != DEATH_HURTTRIGGER) + { + damage = 0; + force *= 0.2; + } + // should this be changed at all? If so, in what way? frag_attacker = attacker; frag_target = targ; @@ -708,7 +774,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float if (targ == attacker) { - if(g_ca || (g_cts && !autocvar_g_cts_selfdamage)) + if(g_cts && !autocvar_g_cts_selfdamage) damage = 0; else damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself @@ -726,7 +792,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float else victim = targ; - if(IS_PLAYER(victim) || victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET) + if(IS_PLAYER(victim) || victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET || victim.flags & FL_MONSTER) { if(IsDifferentTeam(victim, attacker)) { @@ -772,7 +838,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float // apply push if (self.damageforcescale) if (vlen(force)) - if (!IS_PLAYER(self) || time >= self.spawnshieldtime || g_midair) + if (!IS_PLAYER(self) || time >= self.spawnshieldtime) { vector farce = damage_explosion_calcpush(self.damageforcescale * force, self.velocity, autocvar_g_balance_damagepush_speedfactor); if(self.movetype == MOVETYPE_PHYSICS) @@ -1194,7 +1260,7 @@ void Fire_ApplyDamage(entity e) e.fire_endtime = 0; // ice stops fire - if(e.freezetag_frozen) + if(e.frozen) e.fire_endtime = 0; t = min(frametime, e.fire_endtime - time);