diff --git a/quakec/csqctest/src/common/pmove.qc b/quakec/csqctest/src/common/pmove.qc index ea390e73..812fe8b6 100644 --- a/quakec/csqctest/src/common/pmove.qc +++ b/quakec/csqctest/src/common/pmove.qc @@ -21,7 +21,8 @@ Any fields that are read need to be the same between csqc and ssqc code somehow. #define movevars_accelerate 10 #define movevars_stopspeed 100 #define movevars_maxspeed 320 -#define movevars_jumpheight 270 +#define movevars_maxairspeed 30 +#define movevars_jumpspeed 270 #define movevars_watersinkspeed 60 .float pmove_flags; @@ -30,6 +31,7 @@ Any fields that are read need to be the same between csqc and ssqc code somehow. .float gravity; #endif .entity groundentity; +static vector groundnormal; enumflags { @@ -194,8 +196,12 @@ void() PMove_InAirAccelerate = { if (!(self.pmove_flags & PMF_JUMP_HELD)) { - self.velocity_z += movevars_jumpheight; - self.pmove_flags |= PMF_ONGROUND; + //make sure we get at least jumpspeed upwards from the ground plane by clamping it first. + if (self.velocity*groundnormal < 0) + self.velocity = self.velocity - groundnormal*(self.velocity*groundnormal); + self.velocity_z += movevars_jumpspeed; + self.pmove_flags &~= PMF_ONGROUND; + self.pmove_flags |= PMF_JUMP_HELD; } } } @@ -208,8 +214,8 @@ void() PMove_InAirAccelerate = else { //there's no friction in air... - if (desiredspeed > 30) - desiredspeed = 30; + if (desiredspeed > movevars_maxairspeed) + desiredspeed = movevars_maxairspeed; PMove_Accelerate(desireddir, desiredspeed, movevars_accelerate); #ifdef HAVE_DOTGRAVITY @@ -249,6 +255,7 @@ void() PMove_Categorise = { //don't know, maybe we are, maybe we're not tracebox(self.origin, self.mins, self.maxs, self.origin-'0 0 1', false, self); + groundnormal = trace_plane_normal; if (trace_fraction == 1 || trace_plane_normal_z < 0.7) { self.pmove_flags &= ~PMF_ONGROUND; @@ -321,6 +328,17 @@ static void Pmove_Nudge(void) self.origin = org; }; +#ifdef SSQC +//small hack to make sure our cvars are actually stored as serverinfo (we then access them via serverkey for consistency between ssqc+csqc, safe in the knowledge that they'll be networked for us) +__accumulate void() worldspawn = +{ + if (autocvar(test_qwphys, "0") != serverkey("test_qwphys")) + localcmd(sprintf("setfl test_qwphys %S s\n", autocvar(test_qwphys, "0"))); + if (autocvar(test_autobunny, "0") != serverkey("test_autobunny")) + localcmd(sprintf("setfl test_autobunny %S s\n", autocvar(test_autobunny, "0"))); +}; +#endif + void(entity ent) PMove = { if (stof(serverkey("test_qwphys")) && checkbuiltin(runstandardplayerphysics)) @@ -334,7 +352,7 @@ void(entity ent) PMove = Pmove_Nudge(); - if (!(input_buttons & PMF_JUMP_HELD)) + if (!(input_buttons & 2) || serverkey("test_autobunny")) self.pmove_flags &= ~PMF_JUMP_HELD; PMove_Categorise(); @@ -376,10 +394,6 @@ void(entity ent) PMove = self.flags |= FL_ONGROUND; else self.flags &= ~FL_ONGROUND; - -#ifdef CSQC -cprint(sprintf("onground: %g", self.pmove_flags & PMF_ONGROUND)); -#endif }; #endif diff --git a/quakec/csqctest/src/cs/editor_lights.qc b/quakec/csqctest/src/cs/editor_lights.qc index f7bd4ca7..5a1433f3 100644 --- a/quakec/csqctest/src/cs/editor_lights.qc +++ b/quakec/csqctest/src/cs/editor_lights.qc @@ -9,7 +9,7 @@ static string editvalue; static entity tempent; void() editor_lights_add = { - __using(dynamiclight_get); + __using dynamiclight_get; float l; if (!tempent) @@ -47,7 +47,7 @@ static string fldname[8] = { }; static string(float fld, float foredit) readfield = { - __using(dynamiclight_get); + __using dynamiclight_get; switch(fld) { diff --git a/quakec/csqctest/src/cs/entrypoints.qc b/quakec/csqctest/src/cs/entrypoints.qc index 64aad34d..9d5eb3a2 100644 --- a/quakec/csqctest/src/cs/entrypoints.qc +++ b/quakec/csqctest/src/cs/entrypoints.qc @@ -453,8 +453,7 @@ void(float width, float height, float do2d) CSQC_UpdateView = void(float vwidth, float vheight, float notmenu) CSQC_UpdateViewLoading = { -print("in CSQC_UpdateViewLoading\n"); - drawfill([0,0],[vwidth,vheight], [0,1,0],1, 0); + drawfill([0,0],[vwidth,vheight], [0,0,0],1, 0); const vector tsize = '24 24'; string text = "CSQCTest is Loading!\nPlease wait..."; diff --git a/quakec/csqctest/src/cs/q3playerm.qc b/quakec/csqctest/src/cs/q3playerm.qc index 11cb2859..6164b44b 100644 --- a/quakec/csqctest/src/cs/q3playerm.qc +++ b/quakec/csqctest/src/cs/q3playerm.qc @@ -1158,7 +1158,7 @@ nonstatic vector(string skinname) Anim_GetHeadOffset = -float(float channel, string soundname, vector pos, float vol, float attenuation, float flags) CSQC_ServerSound = +static float(float channel, string soundname, vector pos, float vol, float attenuation, float flags) ServerSoundStartRequest = { //the server started a sound on an entity that the csqc has control over. if (!self.headent) { @@ -1244,11 +1244,17 @@ float(float channel, string soundname, vector pos, float vol, float attenuation, return false; }; +//version that breaks when the ent is not necessarily known to us, called only when 'self' is a known CSQC entity. +float(float channel, string soundname, vector org, float vol, float attenuation, float flags) CSQC_ServerSound = +{ + return ServerSoundStartRequest(channel, soundname, org, vol, attenuation, flags); +} +//version that lets the qc handle any ent fixups. float(float sventnum, float channel, string soundname, float vol, float att, vector org, float pitchmod, float flags) CSQC_Event_Sound = { self = findfloat(world, entnum, sventnum); if (self) - return CSQC_ServerSound(channel, soundname, org, vol, att, flags); + return ServerSoundStartRequest(channel, soundname, org, vol, att, flags); return false; }; #endif diff --git a/quakec/csqctest/src/optsall.qc b/quakec/csqctest/src/optsall.qc index 3b4ae103..6f7d2c95 100644 --- a/quakec/csqctest/src/optsall.qc +++ b/quakec/csqctest/src/optsall.qc @@ -29,6 +29,9 @@ #define NOT_DP //mute deprecation warnings about DP, we don't care. #endif +//just mute engine-dependancy deprecation warnings for now. +#define NOT_QSS +#define NOT_DP diff --git a/quakec/csqctest/src/ss/client.qc b/quakec/csqctest/src/ss/client.qc index 82dd4bc5..5ab65c31 100644 --- a/quakec/csqctest/src/ss/client.qc +++ b/quakec/csqctest/src/ss/client.qc @@ -1211,15 +1211,16 @@ void() ClientConnect = if (intermission_running) ExitIntermission (); + __using dimension_see; //csqc support checks are safe. just mute the splitscreen/mvd warnings. self.usingcsqc = stof(infokey(self, INFOKEY_P_CSQCACTIVE)); if (self.usingcsqc) { - self.dimension_see = 1; + self.dimension_see = DIMENSION_HASCSQC; sprint(self, "Welcome to csqctest!\n"); } else { - self.dimension_see = 3; + self.dimension_see = DIMENSION_NOCSQC; bprint(self.netname); bprint(" is not using csqc!\n"); @@ -1567,3 +1568,25 @@ void() SV_RunClientCommand = #endif }; +void(string cmd) SV_ParseClientCommand = +{ + tokenize(cmd); + switch(argv(0)) + { + case "give": //we have our own additions/behaviours. + GiveCommand_f(); + break; + + //case "god": + //case "noclip": + //case "fly": + //case "setpos": + //case "notarget": + //case "spiderpig": + //case "6dof": + default: //fallback. let the engine handle it. + clientcommand(self, cmd); + break; + } +}; + diff --git a/quakec/csqctest/src/ss/defs.qc b/quakec/csqctest/src/ss/defs.qc index a28f5b7c..746cf293 100644 --- a/quakec/csqctest/src/ss/defs.qc +++ b/quakec/csqctest/src/ss/defs.qc @@ -509,3 +509,8 @@ float isdp; #define sprint(pl,...) sprint(pl, PRINT_HIGH, __VA_ARGS__) #define bprint(...) bprint(PRINT_HIGH, __VA_ARGS__) #endif + +#define DIMENSION_NOCSQC 1 +#define DIMENSION_HASCSQC 2 +#define DIMENSION_DEFAULT 255 + diff --git a/quakec/csqctest/src/ss/weapons.qc b/quakec/csqctest/src/ss/weapons.qc index 3e4ae089..b3eaa0c8 100644 --- a/quakec/csqctest/src/ss/weapons.qc +++ b/quakec/csqctest/src/ss/weapons.qc @@ -389,13 +389,15 @@ void() s_explode1 = {self.think = s_explode1; makevolcano(); self.frame += 0.5; void() BecomeExplosion = { + __using dimension_seen, dimension_send; //okay for this purpose... + self.movetype = MOVETYPE_NONE; self.velocity = '0 0 0'; self.touch = SUB_Null; self.solid = SOLID_NOT; - self.dimension_seen = 2; - dimension_send = 2; + self.dimension_seen = DIMENSION_NOCSQC; + dimension_send = DIMENSION_NOCSQC; #if 1 WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); @@ -408,8 +410,8 @@ void() BecomeExplosion = #endif sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); - self.dimension_seen = 3; - dimension_send = 3; + self.dimension_seen = DIMENSION_DEFAULT; + dimension_send = DIMENSION_DEFAULT; setmodel (self, "progs/s_explod.spr"); s_explode1 (); @@ -1145,6 +1147,56 @@ void() CheatCommand = W_SetCurrentAmmo (); }; +void() GiveCommand_f = +{ + if (deathmatch || coop) + return; + + switch(argv(1)) + { + case "1": self.items |= IT_AXE; break; //not sure why you'd need this, but oh well. + case "2": self.items |= IT_SHOTGUN; break; //not sure why you'd need this, but oh well. + case "3": self.items |= IT_SUPER_SHOTGUN; break; + case "4": self.items |= IT_NAILGUN; break; + case "5": self.items |= IT_SUPER_NAILGUN; break; + case "6": self.items |= IT_GRENADE_LAUNCHER; break; + case "7": self.items |= IT_ROCKET_LAUNCHER; break; + case "8": self.items |= IT_LIGHTNING; break; + case "s": self.ammo_shells = stof(argv(2)); break; + case "n": self.ammo_nails = stof(argv(2)); break; + case "r": self.ammo_rockets = stof(argv(2)); break; + case "c": self.ammo_cells = stof(argv(2)); break; + case "h": self.health = stof(argv(2)); break; + case "a": + self.armorvalue = stof(argv(2)); + if (self.armorvalue < 1) + { //remove the armour type if they no longer have any. + self.armortype = 0; + self.items &= ~(IT_ARMOR1|IT_ARMOR2|IT_ARMOR3); + } + else if (self.armorvalue > 150 && self.armortype < 0.8) + { //prmote to red if its too high for yellow... + self.armortype = 0.8; + self.items = (self.items & ~(IT_ARMOR1|IT_ARMOR2|IT_ARMOR3)) | IT_ARMOR3; + } + else if (self.armorvalue > 100 && self.armortype < 0.6) + { //promote to yellow if its too high for green... + self.armortype = 0.6; + self.items = (self.items & ~(IT_ARMOR1|IT_ARMOR2|IT_ARMOR3)) | IT_ARMOR2; + } + else if (self.armortype < 0.3) + { //make sure we have at least green armour... + self.armortype = 0.3; + self.items = (self.items & ~(IT_ARMOR1|IT_ARMOR2|IT_ARMOR3)) | IT_ARMOR1; + } + break; + default: + sprint(self, "Item \"", argv(1), "\" not understood\n"); + break; + } + W_SetCurrentAmmo (); +}; + /* ============ CycleWeaponCommand