From: Mario <mario.mario@y7mail.com>
Date: Tue, 24 Dec 2013 23:12:05 +0000 (+1100)
Subject: Remove freeze code, monsters no longer use freeze attacks
X-Git-Tag: xonotic-v0.8.0~241^2^2~21
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=29b8ca3d2b3f1417baaa2c830f628cc0b9ee0022;p=xonotic%2Fxonotic-data.pk3dir.git

Remove freeze code, monsters no longer use freeze attacks
---

diff --git a/qcsrc/client/View.qc b/qcsrc/client/View.qc
index 9acee0173..8c9d59dd9 100644
--- a/qcsrc/client/View.qc
+++ b/qcsrc/client/View.qc
@@ -994,7 +994,7 @@ void CSQC_UpdateView(float w, float h)
 			}
 		}
 	}
-	
+
 	float e1 = (autocvar_hud_postprocessing_maxbluralpha != 0);
 	float e2 = (autocvar_hud_powerup != 0);
 	if(autocvar_hud_postprocessing && (e1 || e2)) // TODO: Remove this code and re-do the postprocess handling in the engine, where it properly belongs.
@@ -1086,12 +1086,15 @@ void CSQC_UpdateView(float w, float h)
 
 	//else
 	{
-		if(getstati(STAT_FROZEN))
-			drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
-		if(getstatf(STAT_REVIVE_PROGRESS))
+		if(gametype == MAPINFO_TYPE_FREEZETAG)
 		{
-			DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
-			drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
+			if(getstati(STAT_FROZEN))
+				drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+			if(getstatf(STAT_REVIVE_PROGRESS))
+			{
+				DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+				drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
+			}
 		}
 
 		if(autocvar_r_letterbox == 0)
diff --git a/qcsrc/client/projectile.qc b/qcsrc/client/projectile.qc
index 518f03102..8cdcdf470 100644
--- a/qcsrc/client/projectile.qc
+++ b/qcsrc/client/projectile.qc
@@ -307,7 +307,7 @@ void Ent_Projectile()
 			case PROJECTILE_TAG: setmodel(self, "models/laser.mdl"); self.traileffect = particleeffectnum("TR_ROCKET"); break;
 			case PROJECTILE_FLAC: setmodel(self, "models/hagarmissile.mdl"); self.scale = 0.4; self.traileffect = particleeffectnum("TR_SEEKER"); break;
 			case PROJECTILE_SEEKER: setmodel(self, "models/tagrocket.md3"); self.traileffect = particleeffectnum("TR_SEEKER"); break;
-			
+
 			case PROJECTILE_MAGE_SPIKE: setmodel(self, "models/ebomb.mdl"); self.traileffect = particleeffectnum("TR_VORESPIKE"); break;
 			case PROJECTILE_SHAMBLER_LIGHTNING: setmodel(self, "models/ebomb.mdl"); self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
 
diff --git a/qcsrc/client/waypointsprites.qc b/qcsrc/client/waypointsprites.qc
index 3a54f7239..a3e856d14 100644
--- a/qcsrc/client/waypointsprites.qc
+++ b/qcsrc/client/waypointsprites.qc
@@ -316,7 +316,7 @@ string spritelookuptext(string s)
 		case "item-shield": return _("Shield");
 		case "item-fuelregen": return _("Fuel regen");
 		case "item-jetpack": return _("Jet Pack");
-		case "frozen": return _("Frozen!");
+		case "freezetag_frozen": return _("Frozen!");
 		case "tagged-target": return _("Tagged");
 		case "vehicle": return _("Vehicle");
 		default: return s;
diff --git a/qcsrc/common/deathtypes.qh b/qcsrc/common/deathtypes.qh
index 35f4f16b2..1265e7eea 100644
--- a/qcsrc/common/deathtypes.qh
+++ b/qcsrc/common/deathtypes.qh
@@ -94,7 +94,7 @@ DEATHTYPES
 #define DEATH_ISSPECIAL(t)            ((t) >= DEATH_SPECIAL_START)
 #define DEATH_ISVEHICLE(t)            ((t) >= DEATH_VHFIRST && (t) <= DEATH_VHLAST)
 #define DEATH_ISTURRET(t)             ((t) >= DEATH_TURRET_FIRST && (t) <= DEATH_TURRET_LAST)
-#define DEATH_ISMONSTER(t)			  ((t) >= DEATH_MONSTER_FIRST && (t) <= DEATH_MONSTER_LAST)
+#define DEATH_ISMONSTER(t)            ((t) >= DEATH_MONSTER_FIRST && (t) <= DEATH_MONSTER_LAST)
 #define DEATH_WEAPONOFWEAPONDEATH(t)  ((t) & DEATH_WEAPONMASK)
 #define DEATH_ISWEAPON(t,w)           (!DEATH_ISSPECIAL(t) && DEATH_WEAPONOFWEAPONDEATH(t) == (w))
 #define DEATH_WEAPONOF(t)             (DEATH_ISSPECIAL(t) ? 0 : DEATH_WEAPONOFWEAPONDEATH(t))
diff --git a/qcsrc/common/monsters/monster/mage.qc b/qcsrc/common/monsters/monster/mage.qc
index d340c09d7..6156cd75b 100644
--- a/qcsrc/common/monsters/monster/mage.qc
+++ b/qcsrc/common/monsters/monster/mage.qc
@@ -60,7 +60,7 @@ float friend_needshelp(entity e)
 		return FALSE;
 	if(DIFF_TEAM(e, self) && e != self.monster_owner)
 		return FALSE;
-	if(e.frozen)
+	if(e.freezetag_frozen)
 		return FALSE;
 	if(!IS_PLAYER(e))
 		return ((e.flags & FL_MONSTER) && e.health < e.max_health);
diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc
index 28a78ceb8..038ffb58c 100644
--- a/qcsrc/common/monsters/sv_monsters.qc
+++ b/qcsrc/common/monsters/sv_monsters.qc
@@ -104,7 +104,7 @@ float monster_isvalidtarget (entity targ, entity ent)
 	if(SAME_TEAM(targ, ent))
 		return FALSE; // enemy is on our team
 
-	if (targ.frozen)
+	if (targ.freezetag_frozen)
 		return FALSE; // ignore frozen
 
 	if(autocvar_g_monsters_target_infront || ent.spawnflags & MONSTERFLAG_INFRONT)
@@ -538,26 +538,6 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_
 
 	entity targ;
 
-	if(self.frozen)
-	{
-		self.revive_progress = bound(0, self.revive_progress + self.ticrate * self.revive_speed, 1);
-		self.health = max(1, self.max_health * self.revive_progress);
-
-		WaypointSprite_UpdateHealth(self.sprite, self.health);
-
-		movelib_beak_simple(stopspeed);
-
-		self.frame = manim_idle;
-
-		self.enemy = world;
-		self.nextthink = time + self.ticrate;
-
-		if(self.revive_progress >= 1)
-			Unfreeze(self); // wait for next think before attacking
-
-		return; // no moving while frozen
-	}
-
 	if(self.flags & FL_SWIM)
 	{
 		if(self.waterlevel < WATERLEVEL_WETFEET)
@@ -733,9 +713,6 @@ void monster_remove(entity mon)
 	if(mon.weaponentity)
 		remove(mon.weaponentity);
 
-	if(mon.iceblock)
-		remove(mon.iceblock);
-
 	WaypointSprite_Kill(mon.sprite);
 
 	remove(mon);
@@ -786,8 +763,6 @@ void monsters_reset()
 	setorigin(self, self.pos1);
 	self.angles = self.pos2;
 
-	Unfreeze(self); // remove any icy remains
-
 	self.health = self.max_health;
 	self.velocity = '0 0 0';
 	self.enemy = world;
@@ -821,12 +796,6 @@ void monster_die(entity attacker, float gibbed)
 	self.nextthink = time;
 	self.ltime = time + 5;
 
-	if ( self.frozen )
-	{
-		Unfreeze(self); // remove any icy remains
-		self.health = 0; // reset by Unfreeze
-	}
-
 	monster_dropitem();
 
 	MonsterSound(monstersound_death, 0, FALSE, CH_VOICE);
@@ -871,10 +840,6 @@ void monster_die(entity attacker, float gibbed)
 
 void monsters_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
-
-	if(self.frozen && deathtype != DEATH_KILL)
-		return;
-
 	if(time < self.pain_finished && deathtype != DEATH_KILL)
 		return;
 
diff --git a/qcsrc/server/accuracy.qc b/qcsrc/server/accuracy.qc
index ab057662b..b78cc4fcd 100644
--- a/qcsrc/server/accuracy.qc
+++ b/qcsrc/server/accuracy.qc
@@ -113,7 +113,6 @@ float accuracy_isgooddamage(entity attacker, entity targ)
 
 	if(!warmup_stage)
 	if(targ_isvalid)
-	if(!targ.frozen)
 	if(targ.deadflag == DEAD_NO)
 	if(DIFF_TEAM(attacker, targ))
 		return TRUE;
diff --git a/qcsrc/server/bot/aim.qc b/qcsrc/server/bot/aim.qc
index 61f4ab5e8..3467e2b39 100644
--- a/qcsrc/server/bot/aim.qc
+++ b/qcsrc/server/bot/aim.qc
@@ -111,7 +111,7 @@ float bot_shouldattack(entity e)
 			return FALSE;
 	}
 
-	if(e.frozen)
+	if(e.freezetag_frozen)
 		return FALSE;
 
 	// If neither player has ball then don't attack unless the ball is on the
diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc
index ebb9ec528..19a1a2e85 100644
--- a/qcsrc/server/cl_client.qc
+++ b/qcsrc/server/cl_client.qc
@@ -168,8 +168,6 @@ void PutObserverInServer (void)
 
 	Portal_ClearAll(self);
 
-	Unfreeze(self);
-
 	if(self.alivetime)
 	{
 		if(!warmup_stage)
@@ -588,8 +586,6 @@ void PutClientInServer (void)
 				self.target = s;
 			activator = world;
 		self = oldself;
-		
-		Unfreeze(self);
 
 		spawn_spot = spot;
 		MUTATOR_CALLHOOK(PlayerSpawn);
@@ -940,7 +936,7 @@ void ClientKill (void)
 {
 	if(gameover) return;
 	if(self.player_blocked) return;
-	if(self.frozen) return;
+	if(self.freezetag_frozen) return;
 
 	ClientKill_TeamChange(0);
 }
@@ -1290,8 +1286,6 @@ void ClientDisconnect (void)
 	MUTATOR_CALLHOOK(ClientDisconnect);
 
 	Portal_ClearAll(self);
-	
-	Unfreeze(self);
 
 	RemoveGrapplingHook(self);
 
@@ -1734,8 +1728,6 @@ void SpectateCopy(entity spectatee) {
 	self.dmg_inflictor = spectatee.dmg_inflictor;
 	self.v_angle = spectatee.v_angle;
 	self.angles = spectatee.v_angle;
-	self.frozen = spectatee.frozen;
-	self.revive_progress = spectatee.revive_progress;
 	if(!self.BUTTON_USE)
 		self.fixangle = TRUE;
 	setorigin(self, spectatee.origin);
@@ -2246,16 +2238,6 @@ void PlayerPreThink (void)
 		return;
 #endif
 
-	if(self.frozen == 2)
-	{
-		self.revive_progress = bound(0, self.revive_progress + frametime * self.revive_speed, 1);
-		self.health = max(1, self.revive_progress * autocvar_g_balance_health_start);
-		self.iceblock.alpha = 1 - self.revive_progress;
-
-		if(self.revive_progress >= 1)
-			Unfreeze(self);
-	}
-
 	MUTATOR_CALLHOOK(PlayerPreThink);
 
 	if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button
@@ -2380,7 +2362,7 @@ void PlayerPreThink (void)
 			do_crouch = 0;
 		if(self.vehicle)
 			do_crouch = 0;
-		if(self.frozen)
+		if(self.freezetag_frozen)
 			do_crouch = 0;
 		if(self.weapon == WEP_SHOTGUN && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
 			do_crouch = 0;
diff --git a/qcsrc/server/cl_physics.qc b/qcsrc/server/cl_physics.qc
index 8c7bd126e..009856137 100644
--- a/qcsrc/server/cl_physics.qc
+++ b/qcsrc/server/cl_physics.qc
@@ -19,9 +19,6 @@ When you press the jump key
 */
 void PlayerJump (void)
 {
-	if(self.frozen)
-		return; // no jumping in freezetag when frozen
-		
 	float doublejump = FALSE;
 
 	player_multijump = doublejump;
@@ -787,25 +784,12 @@ void SV_PlayerPhysics()
 	self.disableclientprediction = 0;
 	if(time < self.ladder_time)
 		self.disableclientprediction = 1;
-		
+
 	if(time < self.spider_slowness)
 	{
 		self.stat_sv_maxspeed *= 0.5; // half speed while slow from spider
 		self.stat_sv_airspeedlimit_nonqw *= 0.5;
 	}
-		
-	if(self.frozen)
-	{
-		if(autocvar_sv_dodging_frozen && IS_REAL_CLIENT(self))
-		{
-			self.movement_x = bound(-5, self.movement_x, 5);
-			self.movement_y = bound(-5, self.movement_y, 5);
-			self.movement_z = bound(-5, self.movement_z, 5);
-		}
-		else
-			self.movement = '0 0 0';
-		self.disableclientprediction = 1;
-	}
 
 	MUTATOR_CALLHOOK(PlayerPhysics);
 
@@ -1008,7 +992,7 @@ void SV_PlayerPhysics()
 			PM_Accelerate(wishdir, wishspeed, wishspeed, autocvar_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
 		}
 	}
-	else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!autocvar_g_jetpack_fuel || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO) && !self.frozen)
+	else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!autocvar_g_jetpack_fuel || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO) && !self.freezetag_frozen)
 	{
 		//makevectors(self.v_angle_y * '0 1 0');
 		makevectors(self.v_angle);
diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc
index b51f295ea..0229d3ed5 100644
--- a/qcsrc/server/cl_player.qc
+++ b/qcsrc/server/cl_player.qc
@@ -246,7 +246,7 @@ void player_anim (void)
 		else
 			deadbits = ANIMSTATE_DEAD2;
 	float animbits = deadbits;
-	if(self.frozen)
+	if(self.freezetag_frozen)
 		animbits |= ANIMSTATE_FROZEN;
 	if(self.crouch)
 		animbits |= ANIMSTATE_DUCK;
diff --git a/qcsrc/server/cl_weapons.qc b/qcsrc/server/cl_weapons.qc
index ed4fa901f..88397a880 100644
--- a/qcsrc/server/cl_weapons.qc
+++ b/qcsrc/server/cl_weapons.qc
@@ -330,8 +330,6 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce)
 	w = self.weapon;
 	if (w == 0)
 		return; // just in case
-	if(self.frozen)
-		return;
 	if(MUTATOR_CALLHOOK(ForbidThrowCurrentWeapon))
 		return;
 	if(!autocvar_g_weapon_throwable)
@@ -360,7 +358,7 @@ float forbidWeaponUse()
 		return 1;
 	if(self.player_blocked)
 		return 1;
-	if(self.frozen)
+	if(self.freezetag_frozen)
 		return 1;
 	return 0;
 }
diff --git a/qcsrc/server/cl_weaponsystem.qc b/qcsrc/server/cl_weaponsystem.qc
index c0fd3dfbd..8d72a798b 100644
--- a/qcsrc/server/cl_weaponsystem.qc
+++ b/qcsrc/server/cl_weaponsystem.qc
@@ -163,7 +163,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m
 	// track max damage
 	if(accuracy_canbegooddamage(ent))
 		accuracy_add(ent, ent.weapon, maxdamage, 0);
-		
+
 	W_HitPlotAnalysis(ent, v_forward, v_right, v_up);
 
 	if(ent.weaponentity.movedir_x > 0)
diff --git a/qcsrc/server/command/getreplies.qc b/qcsrc/server/command/getreplies.qc
index 5e92523f7..b8979155d 100644
--- a/qcsrc/server/command/getreplies.qc
+++ b/qcsrc/server/command/getreplies.qc
@@ -345,13 +345,13 @@ string getmonsterlist()
 {
 	string monsterlist = "", col;
 	float i;
-	
+
 	for(i = MON_FIRST; i <= MON_LAST; ++i)
 	{
 		if(mod(i, 2)) { col = "^2"; }
 		else { col = "^3"; }
 		monsterlist = sprintf("%s%s%s ", monsterlist, col, (get_monsterinfo(i)).netname);
 	}
-	
+
 	return sprintf("^7Monsters available: %s\n", monsterlist);
 }
diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc
index c98ed3cfe..73c04ba91 100644
--- a/qcsrc/server/command/sv_cmd.qc
+++ b/qcsrc/server/command/sv_cmd.qc
@@ -147,32 +147,32 @@ void GameCommand_butcher(float request)
 		{
 			if(autocvar_g_campaign) { print("This command doesn't work in campaign mode.\n"); return; }
 			if(g_invasion) { print("This command doesn't work during an invasion.\n"); return; }
-		
-            float removed_count = 0;
+
+			float removed_count = 0;
 			entity head;
-			
+
 			FOR_EACH_MONSTER(head)
 			{
 				monster_remove(head);
 				++removed_count;
 			}
-			
+
 			FOR_EACH_PLAYER(head)
 				head.monstercount = 0;
-				
+
 			monsters_total = 0; // reset stats?
 			monsters_killed = 0;
-				
+
 			totalspawned = 0;
-			
+
 			if(removed_count <= 0)
 				print("No monsters to kill\n");
 			else
 				print(sprintf("Killed %d monster%s\n", removed_count, ((removed_count == 1) ? "" : "s")));
-				
+
 			return; // never fall through to usage
 		}
-			
+
 		default:
 		case CMD_REQUEST_USAGE:
 		{
diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh
index 3823fa0a5..cfc2ddf31 100644
--- a/qcsrc/server/defs.qh
+++ b/qcsrc/server/defs.qh
@@ -585,10 +585,7 @@ float serverflags;
 
 .float player_blocked;
 
-.float frozen; // for freeze attacks
-.float revive_progress;
-.float revive_speed; // NOTE: multiplier (anything above 1 is instaheal)
-.entity iceblock;
+.float freezetag_frozen;
 
 .entity muzzle_flash;
 .float misc_bulletcounter;	// replaces uzi & hlac bullet counter.
diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc
index 4b7c29731..d25822347 100644
--- a/qcsrc/server/g_damage.qc
+++ b/qcsrc/server/g_damage.qc
@@ -549,77 +549,6 @@ 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, head;
-	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);
-	
-	FOR_EACH_PLAYER(head)
-	if(head.hook.aiment == targ)
-		RemoveGrapplingHook(head);
-	
-	// 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);
-
-	entity head;
-	targ.frozen = 0;
-	targ.revive_progress = 0;
-	
-	WaypointSprite_Kill(targ.waypointsprite_attached);
-	
-	FOR_EACH_PLAYER(head)
-	if(head.hook.aiment == targ)
-		RemoveGrapplingHook(head);
-
-	// 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;
@@ -749,12 +678,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
 			mirrorforce *= g_weaponforcefactor;
 		}
 
-		if(targ.frozen && 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;
@@ -1277,7 +1200,7 @@ void Fire_ApplyDamage(entity e)
 		e.fire_endtime = 0;
 
 	// ice stops fire
-	if(e.frozen)
+	if(e.freezetag_frozen)
 		e.fire_endtime = 0;
 
 	t = min(frametime, e.fire_endtime - time);
diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc
index 85bd64ac4..1366dbbf3 100644
--- a/qcsrc/server/g_world.qc
+++ b/qcsrc/server/g_world.qc
@@ -793,10 +793,6 @@ void spawnfunc_worldspawn (void)
 	addstat(STAT_NEX_CHARGEPOOL, AS_FLOAT, nex_chargepool_ammo);
 
 	addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
-	
-	// freeze attacks
-	addstat(STAT_FROZEN, AS_INT, frozen);
-	addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, revive_progress);
 
 	// g_movementspeed hack
 	addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
@@ -807,7 +803,7 @@ void spawnfunc_worldspawn (void)
 	// secrets
 	addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total);
 	addstat(STAT_SECRETS_FOUND, AS_FLOAT, stat_secrets_found);
-	
+
 	// monsters
 	addstat(STAT_MONSTERS_TOTAL, AS_FLOAT, stat_monsters_total);
 	addstat(STAT_MONSTERS_KILLED, AS_FLOAT, stat_monsters_killed);
diff --git a/qcsrc/server/movelib.qc b/qcsrc/server/movelib.qc
index c262d0152..0774dd1dc 100644
--- a/qcsrc/server/movelib.qc
+++ b/qcsrc/server/movelib.qc
@@ -170,7 +170,7 @@ void movelib_move_simple(vector newdir,float velo,float blendrate)
 */
 #define movelib_move_simple(newdir,velo,blendrate) \
     self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo
-	
+
 #define movelib_move_simple_gravity(newdir,velo,blendrate) \
     if(self.flags & FL_ONGROUND) movelib_move_simple(newdir,velo,blendrate)
 
diff --git a/qcsrc/server/mutators/gamemode_ctf.qc b/qcsrc/server/mutators/gamemode_ctf.qc
index 862504d72..d3565578a 100644
--- a/qcsrc/server/mutators/gamemode_ctf.qc
+++ b/qcsrc/server/mutators/gamemode_ctf.qc
@@ -785,8 +785,7 @@ void ctf_FlagTouch()
 	}
 
 	// special touch behaviors
-	if(toucher.frozen) { return; }
-	else if(toucher.vehicle_flags & VHF_ISVEHICLE)
+	if(toucher.vehicle_flags & VHF_ISVEHICLE)
 	{
 		if(autocvar_g_ctf_allow_vehicle_touch)
 			toucher = toucher.owner; // the player is actually the vehicle owner, not other
diff --git a/qcsrc/server/mutators/gamemode_freezetag.qc b/qcsrc/server/mutators/gamemode_freezetag.qc
index 029a9b58f..9bc065223 100644
--- a/qcsrc/server/mutators/gamemode_freezetag.qc
+++ b/qcsrc/server/mutators/gamemode_freezetag.qc
@@ -1,6 +1,7 @@
 .float freezetag_frozen_time;
 .float freezetag_frozen_timeout;
 .float freezetag_revive_progress;
+.entity freezetag_ice;
 #define ICE_MAX_ALPHA 1
 #define ICE_MIN_ALPHA 0.1
 float freezetag_teams;
@@ -13,22 +14,22 @@ void freezetag_count_alive_players()
 		if(e.team == NUM_TEAM_1 && e.health >= 1)
 		{
 			++total_players;
-			if (e.frozen != 1) ++redalive;
+			if (!e.freezetag_frozen) ++redalive;
 		}
 		else if(e.team == NUM_TEAM_2 && e.health >= 1)
 		{
 			++total_players;
-			if (e.frozen != 1) ++bluealive;
+			if (!e.freezetag_frozen) ++bluealive;
 		}
 		else if(e.team == NUM_TEAM_3 && e.health >= 1)
 		{
 			++total_players;
-			if (e.frozen != 1) ++yellowalive;
+			if (!e.freezetag_frozen) ++yellowalive;
 		}
 		else if(e.team == NUM_TEAM_4 && e.health >= 1)
 		{
 			++total_players;
-			if (e.frozen != 1) ++pinkalive;
+			if (!e.freezetag_frozen) ++pinkalive;
 		}
 	}
 	FOR_EACH_REALCLIENT(e) {
@@ -127,6 +128,15 @@ float freezetag_CheckWinner()
 	return 1;
 }
 
+// this is needed to allow the player to turn his view around (fixangle can't
+// be used to freeze his view, as that also changes the angles), while not
+// turning that ice object with the player
+void freezetag_Ice_Think()
+{
+	setorigin(self, self.owner.origin - '0 0 16');
+	self.nextthink = time;
+}
+
 void freezetag_Add_Score(entity attacker)
 {
 	if(attacker == self)
@@ -147,24 +157,54 @@ void freezetag_Add_Score(entity attacker)
 
 void freezetag_Freeze(entity attacker)
 {
-	if(self.frozen)
+	if(self.freezetag_frozen)
 		return;
-	
-	Freeze(self, 0, 1, TRUE);
-	
+	self.freezetag_frozen = 1;
+	self.freezetag_frozen_time = time;
+	self.freezetag_revive_progress = 0;
+	self.health = 1;
+	if(autocvar_g_freezetag_frozen_maxtime > 0)
+		self.freezetag_frozen_timeout = time + autocvar_g_freezetag_frozen_maxtime;
+
 	freezetag_count_alive_players();
 
+	entity ice;
+	ice = spawn();
+	ice.owner = self;
+	ice.classname = "freezetag_ice";
+	ice.think = freezetag_Ice_Think;
+	ice.nextthink = time;
+	ice.frame = floor(random() * 21); // ice model has 20 different looking frames
+	ice.alpha = ICE_MAX_ALPHA;
+	ice.colormod = Team_ColorRGB(self.team);
+	ice.glowmod = ice.colormod;
+	setmodel(ice, "models/ice/ice.md3");
+
+	self.freezetag_ice = ice;
+
+	RemoveGrapplingHook(self);
+
+	// add waypoint
+	WaypointSprite_Spawn("freezetag_frozen", 0, 0, self, '0 0 64', world, self.team, self, waypointsprite_attached, TRUE, RADARICON_WAYPOINT, '0.25 0.90 1');
+
 	freezetag_Add_Score(attacker);
 }
 
 void freezetag_Unfreeze(entity attacker)
 {
+	self.freezetag_frozen = 0;
 	self.freezetag_frozen_time = 0;
 	self.freezetag_frozen_timeout = 0;
-	
-	Unfreeze(self);
+	self.freezetag_revive_progress = 0;
+
+	remove(self.freezetag_ice);
+	self.freezetag_ice = world;
+
+	if(self.waypointsprite_attached)
+		WaypointSprite_Kill(self.waypointsprite_attached);
 }
 
+
 // ================
 // Bot player logic
 // ================
@@ -181,7 +221,7 @@ void havocbot_goalrating_freeplayers(float ratingscale, vector org, float sradiu
 	{
 		if ((head != self) && (head.team == self.team))
 		{
-			if (head.frozen == 1)
+			if (head.freezetag_frozen)
 			{
 				distance = vlen(head.origin - org);
 				if (distance > sradius)
@@ -213,12 +253,12 @@ void havocbot_role_ft_offense()
 	unfrozen = 0;
 	FOR_EACH_PLAYER(head)
 	{
-		if ((head.team == self.team) && (head.frozen != 1))
+		if ((head.team == self.team) && (!head.freezetag_frozen))
 			unfrozen++;
 	}
 
 	// If only one left on team or if role has timed out then start trying to free players.
-	if (((unfrozen == 0) && (!self.frozen)) || (time > self.havocbot_role_timeout))
+	if (((unfrozen == 0) && (!self.freezetag_frozen)) || (time > self.havocbot_role_timeout))
 	{
 		dprint("changing role to freeing\n");
 		self.havocbot_role = havocbot_role_ft_freeing;
@@ -286,7 +326,7 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
 	if(round_handler_IsActive())
 	if(round_handler_CountdownRunning())
 	{
-		if(self.frozen)
+		if(self.freezetag_frozen)
 			freezetag_Unfreeze(world);
 		freezetag_count_alive_players();
 		return 1; // let the player die so that he can respawn whenever he wants
@@ -298,7 +338,7 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
 		|| frag_deathtype == DEATH_TEAMCHANGE || frag_deathtype == DEATH_AUTOTEAMCHANGE)
 	{
 		// let the player die, he will be automatically frozen when he respawns
-		if(self.frozen != 1)
+		if(!self.freezetag_frozen)
 		{
 			freezetag_Add_Score(frag_attacker);
 			freezetag_count_alive_players();
@@ -309,7 +349,7 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
 		return 1;
 	}
 
-	if(self.frozen)
+	if(self.freezetag_frozen)
 		return 1;
 
 	freezetag_Freeze(frag_attacker);
@@ -329,6 +369,8 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
 		Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_FREEZE, frag_target.netname, frag_attacker.netname);
 	}
 
+	frag_target.health = 1; // "respawn" the player :P
+
 	return 1;
 }
 
@@ -359,7 +401,7 @@ MUTATOR_HOOKFUNCTION(freezetag_reset_map_players)
 {
 	FOR_EACH_PLAYER(self)
 	{
-		if (self.frozen)
+		if (self.freezetag_frozen)
 			freezetag_Unfreeze(world);
 		self.freezetag_frozen_timeout = -1;
 		PutClientInServer();
@@ -383,7 +425,7 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
 	if(gameover)
 		return 1;
 
-	if(self.frozen == 1)
+	if(self.freezetag_frozen)
 	{
 		// keep health = 1
 		self.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
@@ -396,7 +438,7 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
 	entity o;
 	o = world;
 	if(self.freezetag_frozen_timeout > 0 && time < self.freezetag_frozen_timeout)
-		self.iceblock.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time);
+		self.freezetag_ice.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time);
 
 	if(self.freezetag_frozen_timeout > 0 && time >= self.freezetag_frozen_timeout)
 		n = -1;
@@ -406,15 +448,15 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
 		n = 0;
 		FOR_EACH_PLAYER(other) if(self != other)
 		{
-			if(other.frozen == 0)
+			if(other.freezetag_frozen == 0)
 			{
-				if(SAME_TEAM(other, self))
+				if(other.team == self.team)
 				{
 					if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
 					{
 						if(!o)
 							o = other;
-						if(self.frozen == 1)
+						if(self.freezetag_frozen)
 							other.reviving = TRUE;
 						++n;
 					}
@@ -423,12 +465,12 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
 		}
 	}
 
-	if(n && self.frozen == 1) // OK, there is at least one teammate reviving us
+	if(n && self.freezetag_frozen) // OK, there is at least one teammate reviving us
 	{
-		self.revive_progress = bound(0, self.revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
-		self.health = max(1, self.revive_progress * autocvar_g_balance_health_start);
+		self.freezetag_revive_progress = bound(0, self.freezetag_revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
+		self.health = max(1, self.freezetag_revive_progress * autocvar_g_balance_health_start);
 
-		if(self.revive_progress >= 1)
+		if(self.freezetag_revive_progress >= 1)
 		{
 			freezetag_Unfreeze(self);
 			freezetag_count_alive_players();
@@ -459,27 +501,45 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
 		{
 			if(other.reviving)
 			{
-				other.revive_progress = self.revive_progress;
+				other.freezetag_revive_progress = self.freezetag_revive_progress;
 				other.reviving = FALSE;
 			}
 		}
 	}
-	else if(!n && self.frozen == 1) // only if no teammate is nearby will we reset
+	else if(!n && self.freezetag_frozen) // only if no teammate is nearby will we reset
 	{
-		self.revive_progress = bound(0, self.revive_progress - frametime * autocvar_g_freezetag_revive_clearspeed, 1);
-		self.health = max(1, self.revive_progress * autocvar_g_balance_health_start);
+		self.freezetag_revive_progress = bound(0, self.freezetag_revive_progress - frametime * autocvar_g_freezetag_revive_clearspeed, 1);
+		self.health = max(1, self.freezetag_revive_progress * autocvar_g_balance_health_start);
 	}
-	else if(!n && !self.frozen)
+	else if(!n)
 	{
-		self.revive_progress = 0; // thawing nobody
+		self.freezetag_revive_progress = 0; // thawing nobody
 	}
 
 	return 1;
 }
 
+MUTATOR_HOOKFUNCTION(freezetag_PlayerPhysics)
+{
+	if(self.freezetag_frozen)
+	{
+		if(autocvar_sv_dodging_frozen && IS_REAL_CLIENT(self))
+		{
+			self.movement_x = bound(-5, self.movement_x, 5);
+			self.movement_y = bound(-5, self.movement_y, 5);
+			self.movement_z = bound(-5, self.movement_z, 5);
+		}
+		else
+			self.movement = '0 0 0';
+
+		self.disableclientprediction = 1;
+	}
+	return 1;
+}
+
 MUTATOR_HOOKFUNCTION(freezetag_PlayerDamage_Calculate)
 {
-	if(frag_target.frozen == 1 && frag_deathtype != DEATH_HURTTRIGGER)
+	if(frag_target.freezetag_frozen && frag_deathtype != DEATH_HURTTRIGGER)
 	{
 		if(autocvar_g_freezetag_revive_falldamage > 0)
 		if(frag_deathtype == DEATH_FALL)
@@ -498,6 +558,28 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDamage_Calculate)
 	return 1;
 }
 
+MUTATOR_HOOKFUNCTION(freezetag_PlayerJump)
+{
+	if(self.freezetag_frozen)
+		return TRUE; // no jumping in freezetag when frozen
+
+	return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(freezetag_ForbidThrowCurrentWeapon)
+{
+	if (self.freezetag_frozen)
+		return 1;
+	return 0;
+}
+
+MUTATOR_HOOKFUNCTION(freezetag_ItemTouch)
+{
+	if (other.freezetag_frozen)
+		return MUT_ITEMTOUCH_RETURN;
+	return MUT_ITEMTOUCH_CONTINUE;
+}
+
 MUTATOR_HOOKFUNCTION(freezetag_BotRoles)
 {
 	if (!self.deadflag)
@@ -511,6 +593,13 @@ MUTATOR_HOOKFUNCTION(freezetag_BotRoles)
 	return TRUE;
 }
 
+MUTATOR_HOOKFUNCTION(freezetag_SpectateCopy)
+{
+	self.freezetag_frozen = other.freezetag_frozen;
+	self.freezetag_revive_progress = other.freezetag_revive_progress;
+	return 0;
+}
+
 MUTATOR_HOOKFUNCTION(freezetag_GetTeamCount)
 {
 	freezetag_teams = autocvar_g_freezetag_teams_override;
@@ -521,6 +610,14 @@ MUTATOR_HOOKFUNCTION(freezetag_GetTeamCount)
 	return 0;
 }
 
+MUTATOR_HOOKFUNCTION(freezetag_VehicleTouch)
+{
+	if(other.freezetag_frozen)
+		return TRUE;
+
+	return FALSE;
+}
+
 void freezetag_Initialize()
 {
 	precache_model("models/ice/ice.md3");
@@ -533,6 +630,9 @@ void freezetag_Initialize()
 	addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
 	addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
 	addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
+
+	addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
+	addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
 }
 
 MUTATOR_DEFINITION(gamemode_freezetag)
@@ -544,9 +644,15 @@ MUTATOR_DEFINITION(gamemode_freezetag)
 	MUTATOR_HOOK(reset_map_players, freezetag_reset_map_players, CBC_ORDER_ANY);
 	MUTATOR_HOOK(GiveFragsForKill, freezetag_GiveFragsForKill, CBC_ORDER_FIRST);
 	MUTATOR_HOOK(PlayerPreThink, freezetag_PlayerPreThink, CBC_ORDER_FIRST);
+	MUTATOR_HOOK(PlayerPhysics, freezetag_PlayerPhysics, CBC_ORDER_FIRST);
 	MUTATOR_HOOK(PlayerDamage_Calculate, freezetag_PlayerDamage_Calculate, CBC_ORDER_ANY);
+	MUTATOR_HOOK(PlayerJump, freezetag_PlayerJump, CBC_ORDER_ANY);
+	MUTATOR_HOOK(ForbidThrowCurrentWeapon, freezetag_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
+	MUTATOR_HOOK(ItemTouch, freezetag_ItemTouch, CBC_ORDER_ANY);
 	MUTATOR_HOOK(HavocBot_ChooseRule, freezetag_BotRoles, CBC_ORDER_ANY);
+	MUTATOR_HOOK(SpectateCopy, freezetag_SpectateCopy, CBC_ORDER_ANY);
 	MUTATOR_HOOK(GetTeamCount, freezetag_GetTeamCount, CBC_ORDER_EXCLUSIVE);
+	MUTATOR_HOOK(VehicleTouch, freezetag_VehicleTouch, CBC_ORDER_ANY);
 
 	MUTATOR_ONADD
 	{
diff --git a/qcsrc/server/mutators/mutator_dodging.qc b/qcsrc/server/mutators/mutator_dodging.qc
index 6e187b90c..3f808499a 100644
--- a/qcsrc/server/mutators/mutator_dodging.qc
+++ b/qcsrc/server/mutators/mutator_dodging.qc
@@ -35,7 +35,7 @@ MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics) {
 	float clean_up_and_do_nothing;
 	float horiz_speed = autocvar_sv_dodging_horiz_speed;
 
-	if(self.frozen)
+	if(self.freezetag_frozen)
 		horiz_speed = autocvar_sv_dodging_horiz_speed_frozen;
 
     if (self.deadflag != DEAD_NO)
@@ -170,7 +170,7 @@ MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) {
 	tap_direction_y = 0;
 
 	float frozen_dodging;
-	frozen_dodging = (self.frozen && autocvar_sv_dodging_frozen);
+	frozen_dodging = (self.freezetag_frozen && autocvar_sv_dodging_frozen);
 
 	float dodge_detected;
 	if (g_dodging == 0)
diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src
index 78f69eb83..1ae22e202 100644
--- a/qcsrc/server/progs.src
+++ b/qcsrc/server/progs.src
@@ -26,12 +26,10 @@ sys-post.qh
 ../common/command/shared_defs.qh
 ../common/net_notice.qh
 ../common/animdecide.qh
-
 ../common/monsters/monsters.qh
 ../common/monsters/sv_monsters.qh
 ../common/monsters/spawn.qh
 
-
 autocvars.qh
 constants.qh
 defs.qh		// Should rename this, it has fields and globals
diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc
index b0e2e5e99..8878a3199 100644
--- a/qcsrc/server/t_items.qc
+++ b/qcsrc/server/t_items.qc
@@ -682,8 +682,6 @@ void Item_Touch (void)
 
 	if (!IS_PLAYER(other))
 		return;
-	if (other.frozen)
-		return;
 	if (other.deadflag)
 		return;
 	if (self.solid != SOLID_TRIGGER)
diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc
index 8ad3b5ac2..ab1851e84 100644
--- a/qcsrc/server/teamplay.qc
+++ b/qcsrc/server/teamplay.qc
@@ -190,7 +190,7 @@ void InitGameplayMode()
 	{
 		MUTATOR_ADD(gamemode_keepaway);
 	}
-	
+
 	if(g_invasion)
 	{
 		timelimit_override = 0; // no timelimit in invasion, round based
diff --git a/qcsrc/server/tturrets/system/system_main.qc b/qcsrc/server/tturrets/system/system_main.qc
index cced0ec36..d35573b54 100644
--- a/qcsrc/server/tturrets/system/system_main.qc
+++ b/qcsrc/server/tturrets/system/system_main.qc
@@ -1102,7 +1102,7 @@ float turret_stdproc_init (string cvar_base_name, string base, string head, floa
     if (!self.health)
         self.health = 1000;
     self.tur_health = max(1, self.health);
-	self.bot_attack = TRUE;
+    self.bot_attack = TRUE;
     self.monster_attack = TRUE;
 
     if (!self.turrcaps_flags)
diff --git a/qcsrc/server/vehicles/vehicles.qc b/qcsrc/server/vehicles/vehicles.qc
index 3e9a96f01..3172aced9 100644
--- a/qcsrc/server/vehicles/vehicles.qc
+++ b/qcsrc/server/vehicles/vehicles.qc
@@ -564,9 +564,6 @@ void vehicles_touch()
 
     if(other.deadflag != DEAD_NO)
         return;
-		
-	if(other.frozen)
-		return;
 
     if(other.vehicle != world)
         return;
@@ -586,9 +583,6 @@ void vehicles_enter()
 
     if(self.phase > time)
         return;
-		
-	if(other.frozen)
-		return;
 
     if(teamplay)
     if(self.team)
@@ -642,7 +636,7 @@ void vehicles_enter()
 
     self.team                 = self.owner.team;
     self.flags               -= FL_NOTARGET;
-	self.monster_attack		  = TRUE;
+    self.monster_attack       = TRUE;
 
     if (IS_REAL_CLIENT(other))
     {
@@ -820,7 +814,7 @@ void vehicles_exit(float eject)
     sound (_vehicle, CH_TRIGGER_SINGLE, "misc/null.wav", 1, ATTEN_NORM);
     _vehicle.vehicle_hudmodel.viewmodelforclient = _vehicle;
     _vehicle.phase = time + 1;
-	_vehicle.monster_attack = FALSE;
+    _vehicle.monster_attack = FALSE;
 
     _vehicle.vehicle_exit(eject);
 
diff --git a/qcsrc/server/w_electro.qc b/qcsrc/server/w_electro.qc
index ea2cf8bf0..0ad23a137 100644
--- a/qcsrc/server/w_electro.qc
+++ b/qcsrc/server/w_electro.qc
@@ -263,7 +263,7 @@ void lgbeam_think()
 		return;
 	}
 
-	if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.frozen)
+	if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.freezetag_frozen)
 	{
 		if(self == owner_player.lgbeam)
 			owner_player.lgbeam = world;