]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_client.qc
Merge branch 'master' into Mario/monsters
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_client.qc
index 6df7310e7c4e3bb2e37b11cdbc59377db3a87988..a1206c58363b3618339c9fd4ad5d343d3721b50c 100644 (file)
@@ -74,239 +74,8 @@ void ClientData_Touch(entity e)
        }
 }
 
-
-.vector spawnpoint_score;
 .string netname_previous;
 
-void spawnfunc_info_player_survivor (void)
-{
-       spawnfunc_info_player_deathmatch();
-}
-
-void spawnfunc_info_player_start (void)
-{
-       spawnfunc_info_player_deathmatch();
-}
-
-void spawnfunc_info_player_deathmatch (void)
-{
-       self.classname = "info_player_deathmatch";
-       relocate_spawnpoint();
-}
-
-void spawnpoint_use()
-{
-       if(teamplay)
-       if(have_team_spawns > 0)
-       {
-               self.team = activator.team;
-               some_spawn_has_been_used = 1;
-       }
-}
-
-// Returns:
-//   _x: prio (-1 if unusable)
-//   _y: weight
-vector Spawn_Score(entity spot, float mindist, float teamcheck)
-{
-       float shortest, thisdist;
-       float prio;
-       entity player;
-
-       prio = 0;
-
-       // filter out spots for the wrong team
-       if(teamcheck >= 0)
-               if(spot.team != teamcheck)
-                       return '-1 0 0';
-
-       if(race_spawns)
-               if(spot.target == "")
-                       return '-1 0 0';
-
-       if(IS_REAL_CLIENT(self))
-       {
-               if(spot.restriction == 1)
-                       return '-1 0 0';
-       }
-       else
-       {
-               if(spot.restriction == 2)
-                       return '-1 0 0';
-       }
-
-       shortest = vlen(world.maxs - world.mins);
-       FOR_EACH_PLAYER(player) if (player != self)
-       {
-               thisdist = vlen(player.origin - spot.origin);
-               if (thisdist < shortest)
-                       shortest = thisdist;
-       }
-       if(shortest > mindist)
-               prio += SPAWN_PRIO_GOOD_DISTANCE;
-
-       spawn_score = prio * '1 0 0' + shortest * '0 1 0';
-       spawn_spot = spot;
-
-       // filter out spots for assault
-       if(spot.target != "") {
-               entity ent;
-               float found;
-
-               found = 0;
-               for(ent = world; (ent = find(ent, targetname, spot.target)); )
-               {
-                       ++found;
-                       if(ent.spawn_evalfunc)
-                       {
-                               entity oldself = self;
-                               self = ent;
-                               spawn_score = ent.spawn_evalfunc(oldself, spot, spawn_score);
-                               self = oldself;
-                               if(spawn_score_x < 0)
-                                       return spawn_score;
-                       }
-               }
-
-               if(!found)
-               {
-                       dprint("WARNING: spawnpoint at ", vtos(spot.origin), " could not find its target ", spot.target, "\n");
-                       return '-1 0 0';
-               }
-       }
-
-       MUTATOR_CALLHOOK(Spawn_Score);
-       return spawn_score;
-}
-
-void Spawn_ScoreAll(entity firstspot, float mindist, float teamcheck)
-{
-       entity spot;
-       for(spot = firstspot; spot; spot = spot.chain)
-               spot.spawnpoint_score = Spawn_Score(spot, mindist, teamcheck);
-}
-
-entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck)
-{
-       entity spot, spotlist, spotlistend;
-
-       spotlist = world;
-       spotlistend = world;
-
-       Spawn_ScoreAll(firstspot, mindist, teamcheck);
-
-       for(spot = firstspot; spot; spot = spot.chain)
-       {
-               if(spot.spawnpoint_score_x >= 0) // spawning allowed here
-               {
-                       if(spotlistend)
-                               spotlistend.chain = spot;
-                       spotlistend = spot;
-                       if(!spotlist)
-                               spotlist = spot;
-               }
-       }
-       if(spotlistend)
-               spotlistend.chain = world;
-
-       return spotlist;
-}
-
-entity Spawn_WeightedPoint(entity firstspot, float lower, float upper, float exponent)
-{
-       // weight of a point: bound(lower, mindisttoplayer, upper)^exponent
-       // multiplied by spot.cnt (useful if you distribute many spawnpoints in a small area)
-       entity spot;
-
-       RandomSelection_Init();
-       for(spot = firstspot; spot; spot = spot.chain)
-               RandomSelection_Add(spot, 0, string_null, pow(bound(lower, spot.spawnpoint_score_y, upper), exponent) * spot.cnt, (spot.spawnpoint_score_y >= lower) * 0.5 + spot.spawnpoint_score_x);
-
-       return RandomSelection_chosen_ent;
-}
-
-/*
-=============
-SelectSpawnPoint
-
-Finds a point to respawn
-=============
-*/
-entity SelectSpawnPoint (float anypoint)
-{
-       float teamcheck;
-       entity spot, firstspot;
-
-       spot = find (world, classname, "testplayerstart");
-       if (spot)
-               return spot;
-
-       if(anypoint || autocvar_g_spawn_useallspawns)
-               teamcheck = -1;
-       else if(have_team_spawns > 0)
-       {
-               if(have_team_spawns_forteam[self.team] == 0)
-               {
-                       // we request a spawn for a team, and we have team
-                       // spawns, but that team has no spawns?
-                       if(have_team_spawns_forteam[0])
-                               // try noteam spawns
-                               teamcheck = 0;
-                       else
-                               // if not, any spawn has to do
-                               teamcheck = -1;
-               }
-               else
-                       teamcheck = self.team; // MUST be team
-       }
-       else if(have_team_spawns == 0 && have_team_spawns_forteam[0])
-               teamcheck = 0; // MUST be noteam
-       else
-               teamcheck = -1;
-               // if we get here, we either require team spawns but have none, or we require non-team spawns and have none; use any spawn then
-
-
-       // get the entire list of spots
-       firstspot = findchain(classname, "info_player_deathmatch");
-       // filter out the bad ones
-       // (note this returns the original list if none survived)
-       if(anypoint)
-       {
-               spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
-       }
-       else
-       {
-               float mindist;
-               if (g_arena && arena_roundbased)
-                       mindist = 800;
-               else
-                       mindist = 100;
-               firstspot = Spawn_FilterOutBadSpots(firstspot, mindist, teamcheck);
-
-               // there is 50/50 chance of choosing a random spot or the furthest spot
-               // (this means that roughly every other spawn will be furthest, so you
-               // usually won't get fragged at spawn twice in a row)
-               if (random() > autocvar_g_spawn_furthest)
-                       spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
-               else
-                       spot = Spawn_WeightedPoint(firstspot, 1, 5000, 5); // chooses a far far away spawnpoint
-       }
-
-       if (!spot)
-       {
-               if(autocvar_spawn_debug)
-                       GotoNextMap(0);
-               else
-               {
-                       if(some_spawn_has_been_used)
-                               return world; // team can't spawn any more, because of actions of other team
-                       else
-                               error("Cannot find a spawn point - please fix the map!");
-               }
-       }
-
-       return spot;
-}
 
 /*
 =============
@@ -399,6 +168,8 @@ void PutObserverInServer (void)
 
        Portal_ClearAll(self);
        
+       Unfreeze(self);
+       
        if(self.alivetime)
        {
                if(!inWarmupStage)
@@ -585,7 +356,6 @@ PutClientInServer
 Called when a client spawns in the server
 =============
 */
-
 void PutClientInServer (void)
 {
        if(IS_BOT_CLIENT(self))
@@ -741,11 +511,9 @@ void PutClientInServer (void)
                self.oldvelocity = self.velocity;
                self.fire_endtime = -1;
 
-               msg_entity = self;
-               WRITESPECTATABLE_MSG_ONE({
-                       WriteByte(MSG_ONE, SVC_TEMPENTITY);
-                       WriteByte(MSG_ONE, TE_CSQC_SPAWN);
-               });
+               entity spawnevent = spawn();
+               spawnevent.owner = self;
+               Net_LinkEntity(spawnevent, FALSE, 0.5, SpawnEvent_Send);
 
                self.model = "";
                FixPlayermodel();
@@ -766,6 +534,7 @@ void PutClientInServer (void)
                self.event_damage = PlayerDamage;
 
                self.bot_attack = TRUE;
+               self.monster_attack = TRUE;
 
                self.statdraintime = time + 5;
                self.BUTTON_ATCK = self.BUTTON_JUMP = self.BUTTON_ATCK2 = 0;
@@ -811,6 +580,8 @@ void PutClientInServer (void)
                                self.target = s;
                        activator = world;
                self = oldself;
+               
+               Unfreeze(self);
 
                spawn_spot = spot;
                MUTATOR_CALLHOOK(PlayerSpawn);
@@ -832,10 +603,9 @@ void PutClientInServer (void)
                                self.alivetime = time;
 
                antilag_clear(self);
-
-               if (autocvar_g_spawnsound)
-                       soundat(world, self.origin, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM);
-       } else if(IS_OBSERVER(self)) {
+       }
+       else if(IS_OBSERVER(self))
+       {
                PutObserverInServer ();
        }
 }
@@ -864,7 +634,6 @@ float ClientInit_SendEntity(entity to, float sf)
        else
                WriteString(MSG_ENTITY, "");
        WriteByte(MSG_ENTITY, self.count * 255.0); // g_balance_armor_blockpercent
-       WriteByte(MSG_ENTITY, self.cnt * 255.0); // g_balance_weaponswitchdelay
        WriteCoord(MSG_ENTITY, self.bouncefactor); // g_balance_grenadelauncher_bouncefactor
        WriteCoord(MSG_ENTITY, self.bouncestop); // g_balance_grenadelauncher_bouncestop
        WriteCoord(MSG_ENTITY, self.ebouncefactor); // g_balance_grenadelauncher_bouncefactor
@@ -887,11 +656,6 @@ void ClientInit_CheckUpdate()
                self.count = autocvar_g_balance_armor_blockpercent;
                self.SendFlags |= 1;
        }
-       if(self.cnt != autocvar_g_balance_weaponswitchdelay)
-       {
-               self.cnt = autocvar_g_balance_weaponswitchdelay;
-               self.SendFlags |= 1;
-       }
        if(self.bouncefactor != autocvar_g_balance_grenadelauncher_bouncefactor)
        {
                self.bouncefactor = autocvar_g_balance_grenadelauncher_bouncefactor;
@@ -1168,7 +932,7 @@ void ClientKill (void)
 {
        if(gameover) return;
        if(self.player_blocked) return;
-       if(self.freezetag_frozen) return;
+       if(self.frozen) return;
        
        ClientKill_TeamChange(0);
 }
@@ -1518,6 +1282,8 @@ void ClientDisconnect (void)
        MUTATOR_CALLHOOK(ClientDisconnect);
 
        Portal_ClearAll(self);
+       
+       Unfreeze(self);
 
        RemoveGrapplingHook(self);
 
@@ -1969,6 +1735,8 @@ 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);
@@ -2479,6 +2247,16 @@ 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
@@ -2600,7 +2378,7 @@ void PlayerPreThink (void)
                        do_crouch = 1;
                if(self.vehicle)
                        do_crouch = 0;
-               if(self.freezetag_frozen)
+               if(self.frozen)
                        do_crouch = 0;
                if(self.weapon == WEP_SHOTGUN && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
                        do_crouch = 0;
@@ -2672,6 +2450,9 @@ void PlayerPreThink (void)
                // secret status
                secrets_setstatus();
                
+               // monsters status
+               monsters_setstatus();
+               
                self.dmg_team = max(0, self.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
 
                //self.angles_y=self.v_angle_y + 90;   // temp