]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/divVerent/csad' into divVerent/csad
authorRudolf Polzer <divverent@xonotic.org>
Tue, 4 Dec 2012 16:38:35 +0000 (17:38 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Tue, 4 Dec 2012 16:38:35 +0000 (17:38 +0100)
Conflicts:
qcsrc/client/csqcmodel_hooks.qc

14 files changed:
defaultXonotic.cfg
qcsrc/client/autocvars.qh
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/player_skeleton.qc [new file with mode: 0644]
qcsrc/client/player_skeleton.qh [new file with mode: 0644]
qcsrc/client/progs.src
qcsrc/client/scoreboard.qc
qcsrc/common/constants.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/mutators/mutator_vampire.qc

index 4f949c0eb4ec6058d5e81d40d5f7ef5a7d4ce880..dc5a8d6e53a3203150b57687393b33858cb018c9 100644 (file)
@@ -962,6 +962,7 @@ seta scoreboard_offset_left 0.15 "how far (by percent) the scoreboard is offset
 seta scoreboard_offset_right 0.15 "how far (by percent) the scoreboard is offset from the right screen edge"
 seta scoreboard_offset_vertical 0.05 "how far (by percent) the scoreboard is offset from the top and bottom of the screen"
 seta scoreboard_bg_scale 0.25 "scale for the tiled scoreboard background"
+seta scoreboard_respawntime_decimals 1 "decimal places to show for the respawntime countdown display on the scoreboard"
 
 seta accuracy_color_levels "0 20 100" "accuracy values at which a specified color (accuracy_color<X>) will be used. If your accuracy is between 2 of these values then a mix of the Xth and X+1th colors will be used. You can specify up to 10 values, in increasing order"
 seta accuracy_color0 "1 0 0"
index 0d4513f92b802a351f83883eecd5ed8e430d1d2f..9756273a509a9517608c495616097583e00d80cf 100644 (file)
@@ -367,6 +367,7 @@ var float autocvar_scoreboard_highlight_alpha_self = 0.25;
 float autocvar_scoreboard_offset_left;
 float autocvar_scoreboard_offset_right;
 float autocvar_scoreboard_offset_vertical;
+float autocvar_scoreboard_respawntime_decimals;
 float autocvar_v_flipped;
 float autocvar_vid_conheight;
 float autocvar_vid_conwidth;
@@ -402,3 +403,4 @@ string autocvar__cl_playermodel;
 float autocvar_cl_precacheplayermodels;
 float autocvar_cl_deathglow;
 float autocvar_developer_csqcentities;
+float autocvar__animblend;
index e181a29fd9a2330682cec8cddbbea8ad74d524a1..7a642e3bde8f3064b36cb3bb5a574187a2a40fd5 100644 (file)
@@ -588,7 +588,7 @@ void CSQCModel_Hook_PreDraw(float isplayer)
                else
                {
                        // we know that frame3 and frame4 fields, used by InterpolateAnimation, are left alone - but that is all we know!
-                       float doblend = FALSE;
+                       float doblend = autocvar__animblend;
                        float onground = 0;
                        if(self == csqcplayer)
                        {
@@ -609,6 +609,7 @@ void CSQCModel_Hook_PreDraw(float isplayer)
                        animdecide_init(self); // FIXME only do this on model change
                        animdecide_setimplicitstate(self, onground);
                        animdecide_setframes(self, doblend, anim_frame, anim_frame1time, anim_frame2, anim_frame2time);
+                       print(sprintf("frames: %d %d\n", self.anim_frame, self.anim_frame2));
                        float sf = 0;
                        if(self.anim_saveframe != self.anim_frame || self.anim_saveframe1time != self.anim_frame1time)
                                sf |= CSQCMODEL_PROPERTY_FRAME;
@@ -631,12 +632,14 @@ void CSQCModel_Hook_PreDraw(float isplayer)
                        CSQCModel_InterpolateAnimation_2To4_Do();
                        if(doblend)
                        {
-                               // build a skeletonobject
+                               skeleton_from_frames(self);
                        }
                        else
                        {
-                               // remove skeletonobject if any
-                               // all is done
+                               free_skeleton_from_frames(self);
+                               // just in case, clear these
+                               self.lerpfrac3 = 0;
+                               self.lerpfrac4 = 0;
                        }
                }
        }
diff --git a/qcsrc/client/player_skeleton.qc b/qcsrc/client/player_skeleton.qc
new file mode 100644 (file)
index 0000000..42efe9b
--- /dev/null
@@ -0,0 +1,91 @@
+.float skeleton_modelindex;
+#define BONETYPE_LOWER 0
+#define BONETYPE_UPPER 1
+#define MAX_BONES 128
+.float skeleton_bonetype[MAX_BONES];
+.float skeleton_aimbone;
+.float skeleton_numbones;
+
+void skeleton_identifybones(entity e)
+{
+       float s = e.skeletonindex;
+       float n = (e.skeleton_numbones = skel_get_numbones(s));
+       e.skeleton_aimbone = 0;
+       float i;
+       for(i = 1; i <= n; ++i)
+       {
+               float t = BONETYPE_LOWER;
+               float p = skel_get_boneparent(s, i);
+               if(p > 0)
+                       t = e.(skeleton_bonetype[p-1]);
+               string nm = skel_get_bonename(s, i);
+               if(nm == "spine2")
+                       t = BONETYPE_UPPER;
+               if(nm == "upperarm_R")
+                       e.skeleton_aimbone = i;
+               e.(skeleton_bonetype[i-1]) = t;
+       }
+}
+
+void free_skeleton_from_frames(entity e)
+{
+       if(e.skeletonindex)
+       {
+               skel_delete(e.skeletonindex);
+               e.skeletonindex = 0;
+       }
+}
+
+void skeleton_from_frames(entity e)
+{
+       float m = e.modelindex;
+       if(m != e.skeleton_modelindex)
+       {
+               if(e.skeletonindex)
+               {
+                       skel_delete(e.skeletonindex);
+                       e.skeletonindex = 0;
+               }
+               m = (e.skeleton_modelindex = e.modelindex);
+               if(m)
+               {
+                       e.skeletonindex = skel_create(m);
+                       skeleton_identifybones(e);
+               }
+       }
+       float s = e.skeletonindex;
+       if(!s)
+               return;
+       float bone;
+       float n = e.skeleton_numbones;
+       float savelerpfrac = e.lerpfrac;
+       float savelerpfrac3 = e.lerpfrac3;
+       float savelerpfrac4 = e.lerpfrac4;
+       for(bone = 0; bone < n; )
+       {
+               float firstbone = bone;
+               float bonetype = e.skeleton_bonetype[bone];
+               for(++bone; (bone < n) && (e.skeleton_bonetype[bone] == bonetype); ++bone)
+                       ;
+               if(bonetype == BONETYPE_LOWER && 1)
+               {
+                       // only show frames 1+3
+                       e.lerpfrac = 0;
+                       e.lerpfrac3 = savelerpfrac3 * 2;
+                       e.lerpfrac4 = 0;
+               }
+               else
+               {
+                       // only show frames 2+4
+                       e.lerpfrac = savelerpfrac * 2;
+                       e.lerpfrac3 = 0;
+                       e.lerpfrac4 = savelerpfrac4 * 2;
+               }
+               //print(sprintf("Run: bone %d to %d, type %d\n", firstbone + 1, bone, bonetype));
+               //print(sprintf("frame %d %d %d %d lerpfrac * %d %d %d\n", e.frame, e.frame2, e.frame3, e.frame4, e.lerpfrac, e.lerpfrac3, e.lerpfrac4));
+               skel_build(s, e, m, 0, firstbone + 1, bone);
+       }
+       e.lerpfrac = savelerpfrac;
+       e.lerpfrac3 = savelerpfrac;
+       e.lerpfrac4 = savelerpfrac;
+}
diff --git a/qcsrc/client/player_skeleton.qh b/qcsrc/client/player_skeleton.qh
new file mode 100644 (file)
index 0000000..292cfca
--- /dev/null
@@ -0,0 +1,2 @@
+void free_skeleton_from_frames(entity e);
+void skeleton_from_frames(entity e);
index 8c98a07b709031647c733cf06539fcaa5e8e94ac..9d968f1fe7d86e1ceeecf09b135c6dcc1e23d4f7 100644 (file)
@@ -50,6 +50,7 @@ vehicles/vehicles.qh
 ../csqcmodellib/cl_model.qh
 ../csqcmodellib/cl_player.qh
 projectile.qh
+player_skeleton.qh
 
 sortlist.qc
 miscfunctions.qc
@@ -112,6 +113,7 @@ command/cl_cmd.qc
 ../warpzonelib/client.qc
 tturrets.qc
 
+player_skeleton.qc
 ../common/animdecide.qc
 
 ../common/if-this-file-errors-scroll-up-and-fix-the-warnings.fteqccfail
index 48a7217fc703a08b3b7f7fdfab3bc58efea36c2e..364f9e969e27aeee9a5ca91c3a3310f2b4ee3740 100644 (file)
@@ -1374,9 +1374,30 @@ void HUD_DrawScoreboard()
                }
        }
 
-
        pos_y += 1.2 * hud_fontsize_y;
        drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, TRUE, hud_fontsize)), str, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
 
+       // print information about respawn status
+       float respawn_time = getstatf(STAT_RESPAWN_TIME);
+       if(respawn_time)
+       {
+               if(respawn_time < 0)
+               {
+                       // a negative number means we are awaiting respawn, time value is still the same
+                       respawn_time *= -1; // remove mark now that we checked it
+                       if(time >= respawn_time) // don't show a negative value while the server is respawning the player (lag)
+                               str = _("^1Respawning...");
+                       else
+                               str = sprintf(_("^1Respawning in ^3%s^1 seconds..."), ftos_decimals(respawn_time - time, autocvar_scoreboard_respawntime_decimals));
+               }
+               else if(time < respawn_time)
+                       str = sprintf(_("You are dead, wait ^3%s^7 seconds before respawning"), ftos_decimals(respawn_time - time, autocvar_scoreboard_respawntime_decimals));
+               else if(time >= respawn_time)
+                       str = sprintf(_("You are dead, press ^2%s^7 to respawn"), getcommandkey("jump", "+jump"));
+
+               pos_y += 1.2 * hud_fontsize_y;
+               drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, TRUE, hud_fontsize)), str, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+       }
+
        scoreboard_bottom = pos_y + 2 * hud_fontsize_y;
 }
index c270b61a96efa51308b779c733231f2e6284dd47..75f5a0bde762037387dbeb344989a47b1409bc01 100644 (file)
@@ -179,6 +179,8 @@ const float STAT_VEHICLESTAT_RELOAD2 = 66;
 const float STAT_SECRETS_TOTAL = 70;
 const float STAT_SECRETS_FOUND = 71;
 
+const float STAT_RESPAWN_TIME = 72;
+
 // mod stats (1xx)
 const float STAT_REDALIVE = 100;
 const float STAT_BLUEALIVE = 101;
index 71431693ae22e138fbe8f49102d2b81b7e62943b..7ccbacbf314fd191cde32f899bfa1c86e2f36593 100644 (file)
@@ -2167,6 +2167,7 @@ void SpectateCopy(entity spectatee) {
        self.dmg_inflictor = spectatee.dmg_inflictor;
        self.v_angle = spectatee.v_angle;
        self.angles = spectatee.v_angle;
+       self.stat_respawn_time = spectatee.stat_respawn_time;
        if(!self.BUTTON_USE)
                self.fixangle = TRUE;
        setorigin(self, spectatee.origin);
@@ -2558,6 +2559,11 @@ void PlayerPreThink (void)
        self.stat_allow_oldnexbeam = autocvar_g_allow_oldnexbeam;
        self.stat_leadlimit = autocvar_leadlimit;
 
+       if(g_arena || (g_ca && !allowed_to_spawn))
+               self.stat_respawn_time = 0;
+       else
+               self.stat_respawn_time = self.respawn_time;
+
        if(frametime)
        {
                // physics frames: update anticheat stuff
@@ -2730,6 +2736,11 @@ void PlayerPreThink (void)
                                }
                                ShowRespawnCountdown();
                        }
+
+                       // if respawning, invert stat_respawn_time to indicate this, the client translates it
+                       if(self.deadflag == DEAD_RESPAWNING && self.stat_respawn_time > 0)
+                               self.stat_respawn_time *= -1;
+
                        return;
                }
                // FIXME from now on self.deadflag is always 0 (and self.health is never < 1)
index e473b614b3abbc64d7a75bc4a7e56910521a018c..876608745dce17b1dea69d02373d6feca26b14a2 100644 (file)
@@ -408,6 +408,30 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                take = damage;
        }
 
+       if(attacker == self)
+       {
+               // don't reset pushltime for self damage as it may be an attempt to
+               // escape a lava pit or similar
+               //self.pushltime = 0;
+               self.istypefrag = 0;
+       }
+       else if(attacker.classname == "player")
+       {
+               self.pusher = attacker;
+               self.pushltime = time + autocvar_g_maxpushtime;
+               self.istypefrag = self.BUTTON_CHAT;
+       }
+       else if(time < self.pushltime)
+       {
+               attacker = self.pusher;
+               self.pushltime = max(self.pushltime, time + 0.6);
+       }
+       else
+       {
+               self.pushltime = 0;
+               self.istypefrag = 0;
+       }
+
        frag_inflictor = inflictor;
        frag_attacker = attacker;
        frag_target = self;
@@ -492,29 +516,8 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
        self.dmg_take = self.dmg_take + take;//max(take - 10, 0);
        self.dmg_inflictor = inflictor;
 
-       if(attacker == self)
-       {
-               // don't reset pushltime for self damage as it may be an attempt to
-               // escape a lava pit or similar
-               //self.pushltime = 0;
-               self.istypefrag = 0;
-       }
-       else if(attacker.classname == "player")
-       {
-               self.pusher = attacker;
-               self.pushltime = time + autocvar_g_maxpushtime;
-               self.istypefrag = self.BUTTON_CHAT;
-       }
-       else if(time < self.pushltime)
-       {
-               attacker = self.pusher;
-               self.pushltime = max(self.pushltime, time + 0.6);
-       }
-       else
-       {
-               self.pushltime = 0;
-               self.istypefrag = 0;
-       }
+       if(g_ca && self != attacker && attacker.classname == "player")
+               PlayerScore_Add(attacker, SP_SCORE, (damage - excess) * autocvar_g_ca_damage2score_multiplier);
 
        float abot, vbot, awep;
        abot = (clienttype(attacker) == CLIENTTYPE_BOT);
index d81f22924589640bf40b32c98232fa16d47aa693..8b6d65e1214d8e60cbd98578b4360ff7a5ec8437 100644 (file)
@@ -609,6 +609,8 @@ float serverflags;
 .entity muzzle_flash;
 .float misc_bulletcounter;     // replaces uzi & hlac bullet counter.
 
+.float stat_respawn_time; // shows respawn time, and is negative when awaiting respawn
+
 void PlayerUseKey();
 
 typedef vector(entity player, entity spot, vector current) spawn_evalfunc_t;
index d2cc61db3346cb3405ca086e9d025657fd2a4c6f..1e7d2815d501af4bc8bb9d1df2177e7b13bbbcdb 100644 (file)
@@ -854,8 +854,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                                                        if(deathtype & HITTYPE_HEADSHOT)
                                                                headshot = 1;
                                                }
-                                               if(g_ca)
-                                                       PlayerScore_Add(attacker, SP_SCORE, damage * autocvar_g_ca_damage2score_multiplier);
                                        }
                                }
                                else
index 4cd5cc810a1c9f456bc372c0e8106e9b2d274488..69bf57d51b4af98e37a6f79e55d45cdc4cffe841 100644 (file)
@@ -830,6 +830,9 @@ void spawnfunc_worldspawn (void)
        // secrets
        addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total);
        addstat(STAT_SECRETS_FOUND, AS_FLOAT, stat_secrets_found);
+
+       // misc
+       addstat(STAT_RESPAWN_TIME, AS_FLOAT, stat_respawn_time);
        
        next_pingtime = time + 5;
 
index 7e253ddf9dafbe3f50f3d247890e8573edb841bf..40a925b3ce835fbc24c9b64f424d9022690dd0bc 100644 (file)
@@ -10,7 +10,7 @@ MUTATOR_HOOKFUNCTION(vampire_PlayerDamage)
        else
        {
                // otherwise: each hit gets damage back
-               frag_attacker.health += damage_take;
+               frag_attacker.health = frag_attacker.health + bound(0, damage_take, self.health);
        }
        return 0;
 }