X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fmiscfunctions.qc;h=19465d09dd1a156e397abb29ca4fac14d7633ae8;hb=5c1853300daf8fd4855f5a693c86a1c05c79633c;hp=364c925991a893ccb2a75749cb57d9bd8a573104;hpb=406b13f464e47f8ca373b6bbe8ebe3bfc0f6be44;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 364c92599..19465d09d 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -81,19 +81,20 @@ float logfile; string GetAdvancedDeathReports(entity enPlayer) // Extra fragmessage information { - local float nPlayerHealth = rint(enPlayer.health); - local float nPlayerArmor = rint(enPlayer.armorvalue); - local float nPlayerHandicap = enPlayer.cvar_cl_handicap; - local float nPlayerPing = rint(enPlayer.ping); - local string strPlayerPingColor; - local string strMessage; + float nPlayerHealth = rint(enPlayer.health); + float nPlayerArmor = rint(enPlayer.armorvalue); + float nPlayerHandicap = enPlayer.cvar_cl_handicap; + float nPlayerPing = rint(enPlayer.ping); + string strPlayerPingColor; + string strMessage; + if(nPlayerPing >= 150) strPlayerPingColor = "^1"; else strPlayerPingColor = "^2"; if((autocvar_sv_fragmessage_information_stats) && (enPlayer.health >= 1)) - strMessage = strcat(strMessage, "\n^7(Health ^1", ftos(nPlayerHealth), "^7 / Armor ^2", ftos(nPlayerArmor), "^7)"); + strMessage = strcat(strMessage, "^7(Health ^1", ftos(nPlayerHealth), "^7 / Armor ^2", ftos(nPlayerArmor), "^7)"); if(autocvar_sv_fragmessage_information_ping) { if(clienttype(enPlayer) == CLIENTTYPE_BOT) // Bots have no ping @@ -113,12 +114,16 @@ string GetAdvancedDeathReports(entity enPlayer) // Extra fragmessage information } else if(autocvar_sv_fragmessage_information_handicap) { if(autocvar_sv_fragmessage_information_handicap == 2) if(nPlayerHandicap <= 1) - strMessage = strcat(strMessage, "\n^7(Handicap ^2Off^7)"); + strMessage = strcat(strMessage, "^7(Handicap ^2Off^7)"); else - strMessage = strcat(strMessage, "\n^7(Handicap ^2", ftos(nPlayerHandicap), "^7)"); + strMessage = strcat(strMessage, "^7(Handicap ^2", ftos(nPlayerHandicap), "^7)"); else if(nPlayerHandicap > 1) - strMessage = strcat(strMessage, "\n^7(Handicap ^2", ftos(nPlayerHandicap), "^7)"); + strMessage = strcat(strMessage, "^7(Handicap ^2", ftos(nPlayerHandicap), "^7)"); } + + if(strMessage) // add new line to the beginning if there is a message + strMessage = strcat("\n", strMessage); + return strMessage; } void bcenterprint(string s) @@ -236,6 +241,7 @@ void relocate_spawnpoint() if (have_team_spawns != 0) if (self.team) have_team_spawns = 1; + have_team_spawns_forteam[self.team] = 1; if (autocvar_r_showbboxes) { @@ -459,11 +465,6 @@ string formatmessage(string msg) replacement = cursor_ent.netname; if (!replacement || !cursor_ent) replacement = "nothing"; - } else if (escape == "p") { - if (self.last_selected_player) - replacement = self.last_selected_player.netname; - else - replacement = "(nobody)"; } else if (escape == "s") replacement = ftos(vlen(self.velocity - self.velocity_z * '0 0 1')); else if (escape == "S") @@ -583,10 +584,9 @@ void GetCvars(float f) MUTATOR_CALLHOOK(GetCvars); GetCvars_handleFloat(s, f, autoswitch, "cl_autoswitch"); GetCvars_handleFloat(s, f, cvar_cl_playerdetailreduction, "cl_playerdetailreduction"); - GetCvars_handleFloat(s, f, cvar_scr_centertime, "scr_centertime"); - GetCvars_handleFloat(s, f, cvar_cl_shownames, "cl_shownames"); GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion"); GetCvars_handleFloat(s, f, cvar_cl_handicap, "cl_handicap"); + GetCvars_handleFloat(s, f, cvar_cl_clippedspectating, "cl_clippedspectating"); GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriority, "cl_weaponpriority", W_FixWeaponOrder_ForceComplete_AndBuildImpulseList); GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[0], "cl_weaponpriority0", W_FixWeaponOrder_AllowIncomplete); GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[1], "cl_weaponpriority1", W_FixWeaponOrder_AllowIncomplete); @@ -616,25 +616,19 @@ void GetCvars(float f) GetCvars_handleFloatOnce(s, f, cvar_cl_gunalign, "cl_gunalign"); GetCvars_handleFloat(s, f, cvar_cl_allow_uid2name, "cl_allow_uid2name"); GetCvars_handleFloat(s, f, cvar_cl_allow_uidtracking, "cl_allow_uidtracking"); + GetCvars_handleFloat(s, f, cvar_cl_movement_track_canjump, "cl_movement_track_canjump"); + GetCvars_handleFloat(s, f, cvar_cl_newusekeysupported, "cl_newusekeysupported"); // fixup of switchweapon (needed for LMS or when spectating is disabled, as PutClientInServer comes too early) if (f > 0) { if (s == "cl_weaponpriority") self.switchweapon = w_getbestweapon(self); + if (s == "cl_allow_uidtracking") + PlayerStats_AddPlayer(self); } } -float fexists(string f) -{ - float fh; - fh = fopen(f, FILE_READ); - if (fh < 0) - return FALSE; - fclose(fh); - return TRUE; -} - void backtrace(string msg) { float dev, war; @@ -731,51 +725,11 @@ float NumberToTeamNumber(float number) return -1; } -#define CENTERPRIO_POINT 1 -#define CENTERPRIO_SPAM 2 -#define CENTERPRIO_VOTE 4 -#define CENTERPRIO_NORMAL 5 -#define CENTERPRIO_SHIELDING 7 -#define CENTERPRIO_MAPVOTE 9 -#define CENTERPRIO_IDLEKICK 50 -#define CENTERPRIO_ADMIN 99 -.float centerprint_priority; -.float centerprint_expires; -void centerprint_atprio(entity e, float prio, string s) -{ - if (intermission_running) - if (prio < CENTERPRIO_MAPVOTE) - return; - if (time > e.centerprint_expires) - e.centerprint_priority = 0; - if (prio >= e.centerprint_priority) - { - e.centerprint_priority = prio; - if (timeoutStatus == 2) - e.centerprint_expires = time + (e.cvar_scr_centertime * TIMEOUT_SLOWMO_VALUE); - else - e.centerprint_expires = time + e.cvar_scr_centertime; - centerprint_builtin(e, s); - } -} -void centerprint_expire(entity e, float prio) -{ - if (prio == e.centerprint_priority) - { - e.centerprint_priority = 0; - centerprint_builtin(e, ""); - } -} -void centerprint(entity e, string s) -{ - centerprint_atprio(e, CENTERPRIO_NORMAL, s); -} - // decolorizes and team colors the player name when needed string playername(entity p) { string t; - if (teams_matter && !intermission_running && p.classname == "player") + if (teamplay && !intermission_running && p.classname == "player") { t = Team_ColorCode(p.team); return strcat(t, strdecolorize(p.netname)); @@ -921,7 +875,11 @@ void readplayerstartcvars() s = "most"; } - if (s == "off") + if (s == "0" || s == "") + { + // no arena + } + else if (s == "off") { // forcibly turn off weaponarena } @@ -1022,23 +980,11 @@ void readplayerstartcvars() } else if(start_items & IT_UNLIMITED_WEAPON_AMMO) { - for (j = WEP_FIRST; j <= WEP_LAST; ++j) - { - e = get_weaponinfo(j); - if(start_weapons & e.weapons) - { - if(e.items & IT_ROCKETS) - start_ammo_rockets = 999; - if(e.items & IT_SHELLS) - start_ammo_shells = 999; - if(e.items & IT_CELLS) - start_ammo_cells = 999; - if(e.items & IT_NAILS) - start_ammo_nails = 999; - if(e.items & IT_FUEL) - start_ammo_fuel = 999; - } - } + start_ammo_rockets = 999; + start_ammo_shells = 999; + start_ammo_cells = 999; + start_ammo_nails = 999; + start_ammo_fuel = 999; } else { @@ -1235,7 +1181,6 @@ void readlevelcvars(void) g_bloodloss = cvar("g_bloodloss"); sv_maxidle = cvar("sv_maxidle"); sv_maxidle_spectatorsareidle = cvar("sv_maxidle_spectatorsareidle"); - sv_pogostick = cvar("sv_pogostick"); g_ctf_reverse = cvar("g_ctf_reverse"); sv_autotaunt = cvar("sv_autotaunt"); sv_taunt = cvar("sv_taunt"); @@ -1312,9 +1257,6 @@ void readlevelcvars(void) if(!g_weapon_stay) g_weapon_stay = cvar("g_weapon_stay"); - if (!g_weapon_stay && (cvar("deathmatch") == 2)) - g_weapon_stay = 1; - g_ghost_items = cvar("g_ghost_items"); if(g_ghost_items >= 1) @@ -1334,7 +1276,6 @@ void readlevelcvars(void) // Sound functions string precache_sound (string s) = #19; -void(entity e, float chan, string samp, float vol, float atten) sound_builtin = #8; float precache_sound_index (string s) = #19; #define SND_VOLUME 1 @@ -1366,12 +1307,24 @@ float sound_allowed(float dest, entity e) return TRUE; } +#ifdef COMPAT_XON010_CHANNELS +void(entity e, float chan, string samp, float vol, float atten) sound_builtin = #8; void sound(entity e, float chan, string samp, float vol, float atten) { if (!sound_allowed(MSG_BROADCAST, e)) return; sound_builtin(e, chan, samp, vol, atten); } +#else +#undef sound +void sound(entity e, float chan, string samp, float vol, float atten) +{ + if (!sound_allowed(MSG_BROADCAST, e)) + return; + sound7(e, chan, samp, vol, atten, 0, 0); +} +#endif + void soundtoat(float dest, entity e, vector o, float chan, string samp, float vol, float atten) { float entno, idx; @@ -1392,7 +1345,7 @@ void soundtoat(float dest, entity e, vector o, float chan, string samp, float vo sflags |= SND_VOLUME; if (atten != 64) sflags |= SND_ATTENUATION; - if (entno >= 8192) + if (entno >= 8192 || chan < 0 || chan > 7) sflags |= SND_LARGEENTITY; if (idx >= 256) sflags |= SND_LARGESOUND; @@ -1433,7 +1386,7 @@ void soundto(float dest, entity e, float chan, string samp, float vol, float att } void soundat(entity e, vector o, float chan, string samp, float vol, float atten) { - soundtoat(MSG_BROADCAST, e, o, chan, samp, vol, atten); + soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, atten); } void stopsoundto(float dest, entity e, float chan) { @@ -1444,7 +1397,7 @@ void stopsoundto(float dest, entity e, float chan) entno = num_for_edict(e); - if (entno >= 8192) + if (entno >= 8192 || chan < 0 || chan > 7) { float idx, sflags; idx = precache_sound_index("misc/null.wav"); @@ -1482,7 +1435,7 @@ void play2(entity e, string filename) { //stuffcmd(e, strcat("play2 ", filename, "\n")); msg_entity = e; - soundtoat(MSG_ONE, world, '0 0 0', CHAN_AUTO, filename, VOL_BASE, ATTN_NONE); + soundtoat(MSG_ONE, world, '0 0 0', CH_INFO, filename, VOL_BASE, ATTN_NONE); } // use this one if you might be causing spam (e.g. from touch functions that might get called more than once per frame) @@ -1520,7 +1473,7 @@ void play2all(string samp) if (autocvar_bot_sound_monopoly) return; - sound(world, CHAN_AUTO, samp, VOL_BASE, ATTN_NONE); + sound(world, CH_INFO, samp, VOL_BASE, ATTN_NONE); } void PrecachePlayerSounds(string f); @@ -1578,7 +1531,6 @@ void precache() { // gamemode related things precache_model ("models/misc/chatbubble.spr"); - precache_model ("models/misc/teambubble.spr"); if (g_runematch) { precache_model ("models/runematch/curse.mdl"); @@ -1664,6 +1616,7 @@ void precache() precache_model ("models/sprites/10.spr32"); // common weapon precaches + precache_sound ("weapons/reload.wav"); // until weapons have individual reload sounds, precache the reload sound here precache_sound ("weapons/weapon_switch.wav"); precache_sound ("weapons/weaponpickup.wav"); precache_sound ("weapons/unavailable.wav"); @@ -1710,6 +1663,29 @@ void precache() #define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement) #define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0 + +void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num) +{ + if (clienttype(e) == CLIENTTYPE_REAL) + { + msg_entity = e; + WRITESPECTATABLE_MSG_ONE({ + WriteByte(MSG_ONE, SVC_TEMPENTITY); + WriteByte(MSG_ONE, TE_CSQC_CENTERPRINT_GENERIC); + WriteByte(MSG_ONE, id); + WriteString(MSG_ONE, s); + if (id != 0 && s != "") + { + WriteByte(MSG_ONE, duration); + WriteByte(MSG_ONE, countdown_num); + } + }); + } +} +void Send_CSQC_Centerprint_Generic_Expire(entity e, float id) +{ + Send_CSQC_Centerprint_Generic(e, id, "", 1, 0); +} // WARNING: this kills the trace globals #define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return #define EXACTTRIGGER_INIT WarpZoneLib_ExactTrigger_Init() @@ -1775,6 +1751,8 @@ void remove_except_protected(entity e) void remove_unsafely(entity e) { + if(e.classname == "spike") + error("Removing spikes is forbidden (crylink bug), please report"); remove_builtin(e); } @@ -2007,7 +1985,8 @@ float SUB_NoImpactCheck() // these stop the projectile from moving, so... if(trace_dphitcontents == 0) { - dprint("A hit happened with zero hit contents... DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct.\n"); + //dprint("A hit happened with zero hit contents... DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct.\n"); + dprint(sprintf(_("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Profectile will self-destruct. (edict: %d, classname: %s, origin: %s)\n"), num_for_edict(self), self.classname, vtos(self.origin))); checkclient(); } if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) @@ -2034,17 +2013,27 @@ float SUB_NoImpactCheck() #define SUB_OwnerCheck() (other && (other == self.owner)) +void RemoveGrapplingHook(entity pl); +void W_Crylink_Dequeue(entity e); float WarpZone_Projectile_Touch_ImpactFilter_Callback() { if(SUB_OwnerCheck()) return TRUE; if(SUB_NoImpactCheck()) { - remove(self); + if(self.classname == "grapplinghook") + RemoveGrapplingHook(self.realowner); + else if(self.classname == "spike") + { + W_Crylink_Dequeue(self); + remove(self); + } + else + remove(self); return TRUE; } if(trace_ent && trace_ent.solid > SOLID_TRIGGER) - UpdateCSQCProjectileNextFrame(self); + UpdateCSQCProjectile(self); return FALSE; } #define PROJECTILE_TOUCH if(WarpZone_Projectile_Touch()) return @@ -2062,7 +2051,11 @@ void URI_Get_Callback(float id, float status, string data) dprint(data); dprint("\nEnd of data.\n"); - if (id == URI_GET_DISCARD) + if(url_URI_Get_Callback(id, status, data)) + { + // handled + } + else if (id == URI_GET_DISCARD) { // discard } @@ -2480,6 +2473,7 @@ float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, f { float m, i; vector start, org, delta, end, enddown, mstart; + entity sp; m = e.dphitcontentsmask; e.dphitcontentsmask = goodcontents | badcontents; @@ -2532,6 +2526,19 @@ float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, f if (trace_fraction >= 1) continue; + // rule 4: we must "see" some spawnpoint + for(sp = world; (sp = find(sp, classname, "info_player_deathmatch")); ) + if(checkpvs(mstart, sp)) + break; + if(!sp) + { + for(sp = world; (sp = findflags(sp, flags, FL_ITEM)); ) + if(checkpvs(mstart, sp)) + break; + if(!sp) + continue; + } + // find a random vector to "look at" end_x = org_x + random() * delta_x; end_y = org_y + random() * delta_y; @@ -2643,15 +2650,15 @@ vector shotorg_adjustfromclient(vector vecs, float y_is_right, float allowcenter { switch(algn) { - case 1: // right + default: + case 3: // right break; - case 2: // left + case 4: // left vecs_y = -vecs_y; break; - default: - case 3: + case 1: if(allowcenter) // 2: allow center handedness { // center @@ -2664,7 +2671,7 @@ vector shotorg_adjustfromclient(vector vecs, float y_is_right, float allowcenter } break; - case 4: + case 2: if(allowcenter) // 2: allow center handedness { // center @@ -2690,7 +2697,8 @@ vector shotorg_adjust_values(vector vecs, float y_is_right, float visual, float { if (visual) { - vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE, algn); + vecs_y = 0; + vecs_z -= 2; } else { @@ -2700,15 +2708,8 @@ vector shotorg_adjust_values(vector vecs, float y_is_right, float visual, float } else if (autocvar_g_shootfromcenter) { - if (visual) - { - vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE, algn); - } - else - { - vecs_y = 0; - vecs_z -= 2; - } + vecs_y = 0; + vecs_z -= 2; } else if ((s = autocvar_g_shootfromfixedorigin) != "") { @@ -3112,3 +3113,60 @@ void defer(float fdelay, void() func) e.think = defer_think; e.nextthink = time + fdelay; } + +.string aiment_classname; +.float aiment_deadflag; +void SetMovetypeFollow(entity ent, entity e) +{ + // FIXME this may not be warpzone aware + ent.movetype = MOVETYPE_FOLLOW; // make the hole follow + ent.solid = SOLID_NOT; // MOVETYPE_FOLLOW is always non-solid - this means this cannot be teleported by warpzones any more! Instead, we must notice when our owner gets teleported. + ent.aiment = e; // make the hole follow bmodel + ent.punchangle = e.angles; // the original angles of bmodel + ent.view_ofs = ent.origin - e.origin; // relative origin + ent.v_angle = ent.angles - e.angles; // relative angles + ent.aiment_classname = strzone(e.classname); + ent.aiment_deadflag = e.deadflag; +} +void UnsetMovetypeFollow(entity ent) +{ + ent.movetype = MOVETYPE_FLY; + PROJECTILE_MAKETRIGGER(ent); + ent.aiment = world; +} +float LostMovetypeFollow(entity ent) +{ +/* + if(ent.movetype != MOVETYPE_FOLLOW) + if(ent.aiment) + error("???"); +*/ + if(ent.aiment) + { + if(ent.aiment.classname != ent.aiment_classname) + return 1; + if(ent.aiment.deadflag != ent.aiment_deadflag) + return 1; + } + return 0; +} + +float isPushable(entity e) +{ + if(e.iscreature) + return TRUE; + switch(e.classname) + { + case "body": + case "droppedweapon": + case "keepawayball": + case "nexball_basketball": + case "nexball_football": + return TRUE; + case "bullet": // antilagged bullets can't hit this either + return FALSE; + } + if (e.projectiledeathtype) + return TRUE; + return FALSE; +}