X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Frace.qc;h=e5b6960996dcf0bda60bc53d3790bc0abb2822ea;hb=dc02e4d78fb0e67b47a0c1e150b4c18c0711b8bf;hp=9a12a04866c2c251fdd333725f0a22c4af757fff;hpb=5de503ab3a50bb9a57dfd205bf8fb0d208273c44;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc index 9a12a0486..e5b696099 100644 --- a/qcsrc/server/race.qc +++ b/qcsrc/server/race.qc @@ -1,8 +1,15 @@ #include "race.qh" -#include +#include +#include +#include +#include +#include +#include #include +#include #include "client.qh" +#include "cheats.qh" #include "portals.qh" #include "scores.qh" #include "spawnpoints.qh" @@ -10,7 +17,7 @@ #include "command/getreplies.qh" #include "../common/deathtypes/all.qh" #include "../common/notifications/all.qh" -#include "../common/mapinfo.qh" +#include #include #include #include @@ -22,6 +29,17 @@ #include #include "../common/mutators/mutator/waypoints/waypointsprites.qh" +void write_recordmarker(entity pl, float tstart, float dt) +{ + GameLogEcho(strcat(":recordset:", ftos(pl.playerid), ":", ftos(dt))); + + // also write a marker into demo files for demotc-race-record-extractor to find + stuffcmd(pl, + strcat( + strcat("//", strconv(2, 0, 0, GetGametype()), " RECORD SET ", TIME_ENCODED_TOSTRING(TIME_ENCODE(dt))), + " ", ftos(tstart), " ", ftos(dt), "\n")); +} + IntrusiveList g_race_targets; IntrusiveList g_racecheckpoints; STATIC_INIT(g_race) @@ -749,9 +767,35 @@ bool race_waypointsprite_visible_for_player(entity this, entity player, entity v return false; } +void defrag_waypointsprites(entity targeted, entity checkpoint) +{ + for(entity t = findchain(target, targeted.targetname); t; t = t.chain) + { + if(t.modelindex) + { + entity s = WP_RaceStart; + + if(checkpoint.classname == "target_checkpoint") + s = WP_RaceCheckpoint; + else if(checkpoint.classname == "target_stopTimer") + s = WP_RaceFinish; + + vector o = (t.absmin + t.absmax) * 0.5; + + WaypointSprite_SpawnFixed(s, o, t, sprite, RADARICON_NONE); + + t.sprite.realowner = checkpoint; + t.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player; + } + + if(t.targetname) + defrag_waypointsprites(t, checkpoint); + } +} + void trigger_race_checkpoint_verify(entity this) { - static bool have_verified; + static bool have_verified; if (have_verified) return; have_verified = true; @@ -767,25 +811,25 @@ void trigger_race_checkpoint_verify(entity this) // race only (middle of the race) g_race_qualifying = false; pl_race_place = 0; - if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false)) { + if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) { error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for respawning in race) - bailing out")); - } + } if (i == 0) { // qualifying only g_race_qualifying = 1; pl_race_place = race_lowest_place_spawn; - if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false)) { + if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) { error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for qualifying) - bailing out")); - } + } // race only (initial spawn) g_race_qualifying = 0; for (int p = 1; p <= race_highest_place_spawn; ++p) { pl_race_place = p; - if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false)) { + if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) { error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for initially spawning in race) - bailing out")); - } + } } } } @@ -794,9 +838,9 @@ void trigger_race_checkpoint_verify(entity this) pl_race_checkpoint = race_NextCheckpoint(0); g_race_qualifying = 1; pl_race_place = race_lowest_place_spawn; - if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false)) { + if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) { error(strcat("Checkpoint 0 misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for qualifying) - bailing out")); - } + } } else { pl_race_checkpoint = race_NextCheckpoint(0); g_race_qualifying = 1; @@ -818,8 +862,8 @@ void trigger_race_checkpoint_verify(entity this) for (entity cp = NULL; (cp = find(cp, classname, "target_checkpoint"));) { if (argv(0) == cp.targetname) { cp.race_checkpoint = stof(argv(1)); - } - } + } + } } fclose(fh); } @@ -827,37 +871,12 @@ void trigger_race_checkpoint_verify(entity this) g_race_qualifying = qual; - IL_EACH(g_race_targets, it.classname == "target_checkpoint" || it.classname == "target_startTimer" || it.classname == "target_stopTimer", - { - if(it.targetname == "" || !it.targetname) // somehow this is a case... - continue; - entity cpt = it; - FOREACH_ENTITY_STRING(target, cpt.targetname, - { - vector org = (it.absmin + it.absmax) * 0.5; - if(cpt.race_checkpoint == 0) - WaypointSprite_SpawnFixed(WP_RaceStart, org, it, sprite, RADARICON_NONE); - else - WaypointSprite_SpawnFixed(WP_RaceCheckpoint, org, it, sprite, RADARICON_NONE); - - it.sprite.realowner = cpt; - it.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player; - }); - }); - if (race_timed_checkpoint) { if (defrag_ents) { IL_EACH(g_race_targets, it.classname == "target_checkpoint" || it.classname == "target_startTimer" || it.classname == "target_stopTimer", { - entity cpt = it; - if(it.classname == "target_startTimer" || it.classname == "target_stopTimer") { - if(it.targetname == "" || !it.targetname) // somehow this is a case... - continue; - FOREACH_ENTITY_STRING(target, cpt.targetname, { - if(it.sprite) - WaypointSprite_UpdateSprites(it.sprite, ((cpt.classname == "target_startTimer") ? WP_RaceStart : WP_RaceFinish), WP_Null, WP_Null); - }); - } + defrag_waypointsprites(it, it); + if(it.classname == "target_checkpoint") { if(it.race_checkpoint == -2) defragcpexists = -1; // something's wrong with the defrag cp file or it has not been written yet, set defragcpexists to -1 so that it will be rewritten when someone finishes @@ -868,17 +887,17 @@ void trigger_race_checkpoint_verify(entity this) for (entity cp = NULL; (cp = find(cp, classname, "target_checkpoint"));) { if (cp.race_checkpoint > largest_cp_id) { largest_cp_id = cp.race_checkpoint; - } - } + } + } for (entity cp = NULL; (cp = find(cp, classname, "target_stopTimer"));) { cp.race_checkpoint = largest_cp_id + 1; // finish line - } + } race_highest_checkpoint = largest_cp_id + 1; race_timed_checkpoint = largest_cp_id + 1; } else { for (entity cp = NULL; (cp = find(cp, classname, "target_stopTimer"));) { cp.race_checkpoint = 255; // finish line - } + } race_highest_checkpoint = 255; race_timed_checkpoint = 255; } @@ -887,14 +906,14 @@ void trigger_race_checkpoint_verify(entity this) { if (it.race_checkpoint == 0) { WaypointSprite_UpdateSprites(it.sprite, WP_RaceStart, WP_Null, WP_Null); - } else if (it.race_checkpoint == race_timed_checkpoint) { + } else if (it.race_checkpoint == race_timed_checkpoint) { WaypointSprite_UpdateSprites(it.sprite, WP_RaceFinish, WP_Null, WP_Null); } - }); + }); } } - if (defrag_ents) { + if (defrag_ents) { /* The following hack shall be removed when per-player trigger_multiple.wait is implemented for cts */ for (entity trigger = NULL; (trigger = find(trigger, classname, "trigger_multiple")); ) { for (entity targ = NULL; (targ = find(targ, targetname, trigger.target)); ) { if (targ.classname == "target_checkpoint" || targ.classname == "target_startTimer" || targ.classname == "target_stopTimer") {