From: Mario Date: Fri, 22 Feb 2013 15:49:58 +0000 (+1100) Subject: Remove runematch gamemode X-Git-Tag: xonotic-v0.7.0~79^2~2^2~1 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=dca461716d4204384f9bbf8826c05045d59832c7;p=xonotic%2Fxonotic-data.pk3dir.git Remove runematch gamemode --- diff --git a/gamemodes.cfg b/gamemodes.cfg index 6cff7e5a4..a0b8a80d2 100644 --- a/gamemodes.cfg +++ b/gamemodes.cfg @@ -26,7 +26,6 @@ alias cl_hook_gamestart_dm alias cl_hook_gamestart_tdm alias cl_hook_gamestart_dom alias cl_hook_gamestart_ctf -alias cl_hook_gamestart_rune alias cl_hook_gamestart_lms alias cl_hook_gamestart_arena alias cl_hook_gamestart_ca @@ -48,7 +47,6 @@ alias sv_hook_gamestart_dm alias sv_hook_gamestart_tdm alias sv_hook_gamestart_dom alias sv_hook_gamestart_ctf -alias sv_hook_gamestart_rune alias sv_hook_gamestart_lms alias sv_hook_gamestart_arena alias sv_hook_gamestart_ca @@ -79,8 +77,6 @@ seta g_arena_point_limit -1 "Arena point limit overriding the mapinfo specified seta g_arena_point_leadlimit -1 "Arena point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" seta g_domination_point_limit -1 "Domination point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" seta g_domination_point_leadlimit -1 "Domination point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" -seta g_runematch_point_limit -1 "Runematch point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" -seta g_runematch_point_leadlimit -1 "Runematch point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" seta g_keyhunt_point_limit -1 "Keyhunt point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" seta g_keyhunt_point_leadlimit -1 "Keyhunt point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" seta g_race_laps_limit -1 "Race laps limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" @@ -105,9 +101,6 @@ set g_dom_weapon_stay 0 set g_lms_respawn_delay 0 set g_lms_respawn_waves 0 set g_lms_weapon_stay 0 -set g_rune_respawn_delay 0 -set g_rune_respawn_waves 0 -set g_rune_weapon_stay 0 set g_tdm_respawn_delay 0 set g_tdm_respawn_waves 0 set g_tdm_weapon_stay 0 @@ -414,61 +407,3 @@ set g_race 0 "Race: be faster than your opponents" set g_race_qualifying_timelimit 0 set g_race_qualifying_timelimit_override -1 set g_race_teams 0 "when 2, 3, or 4, the race is played as a team game (the team members can add up their laps)" - - -// =========== -// runematch -// =========== -set g_runematch 0 "Runematch: pick up and hold the runes, special items that give you points, a special power (rune) and a disadvantage (curse)" -set g_runematch_pointrate 5 -set g_runematch_fixedspawns 1 "use fixed runematch spawns if available" -set g_runematch_pointamt 1 -set g_runematch_shuffletime 30 "how often runes change position" -set g_runematch_respawntime 15 "how soon after being dropped to respawn" -set g_runematch_frags_killedby_runeholder 4 -set g_runematch_frags_killed_runeholder 5 -set g_runematch_frags_norune 0 -set g_runematch_drop_runes_max 2 "only drop up to 2 runes, the rest should respawn" -set g_runematch_allow_same 0 "allow matching rune-curse pairs" -set g_runematch_rune_alpha 0.78 -set g_runematch_rune_effects 544 "EF_ADDITIVE + EF_FULLBRIGHT = 544" -set g_runematch_rune_glow_size 0 -set g_runematch_rune_glow_color 0 -set g_runematch_rune_color_strength 1.0 -// strength/weakness -set g_balance_rune_strength_damage 2.0 -set g_balance_rune_strength_force 1.5 -set g_balance_curse_weak_damage 0.5 -set g_balance_curse_weak_force 0.6 -set g_balance_rune_strength_combo_damage 0.9 -set g_balance_rune_strength_combo_force 1.0 -// defense/vulner -set g_balance_rune_defense_takedamage 0.5 -set g_balance_curse_vulner_takedamage 2.0 -set g_balance_rune_defense_combo_takedamage 1.0 -// vampire/empathy -set g_balance_rune_vampire_absorb 0.4 -set g_balance_curse_empathy_takedamage -0.4 -set g_balance_rune_vampire_combo_absorb -0.1 -set g_balance_rune_vampire_maxhealth 500 -set g_balance_curse_empathy_minhealth 20 -set g_balance_rune_vampire_combo_minhealth 40 -// regen/venom -set g_balance_rune_regen_hpmod 1.75 -set g_balance_curse_venom_hpmod 0.6 -set g_balance_rune_regen_combo_hpmod 0.9 -set g_balance_rune_regen_regenrate 3.0 -set g_balance_curse_venom_rotrate 3.0 -set g_balance_rune_regen_combo_regenrate 0.5 -set g_balance_rune_regen_combo_rotrate 1.5 -set g_balance_rune_regen_limitmod 1 -set g_balance_curse_venom_limitmod 1 -set g_balance_rune_regen_combo_limitmod 1 -// speed/slow -set g_balance_rune_speed_atkrate 0.66 -set g_balance_curse_slow_atkrate 1.5 -set g_balance_rune_speed_combo_atkrate 1.2 -set g_balance_rune_speed_highspeed 1.5 -set g_balance_curse_slow_highspeed 0.6 -set g_balance_rune_speed_combo_highspeed 0.9 - diff --git a/gfx/menu/luminos/gametype_rune.tga b/gfx/menu/luminos/gametype_rune.tga deleted file mode 100644 index 6906411d3..000000000 Binary files a/gfx/menu/luminos/gametype_rune.tga and /dev/null differ diff --git a/gfx/menu/wickedx/gametype_rune.tga b/gfx/menu/wickedx/gametype_rune.tga deleted file mode 100644 index 6906411d3..000000000 Binary files a/gfx/menu/wickedx/gametype_rune.tga and /dev/null differ diff --git a/gfx/menu/xaw/gametype_rune.tga b/gfx/menu/xaw/gametype_rune.tga deleted file mode 100644 index 79c8f30b0..000000000 Binary files a/gfx/menu/xaw/gametype_rune.tga and /dev/null differ diff --git a/qcsrc/common/mapinfo.qc b/qcsrc/common/mapinfo.qc index f7ced4205..b4dbda25f 100644 --- a/qcsrc/common/mapinfo.qc +++ b/qcsrc/common/mapinfo.qc @@ -313,8 +313,6 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTF; else if(v == "team_CTF_blueflag") MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTF; - else if(v == "runematch_spawn_point") - MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_RUNEMATCH; else if(v == "target_assault_roundend") MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_ASSAULT; else if(v == "onslaught_generator") @@ -364,7 +362,6 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp else { MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_DEATHMATCH; // DM always works - MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_RUNEMATCH; // Rune always works MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_LMS; // LMS always works MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_KEEPAWAY; // Keepaway always works @@ -418,7 +415,6 @@ string _MapInfo_GetDefault(float t) case MAPINFO_TYPE_TEAM_DEATHMATCH: return "50 20 2 0"; case MAPINFO_TYPE_DOMINATION: return "200 20 0"; case MAPINFO_TYPE_CTF: return "300 20 10 0"; - case MAPINFO_TYPE_RUNEMATCH: return "200 20 0"; case MAPINFO_TYPE_LMS: return "9 20 0"; case MAPINFO_TYPE_ARENA: return "10 20 0"; case MAPINFO_TYPE_CA: return "10 20 0"; diff --git a/qcsrc/common/mapinfo.qh b/qcsrc/common/mapinfo.qh index bd67f67a8..10a35ee47 100644 --- a/qcsrc/common/mapinfo.qh +++ b/qcsrc/common/mapinfo.qh @@ -42,9 +42,6 @@ REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,"timelimit=20 lives=9 lea REGISTER_GAMETYPE(_("Arena"),arena,g_arena,ARENA,"timelimit=20 pointlimit=10 leadlimit=0") #define g_arena IS_GAMETYPE(ARENA) -REGISTER_GAMETYPE(_("Runematch"),rune,g_runematch,RUNEMATCH,"timelimit=20 pointlimit=200 leadlimit=0") -#define g_runematch IS_GAMETYPE(RUNEMATCH) - REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0") #define g_race IS_GAMETYPE(RACE) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create.c b/qcsrc/menu/xonotic/dialog_multiplayer_create.c index a53401693..3fc6f31fe 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create.c +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create.c @@ -153,7 +153,6 @@ void XonoticServerCreateTab_gameTypeChangeNotify(entity me) case MAPINFO_TYPE_CTF: GameType_ConfigureSliders(e, l, l2, _("Capture limit:"), 1, 20, 1, "capturelimit_override"); break; case MAPINFO_TYPE_DOMINATION: GameType_ConfigureSliders(e, l, l2, _("Point limit:"), 50, 500, 10, "g_domination_point_limit"); break; case MAPINFO_TYPE_KEYHUNT: GameType_ConfigureSliders(e, l, l2, _("Point limit:"), 200, 1500, 50, "g_keyhunt_point_limit"); break; - case MAPINFO_TYPE_RUNEMATCH: GameType_ConfigureSliders(e, l, l2, _("Point limit:"), 50, 500, 10, "g_runematch_point_limit"); break; case MAPINFO_TYPE_LMS: GameType_ConfigureSliders(e, l, l2, _("Lives:"), 3, 50, 1, "g_lms_lives_override"); break; case MAPINFO_TYPE_RACE: GameType_ConfigureSliders(e, l, l2, _("Laps:"), 1, 25, 1, "g_race_laps_limit"); break; case MAPINFO_TYPE_NEXBALL: GameType_ConfigureSliders(e, l, l2, _("Goals:"), 1, 50, 1, "g_nexball_goallimit"); break; diff --git a/qcsrc/menu/xonotic/util.qc b/qcsrc/menu/xonotic/util.qc index e80bf30e4..b4ca21385 100644 --- a/qcsrc/menu/xonotic/util.qc +++ b/qcsrc/menu/xonotic/util.qc @@ -609,7 +609,6 @@ float updateCompression() GAMETYPE(MAPINFO_TYPE_ONSLAUGHT) \ GAMETYPE(MAPINFO_TYPE_RACE) \ GAMETYPE(MAPINFO_TYPE_CTS) \ - GAMETYPE(MAPINFO_TYPE_RUNEMATCH) \ GAMETYPE(MAPINFO_TYPE_TEAM_DEATHMATCH) \ /* nothing */ diff --git a/qcsrc/server/arena.qc b/qcsrc/server/arena.qc index ef81fd92b..c364ecae3 100644 --- a/qcsrc/server/arena.qc +++ b/qcsrc/server/arena.qc @@ -22,7 +22,7 @@ float red_players, blue_players, yellow_players, pink_players; float total_players; /** - * Resets the state of all clients, items, flags, runes, keys, weapons, waypoints, ... of the map. + * Resets the state of all clients, items, flags, keys, weapons, waypoints, ... of the map. * Sets the 'warmup' global variable. */ void reset_map(float dorespawn) diff --git a/qcsrc/server/attic/runematch.qc b/qcsrc/server/attic/runematch.qc new file mode 100644 index 000000000..ba8f648c8 --- /dev/null +++ b/qcsrc/server/attic/runematch.qc @@ -0,0 +1,604 @@ +float rune_numspawns; + +float RUNE_FIRST = 1; +float RUNE_STRENGTH = 1; +float RUNE_DEFENSE = 2; +float RUNE_REGEN = 4; +float RUNE_SPEED = 8; +float RUNE_VAMPIRE = 16; +float RUNE_LAST = 16; + +float CURSE_FIRST = 8192; +float CURSE_WEAK = 8192; +float CURSE_VULNER = 16384; +float CURSE_VENOM = 32768; +float CURSE_SLOW = 65536; +float CURSE_EMPATHY = 131072; +float CURSE_LAST = 131072; + +float RUNE_COUNT = 5; + +/* rune ideas: + + Doom/Death + Rune: When you damage enemies, you have a slight chance of instant-killing them (porportional to damage dealt / their health) + Curse: When you are damaged, you have a chance of being instant-killed + + Vengence/Slothful + Rune: The lower your health below 100, the more damage you deal (does not decrease your damage if you're above 100) + Curse: The higher your health (up to 100), the less damage you deal (at 100 hp deal 1/5th damage) + +*/ + +/*QUAKED spawnfunc_runematch_spawn_point (1 0 0) (-16 -16 -24) (16 16 24) +spawn point for runes in runematch +*/ + +void spawnfunc_runematch_spawn_point() +{ + if(!g_runematch || !autocvar_g_runematch_fixedspawns) + { + remove(self); + return; + } + + setsize(self, '0 0 -35', '0 0 0'); + droptofloor(); + ++rune_numspawns; +} + +// only used if using rune spawns at all +entity rune_find_spawnpoint() +{ + entity e; + + if(rune_numspawns < RUNE_COUNT) + return world; + + RandomSelection_Init(); + + for(e = world; (e = find(e, classname, "runematch_spawn_point")); ) + if(e.owner == world) + RandomSelection_Add(e, 0, string_null, e.cnt, 0); + + return RandomSelection_chosen_ent; +} + +float rune_spawn_somewhere(entity e) +{ + entity spot; + spot = rune_find_spawnpoint(); + if(spot) + { + spot.owner = e; + setorigin(e, spot.origin); + + e.owner = spot; + spot.owner = e; + + return TRUE; + } + else + { + if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256)) + { + // great + makevectors(self.angles), + self.velocity = v_forward * 250; + self.angles = '0 0 0'; + return TRUE; + } + else + { + // sorry, can't spawn, better luck next frame + return FALSE; + } + } +} + +void rune_unmark_spot(entity e) +{ + if(e.owner.classname == "runematch_spawn_point") + { + e.owner.owner = world; + e.owner = world; + } +} + +string RuneName(float r) +{ + if(r == RUNE_STRENGTH) + return "^1Strength^7"; + if(r == RUNE_DEFENSE) + return "^4Defense^7"; + if(r == RUNE_REGEN) + return "^2Vitality^7"; + if(r == RUNE_SPEED) + return "^3Speed^7"; + if(r == RUNE_VAMPIRE) + return "^6Vampire^7"; + + if(r == CURSE_WEAK) + return "^1Weakness^7"; + if(r == CURSE_VULNER) + return "^4Vulnerability^7"; + if(r == CURSE_VENOM) + return "^2Venom^7"; + if(r == CURSE_SLOW) + return "^3Slow^7"; + if(r == CURSE_EMPATHY) + return "^6Empathy^7"; + return strcat("^8[unnamed", ftos(r), "]^7"); +} + +vector RuneColormod(float r) +{ + vector _color = '255 0 255'; + + if(r == RUNE_STRENGTH) + _color = '255 0 0'; + if(r == RUNE_DEFENSE) + _color = '0 0 255';//'0 102 255';// + if(r == RUNE_REGEN) + _color = '0 204 0';//'0 255 0'; + if(r == RUNE_SPEED) + _color = 0.35*'185 185 0';//255 230 0';//'255 255 0'; + if(r == RUNE_VAMPIRE) + _color = '64 0 128';//'108 0 217';//'128 0 255';//'179 0 204';// + + if(r == CURSE_WEAK) + _color = '255 0 0'; + if(r == CURSE_VULNER) + _color = '0 0 255';//'0 102 255';// + if(r == CURSE_VENOM) + _color = '0 204 0';//'0 255 0'; + if(r == CURSE_SLOW) + _color = 0.5*'185 185 0';//'255 255 0'; + if(r == CURSE_EMPATHY) + _color = '179 0 204';//'128 0 255'; + + return _color * (1 / 255) * autocvar_g_runematch_rune_color_strength; +} + +void rune_respawn(); + +void RuneCarriedThink() +{ + float rcount, rnum; + vector ang = '0 0 0'; + entity rune; + + if(self.owner.classname != "player" || time < game_starttime) + { + rune_respawn(); + return; + } + + self.nextthink = time + 0.1; + + // count runes my owner holds + rcount = 0; + rune = find(world, classname, "rune"); + rnum = -1; + while(rune) + { + if(rune.owner == self.owner) + rcount = rcount + 1; + if(rune == self) + rnum = rcount; + rune = find(rune, classname, "rune"); + } + + ang_y = rnum*(360 / rcount) + mod(time, 360)*45;//180; + + makevectors(ang); + + setorigin(self, v_forward*32); +} + +void rune_touch() +{ + if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) + { + self.think = rune_respawn; + self.nextthink = time; + return; + } + + if(other.classname != "player" || other.health < 1) + return; + if(self.wait > time) + return; // "notouch" time isn't finished + + // detach from the spawn point you're on + rune_unmark_spot(self); + + self.owner = other; + self.enemy.owner = other; + setattachment(self, other, ""); + + other.runes = other.runes | self.runes | self.enemy.runes; + + //self.think = func_null; + //self.nextthink = 0; + self.think = RuneCarriedThink; + self.nextthink = time; + self.touch = func_null; + + self.solid = SOLID_NOT; + setorigin(self, self.origin); + + //sprint(other, strcat("^3You have picked up ", + // RuneName(self.runes & (RUNE_LAST*2-1)), " and ")); + //sprint(other, strcat(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n")); + + bprint("^3", other.netname, "^7 has picked up ", + RuneName(self.runes & (RUNE_LAST*2-1)), "^7 and "); + bprint(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n"); +} + +void rune_respawn() +{ + rune_unmark_spot(self); + if(rune_spawn_somewhere(self)) + { + self.solid = SOLID_TRIGGER; + self.touch = rune_touch; + self.think = rune_respawn; + self.nextthink = time + autocvar_g_runematch_shuffletime;//30 + random()*5; // fixme: cvar + } + else + { + // try again later + self.think = rune_respawn; + self.nextthink = time; + } +} + +entity FindRune(entity own, string clname, float r) +{ + entity rune; + float _count, c; + + c = _count = 0; + rune = world; + + do + { + rune = find(rune, classname, clname); + if(!rune) + rune = find(rune, classname, clname); + if(!rune) + break; + if(rune.owner == own) + { + _count = _count + 1; + if(_count >= r) + return rune; + if(r <= 1) + return rune; + } + c = c + 1; + }while(c < 30); + return world; +} + + +void DropRune(entity pl, entity e) +{ + //entity pl; + + //pl = e.owner; + // detach from player + setattachment(e, world, ""); + e.owner = world; + e.enemy.owner = world; + // don't instantly touch player again + e.wait = time + 1; // "notouch" time + e.movetype = MOVETYPE_TOSS; + e.solid = SOLID_TRIGGER; + // reposition itself if not picked up soon + e.think = rune_respawn; + e.nextthink = time + autocvar_g_runematch_respawntime;//15 + random()*5; // fixme: cvar + e.touch = rune_touch; + + pl.runes = pl.runes - (pl.runes & (e.runes | e.enemy.runes)); + + // toss from player + setorigin(e, pl.origin + '0 0 10'); + e.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom(); + + + bprint("^3", pl.netname, "^7 has lost ", + RuneName(e.runes & (RUNE_LAST*2-1)), "^7 and "); + bprint(RuneName(e.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n"); +} + +float RuneMatchesCurse(float r, float c) +{ + float cr; + if(r & RUNE_STRENGTH) + cr = CURSE_WEAK; + else if(r & RUNE_DEFENSE) + cr = CURSE_VULNER; + else if(r & RUNE_REGEN) + cr = CURSE_VENOM; + else if(r & RUNE_SPEED) + cr = CURSE_SLOW; + else if(r & RUNE_VAMPIRE) + cr = CURSE_EMPATHY; + else return FALSE; // fixme: error? + + if(c & cr) + return TRUE; + return FALSE; +} + +// player died, drop runes +// each rune should pair up with a random curse and then be tossed from the player +void DropAllRunes(entity pl) +{ + entity rune, curse; + float rcount, ccount, r, c, rand, prevent_same, numtodrop, tries; + + entity curse1, rune1, curse2, rune2; + + rcount = ccount = r = c = 0; + rune = find(world, classname, "rune"); + while(rune) + { + if(rune.owner == pl) + rcount = rcount + 1; + rune = find(rune, classname, "rune"); + } + curse = find(world, classname, "curse"); + while(curse) + { + if(curse.owner == pl) + ccount = ccount + 1; + curse = find(curse, classname, "curse"); + } + + numtodrop = autocvar_g_runematch_drop_runes_max; + prevent_same = !autocvar_g_runematch_allow_same; + + do + { + rune = find(rune, classname, "rune"); + if(!rune) + break; + if(rune.owner != pl) + continue; + + + // find a random curse + tries = 15; + if(ccount > 1 && prevent_same) + { + // avoid pairing runes and curses that match each other + do{ + rand = floor(random()*ccount) + 1; + curse = FindRune(pl, "curse", rand); + tries = tries - 1; + }while(RuneMatchesCurse(rune.runes, curse.runes) && tries > 0); + if(tries <= 0) + { + bprint("warning: couldn't prevent same rune\n"); + } + } + else + { + rand = floor(random()*ccount) + 1; + curse = FindRune(pl, "curse", rand); + } + + if(!curse) + error("Couldn't fine curse to bind rune to\n"); + + // pair rune and curse + + rune1 = rune; + curse1 = curse; + rune2 = curse1.enemy; + curse2 = rune1.enemy; + + if(rune1 != rune2) // not already attached to each other + { + rune1.enemy = curse1; + curse1.enemy = rune1; + setattachment(curse1, rune1, ""); + rune2.enemy = curse2; + curse2.enemy = rune2; + setattachment(curse2, rune2, ""); + //DropRune(pl, rune2); + //ccount = ccount - 1; + //rcount = rcount - 1; + } + DropRune(pl, rune1); + + if(numtodrop <=0) + { + rune1.think = rune_respawn; + rune1.nextthink = time; + } + + numtodrop = numtodrop - 1; + + ccount = ccount - 1; + rcount = rcount - 1; + + }while(rune); +} + +void rune_reset() +{ + if(self.owner) + if(self.owner.classname != "runematch_spawn_point") + DropAllRunes(self.owner); + rune_respawn(); +} + +void spawn_runes() +{ + float rn, cs, runes_used, curses_used, prevent_same, numrunes; + entity e; + + if(self) + remove(self); + + // fixme: instead of placing them all now, why not + // simply create them all and let them call rune_respawn() as their think? + + runes_used = 0; + curses_used = 0; + + prevent_same = !autocvar_g_runematch_allow_same; + numrunes = RUNE_COUNT; + + while(numrunes > 0) + { + RandomSelection_Init(); + for(rn = RUNE_FIRST; rn <= RUNE_LAST; rn *= 2) + if not(runes_used & rn) + RandomSelection_Add(world, rn, string_null, 1, 1); + rn = RandomSelection_chosen_float; + + RandomSelection_Init(); + for(cs = CURSE_FIRST; cs <= CURSE_LAST; cs *= 2) + if not(curses_used & cs) + if not(prevent_same && cs == RuneMatchesCurse(rn, cs)) + RandomSelection_Add(world, cs, string_null, 1, 1); + cs = RandomSelection_chosen_float; + + if(!rn || !cs) + error("No rune/curse left"); + + runes_used |= rn; + curses_used |= cs; + + e = spawn(); + e.runes = rn; + e.classname = "rune"; + e.touch = rune_touch; + e.think = rune_respawn; + e.nextthink = time; + e.movetype = MOVETYPE_TOSS; + e.solid = SOLID_TRIGGER; + e.flags = FL_ITEM; + e.reset = rune_reset; + setmodel(e, "models/runematch/rune.mdl"); // precision set below + setsize(e, '0 0 -35', '0 0 0'); + + e.enemy = spawn(); + e.enemy.enemy = e; + e.enemy.classname = "curse"; + e.enemy.runes = cs; + //e.enemy.avelocity = '300 500 200'; + setmodel(e.enemy, "models/runematch/curse.mdl"); // precision set below + setorigin(e, '0 0 0'); + setattachment(e.enemy, e, ""); + + e.colormod = RuneColormod(rn); + e.enemy.colormod = RuneColormod(cs); + + e.alpha = e.enemy.alpha = autocvar_g_runematch_rune_alpha;//0.78; + e.effects = e.enemy.effects = autocvar_g_runematch_rune_effects | EF_LOWPRECISION;//EF_ADDITIVE;// | EF_FULLBRIGHT; + + //e.glow_size = e.enemy.glow_size = cvar("g_runematch_rune_glow_size"); + //e.glow_color = e.enemy.glow_color = cvar("g_runematch_rune_glow_color"); + + //rn = RUNE_FIRST; + //cs = CURSE_FIRST; + + numrunes = numrunes - 1; + } +} + +void runematch_init() +{ + if(!g_runematch) + return; + + entity e; + e = spawn(); + e.think = spawn_runes; + e.nextthink = time + 0.1; +} + + +float runematch_point_time; + +// give points to players who are holding runes +void RuneMatchGivePoints() +{ + entity rune; + + if(!g_runematch || !autocvar_g_runematch_pointamt) + return; + + if(gameover) + return; + + if(runematch_point_time > time) + return; + + runematch_point_time = time + autocvar_g_runematch_pointrate; + + rune = world; + do + { + rune = find(rune, classname, "rune"); + if(!rune) + return; + + if(rune.owner.classname == "player") + { + UpdateFrags(rune.owner, autocvar_g_runematch_pointamt); + } + }while(rune); +} + +float RunematchHandleFrags(entity attacker, entity targ, float f) +{ + entity head; + float arunes, trunes, newfrags; + + if(f <= 0) + return f; + if(attacker == targ) + return f; + + arunes = trunes = 0; + + head = find(world, classname, "rune"); + while(head) + { + if(head.owner == attacker) + { + arunes = arunes + 1; + } + else if(head.owner == targ) + { + trunes = trunes + 1; + } + + head = find(head, classname, "rune"); + } + + if(!arunes && !trunes) + return f - 1 + autocvar_g_runematch_frags_norune; // don't give points to players when no runes are involved. + + newfrags = 0; + if(arunes) + { // got a kill while holding runes + newfrags = newfrags + autocvar_g_runematch_frags_killedby_runeholder;//5; + } + if(trunes) + { // killed an enemy holding runes + newfrags = newfrags + autocvar_g_runematch_frags_killed_runeholder;//5; + } + if(newfrags) + f = f - 1 + newfrags; + + return f; +} diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 08a6297ad..e6b112981 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -178,16 +178,6 @@ float autocvar_g_balance_crylink_secondary_spread; float autocvar_g_balance_crylink_secondary_spreadtype; float autocvar_g_balance_crylink_reload_ammo; float autocvar_g_balance_crylink_reload_time; -float autocvar_g_balance_curse_empathy_minhealth; -float autocvar_g_balance_curse_empathy_takedamage; -float autocvar_g_balance_curse_slow_atkrate; -float autocvar_g_balance_curse_slow_highspeed; -float autocvar_g_balance_curse_venom_hpmod; -float autocvar_g_balance_curse_venom_limitmod; -float autocvar_g_balance_curse_venom_rotrate; -float autocvar_g_balance_curse_vulner_takedamage; -float autocvar_g_balance_curse_weak_damage; -float autocvar_g_balance_curse_weak_force; float autocvar_g_balance_damagepush_speedfactor; float autocvar_g_balance_electro_combo_comboradius; float autocvar_g_balance_electro_combo_damage; @@ -593,26 +583,6 @@ float autocvar_g_balance_rocketlauncher_speedaccel; float autocvar_g_balance_rocketlauncher_speedstart; float autocvar_g_balance_rocketlauncher_reload_ammo; float autocvar_g_balance_rocketlauncher_reload_time; -float autocvar_g_balance_rune_defense_combo_takedamage; -float autocvar_g_balance_rune_defense_takedamage; -float autocvar_g_balance_rune_regen_combo_hpmod; -float autocvar_g_balance_rune_regen_combo_limitmod; -float autocvar_g_balance_rune_regen_combo_regenrate; -float autocvar_g_balance_rune_regen_combo_rotrate; -float autocvar_g_balance_rune_regen_hpmod; -float autocvar_g_balance_rune_regen_limitmod; -float autocvar_g_balance_rune_regen_regenrate; -float autocvar_g_balance_rune_speed_atkrate; -float autocvar_g_balance_rune_speed_combo_atkrate; -float autocvar_g_balance_rune_speed_combo_highspeed; -float autocvar_g_balance_rune_speed_highspeed; -float autocvar_g_balance_rune_strength_combo_damage; -float autocvar_g_balance_rune_strength_combo_force; -float autocvar_g_balance_rune_strength_damage; -float autocvar_g_balance_rune_strength_force; -float autocvar_g_balance_rune_vampire_absorb; -float autocvar_g_balance_rune_vampire_combo_absorb; -float autocvar_g_balance_rune_vampire_maxhealth; float autocvar_g_balance_seeker_type; float autocvar_g_balance_seeker_flac_ammo; float autocvar_g_balance_seeker_flac_animtime; @@ -988,21 +958,6 @@ float autocvar_g_respawn_ghosts; float autocvar_g_respawn_ghosts_maxtime; float autocvar_g_respawn_ghosts_speed; float autocvar_g_respawn_waves; -float autocvar_g_runematch_allow_same; -float autocvar_g_runematch_drop_runes_max; -float autocvar_g_runematch_fixedspawns; -float autocvar_g_runematch_frags_killed_runeholder; -float autocvar_g_runematch_frags_killedby_runeholder; -float autocvar_g_runematch_frags_norune; -float autocvar_g_runematch_point_leadlimit; -#define autocvar_g_runematch_point_limit cvar("g_runematch_point_limit") -float autocvar_g_runematch_pointamt; -float autocvar_g_runematch_pointrate; -float autocvar_g_runematch_respawntime; -float autocvar_g_runematch_rune_alpha; -float autocvar_g_runematch_rune_color_strength; -float autocvar_g_runematch_rune_effects; -float autocvar_g_runematch_shuffletime; float autocvar_g_running_guns; float autocvar_g_shootfromcenter; float autocvar_g_shootfromclient; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 1c4f220e2..a403af329 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -401,7 +401,6 @@ void PutObserverInServer (void) WriteEntity(MSG_ONE, self); } - DropAllRunes(self); MUTATOR_CALLHOOK(MakePlayerObserver); minstagib_stop_countdown(self); @@ -475,7 +474,6 @@ void PutObserverInServer (void) self.think = func_null; self.nextthink = 0; self.hook_time = 0; - self.runes = 0; self.deadflag = DEAD_NO; self.angles = spot.angles; self.angles_z = 0; @@ -805,8 +803,6 @@ void PutClientInServer (void) self.metertime = 0; - self.runes = 0; - self.deadflag = DEAD_NO; self.angles = spot.angles; @@ -1638,7 +1634,6 @@ void ClientDisconnect (void) bprint ("^4",self.netname); bprint ("^4 disconnected\n"); - DropAllRunes(self); MUTATOR_CALLHOOK(ClientDisconnect); Portal_ClearAll(self); @@ -2001,32 +1996,6 @@ void player_regen (void) max_mod = regen_mod = rot_mod = limit_mod = 1; - if (self.runes & RUNE_REGEN) - { - if (self.runes & CURSE_VENOM) // do we have both rune/curse? - { - regen_mod = autocvar_g_balance_rune_regen_combo_regenrate; - max_mod = autocvar_g_balance_rune_regen_combo_hpmod; - limit_mod = autocvar_g_balance_rune_regen_combo_limitmod; - } - else - { - regen_mod = autocvar_g_balance_rune_regen_regenrate; - max_mod = autocvar_g_balance_rune_regen_hpmod; - limit_mod = autocvar_g_balance_rune_regen_limitmod; - } - } - else if (self.runes & CURSE_VENOM) - { - max_mod = autocvar_g_balance_curse_venom_hpmod; - if (self.runes & RUNE_REGEN) // do we have both rune/curse? - rot_mod = autocvar_g_balance_rune_regen_combo_rotrate; - else - rot_mod = autocvar_g_balance_curse_venom_rotrate; - limit_mod = autocvar_g_balance_curse_venom_limitmod; - //if (!self.runes & RUNE_REGEN) - // rot_mod = autocvar_g_balance_curse_venom_rotrate; - } maxh = maxh * max_mod; //maxa = maxa * max_mod; //maxf = maxf * max_mod; diff --git a/qcsrc/server/cl_physics.qc b/qcsrc/server/cl_physics.qc index 50401604e..6ddf7b69e 100644 --- a/qcsrc/server/cl_physics.qc +++ b/qcsrc/server/cl_physics.qc @@ -712,20 +712,6 @@ void SV_PlayerPhysics() else if(g_keepaway) maxspd_mod *= autocvar_g_keepaway_ballcarrier_highspeed; - if(g_runematch) - { - if(self.runes & RUNE_SPEED) - { - if(self.runes & CURSE_SLOW) - maxspd_mod *= autocvar_g_balance_rune_speed_combo_highspeed; - else - maxspd_mod *= autocvar_g_balance_rune_speed_highspeed; - } - else if(self.runes & CURSE_SLOW) - { - maxspd_mod *= autocvar_g_balance_curse_slow_highspeed; - } - } maxspd_mod *= autocvar_g_movement_highspeed; // fix physics stats for g_movement_highspeed diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index e81b08e58..73bf1bca7 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -590,7 +590,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht // print an obituary message Obituary (attacker, inflictor, self, deathtype); race_PreDie(); - DropAllRunes(self); // increment frag counter for used weapon type float w; diff --git a/qcsrc/server/cl_weaponsystem.qc b/qcsrc/server/cl_weaponsystem.qc index f697d3689..cf6ebed95 100644 --- a/qcsrc/server/cl_weaponsystem.qc +++ b/qcsrc/server/cl_weaponsystem.qc @@ -14,21 +14,6 @@ float W_WeaponRateFactor() float t; t = 1.0 / g_weaponratefactor; - if(g_runematch) - { - if(self.runes & RUNE_SPEED) - { - if(self.runes & CURSE_SLOW) - t = t * autocvar_g_balance_rune_speed_combo_atkrate; - else - t = t * autocvar_g_balance_rune_speed_atkrate; - } - else if(self.runes & CURSE_SLOW) - { - t = t * autocvar_g_balance_curse_slow_atkrate; - } - } - return t; } diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index bfea6b2bc..93e9d7c80 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -215,9 +215,6 @@ float intermission_running; float intermission_exittime; float alreadychangedlevel; - -.float runes; - // Keys player is holding .float itemkeys; // message delay for func_door locked by keys and key locks @@ -299,9 +296,6 @@ string gamemode_name; float startitem_failed; -void DropAllRunes(entity pl); - - typedef .float floatfield; floatfield Item_CounterField(float it); diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 31512fbff..d3fdd0973 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -186,11 +186,7 @@ void GiveFrags (entity attacker, entity targ, float f, float deathtype) else { self = oldself; - if(g_runematch) - { - f = RunematchHandleFrags(attacker, targ, f); - } - else if(g_lms) + if(g_lms) { // remove a life float tl; @@ -273,8 +269,6 @@ string AppendItemcodes(string s, entity player) s = strcat(s, "T"); if(player.kh_next) s = strcat(s, "K"); - if(player.runes) - s = strcat(s, "|", ftos(player.runes)); return s; } @@ -741,40 +735,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself } - if(g_runematch) - { - // apply strength rune - if (attacker.runes & RUNE_STRENGTH) - { - if(attacker.runes & CURSE_WEAK) // have both curse & rune - { - damage = damage * autocvar_g_balance_rune_strength_combo_damage; - force = force * autocvar_g_balance_rune_strength_combo_force; - } - else - { - damage = damage * autocvar_g_balance_rune_strength_damage; - force = force * autocvar_g_balance_rune_strength_force; - } - } - else if (attacker.runes & CURSE_WEAK) - { - damage = damage * autocvar_g_balance_curse_weak_damage; - force = force * autocvar_g_balance_curse_weak_force; - } - - // apply defense rune - if (targ.runes & RUNE_DEFENSE) - { - if (targ.runes & CURSE_VULNER) // have both curse & rune - damage = damage * autocvar_g_balance_rune_defense_combo_takedamage; - else - damage = damage * autocvar_g_balance_rune_defense_takedamage; - } - else if (targ.runes & CURSE_VULNER) - damage = damage * autocvar_g_balance_curse_vulner_takedamage; - } - // count the damage if(attacker) if(!targ.deadflag) @@ -866,42 +826,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float self.event_damage (inflictor, attacker, damage, deathtype, hitloc, force); self = oldself; - if(targ.classname == "player" && attacker.classname == "player" && attacker != targ && attacker.health > 2) - { - if(g_runematch) - { - if (attacker.runes & RUNE_VAMPIRE) - { - // apply vampire rune - if (attacker.runes & CURSE_EMPATHY) // have the curse too - { - //attacker.health = attacker.health + damage * autocvar_g_balance_rune_vampire_combo_absorb; - attacker.health = bound( - autocvar_g_balance_curse_empathy_minhealth, // LA: was 3, now 40 - attacker.health + damage * autocvar_g_balance_rune_vampire_combo_absorb, - autocvar_g_balance_rune_vampire_maxhealth); // LA: was 1000, now 500 - } - else - { - //attacker.health = attacker.health + damage * autocvar_g_balance_rune_vampire_absorb; - attacker.health = bound( - attacker.health, // LA: was 3, but changed so that you can't lose health - // empathy won't let you gain health in the same way... - attacker.health + damage * autocvar_g_balance_rune_vampire_absorb, - autocvar_g_balance_rune_vampire_maxhealth); // LA: was 1000, now 500 - } - } - // apply empathy curse - else if (attacker.runes & CURSE_EMPATHY) - { - attacker.health = bound( - autocvar_g_balance_curse_empathy_minhealth, // LA: was 3, now 20 - attacker.health + damage * autocvar_g_balance_curse_empathy_takedamage, - attacker.health); - } - } - } - // apply mirror damage if any if(mirrordamage > 0 || mirrorforce > 0) { diff --git a/qcsrc/server/g_triggers.qc b/qcsrc/server/g_triggers.qc index 293c78f00..12c75ae9e 100644 --- a/qcsrc/server/g_triggers.qc +++ b/qcsrc/server/g_triggers.qc @@ -476,17 +476,6 @@ void trigger_hurt_touch() Damage(other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0'); } } - else - { - if (!other.owner) - { - if (other.classname == "rune") // reset runes - { - EXACTTRIGGER_TOUCH; - other.nextthink = min(other.nextthink, time + 1); - } - } - } return; } diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 5e5fc4c7d..cac843b23 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -271,7 +271,6 @@ void cvar_changes_init() BADCVAR("g_onslaught"); BADCVAR("g_race"); BADCVAR("g_race_qualifying_timelimit"); - BADCVAR("g_runematch"); BADCVAR("g_tdm"); BADCVAR("g_tdm_teams"); BADCVAR("leadlimit"); @@ -315,7 +314,6 @@ void cvar_changes_init() BADCVAR("g_keyhunt_point_leadlimit"); BADPREFIX("g_mod_"); BADCVAR("g_nexball_goalleadlimit"); - BADCVAR("g_runematch_point_leadlimit"); BADCVAR("leadlimit_and_fraglimit"); BADCVAR("leadlimit_override"); BADCVAR("pausable"); @@ -381,7 +379,6 @@ void cvar_changes_init() BADCVAR("g_mirrordamage"); BADCVAR("g_nexball_goallimit"); BADCVAR("g_powerups"); - BADCVAR("g_runematch_point_limit"); BADCVAR("g_start_delay"); BADCVAR("g_warmup"); BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay"); diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index e3689cc3d..63ed488c0 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -1183,7 +1183,7 @@ void readlevelcvars(void) g_warmup_allguns = cvar("g_warmup_allguns"); g_warmup_allow_timeout = cvar("g_warmup_allow_timeout"); - if ((g_race && g_race_qualifying == 2) || g_runematch || g_arena || g_assault || cvar("g_campaign")) + if ((g_race && g_race_qualifying == 2) || g_arena || g_assault || cvar("g_campaign")) inWarmupStage = 0; // these modes cannot work together, sorry g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon"); @@ -1516,11 +1516,6 @@ void precache() { // gamemode related things precache_model ("models/misc/chatbubble.spr"); - if (g_runematch) - { - precache_model ("models/runematch/curse.mdl"); - precache_model ("models/runematch/rune.mdl"); - } #ifdef TTURRETS_ENABLED if (autocvar_g_turrets) diff --git a/qcsrc/server/mutators/base.qh b/qcsrc/server/mutators/base.qh index d90d564b5..35b2e6523 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -142,7 +142,7 @@ MUTATOR_HOOKABLE(PlayerDamage_SplitHealthArmor); float damage_save; MUTATOR_HOOKABLE(PlayerDamage_Calculate); - // called to adjust damage and force values which are applied to the player, used for e.g. strength damage/force multiplier or runematch runes + // called to adjust damage and force values which are applied to the player, used for e.g. strength damage/force multiplier // i'm not sure if I should change this around slightly (Naming of the entities, and also how they're done in g_damage). // INPUT: entity frag_attacker; diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index db9311610..e991f9765 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -96,7 +96,7 @@ g_subs.qc g_tetris.qc -runematch.qc +//runematch.qc arena.qc g_violence.qc diff --git a/qcsrc/server/runematch.qc b/qcsrc/server/runematch.qc deleted file mode 100644 index ba8f648c8..000000000 --- a/qcsrc/server/runematch.qc +++ /dev/null @@ -1,604 +0,0 @@ -float rune_numspawns; - -float RUNE_FIRST = 1; -float RUNE_STRENGTH = 1; -float RUNE_DEFENSE = 2; -float RUNE_REGEN = 4; -float RUNE_SPEED = 8; -float RUNE_VAMPIRE = 16; -float RUNE_LAST = 16; - -float CURSE_FIRST = 8192; -float CURSE_WEAK = 8192; -float CURSE_VULNER = 16384; -float CURSE_VENOM = 32768; -float CURSE_SLOW = 65536; -float CURSE_EMPATHY = 131072; -float CURSE_LAST = 131072; - -float RUNE_COUNT = 5; - -/* rune ideas: - - Doom/Death - Rune: When you damage enemies, you have a slight chance of instant-killing them (porportional to damage dealt / their health) - Curse: When you are damaged, you have a chance of being instant-killed - - Vengence/Slothful - Rune: The lower your health below 100, the more damage you deal (does not decrease your damage if you're above 100) - Curse: The higher your health (up to 100), the less damage you deal (at 100 hp deal 1/5th damage) - -*/ - -/*QUAKED spawnfunc_runematch_spawn_point (1 0 0) (-16 -16 -24) (16 16 24) -spawn point for runes in runematch -*/ - -void spawnfunc_runematch_spawn_point() -{ - if(!g_runematch || !autocvar_g_runematch_fixedspawns) - { - remove(self); - return; - } - - setsize(self, '0 0 -35', '0 0 0'); - droptofloor(); - ++rune_numspawns; -} - -// only used if using rune spawns at all -entity rune_find_spawnpoint() -{ - entity e; - - if(rune_numspawns < RUNE_COUNT) - return world; - - RandomSelection_Init(); - - for(e = world; (e = find(e, classname, "runematch_spawn_point")); ) - if(e.owner == world) - RandomSelection_Add(e, 0, string_null, e.cnt, 0); - - return RandomSelection_chosen_ent; -} - -float rune_spawn_somewhere(entity e) -{ - entity spot; - spot = rune_find_spawnpoint(); - if(spot) - { - spot.owner = e; - setorigin(e, spot.origin); - - e.owner = spot; - spot.owner = e; - - return TRUE; - } - else - { - if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256)) - { - // great - makevectors(self.angles), - self.velocity = v_forward * 250; - self.angles = '0 0 0'; - return TRUE; - } - else - { - // sorry, can't spawn, better luck next frame - return FALSE; - } - } -} - -void rune_unmark_spot(entity e) -{ - if(e.owner.classname == "runematch_spawn_point") - { - e.owner.owner = world; - e.owner = world; - } -} - -string RuneName(float r) -{ - if(r == RUNE_STRENGTH) - return "^1Strength^7"; - if(r == RUNE_DEFENSE) - return "^4Defense^7"; - if(r == RUNE_REGEN) - return "^2Vitality^7"; - if(r == RUNE_SPEED) - return "^3Speed^7"; - if(r == RUNE_VAMPIRE) - return "^6Vampire^7"; - - if(r == CURSE_WEAK) - return "^1Weakness^7"; - if(r == CURSE_VULNER) - return "^4Vulnerability^7"; - if(r == CURSE_VENOM) - return "^2Venom^7"; - if(r == CURSE_SLOW) - return "^3Slow^7"; - if(r == CURSE_EMPATHY) - return "^6Empathy^7"; - return strcat("^8[unnamed", ftos(r), "]^7"); -} - -vector RuneColormod(float r) -{ - vector _color = '255 0 255'; - - if(r == RUNE_STRENGTH) - _color = '255 0 0'; - if(r == RUNE_DEFENSE) - _color = '0 0 255';//'0 102 255';// - if(r == RUNE_REGEN) - _color = '0 204 0';//'0 255 0'; - if(r == RUNE_SPEED) - _color = 0.35*'185 185 0';//255 230 0';//'255 255 0'; - if(r == RUNE_VAMPIRE) - _color = '64 0 128';//'108 0 217';//'128 0 255';//'179 0 204';// - - if(r == CURSE_WEAK) - _color = '255 0 0'; - if(r == CURSE_VULNER) - _color = '0 0 255';//'0 102 255';// - if(r == CURSE_VENOM) - _color = '0 204 0';//'0 255 0'; - if(r == CURSE_SLOW) - _color = 0.5*'185 185 0';//'255 255 0'; - if(r == CURSE_EMPATHY) - _color = '179 0 204';//'128 0 255'; - - return _color * (1 / 255) * autocvar_g_runematch_rune_color_strength; -} - -void rune_respawn(); - -void RuneCarriedThink() -{ - float rcount, rnum; - vector ang = '0 0 0'; - entity rune; - - if(self.owner.classname != "player" || time < game_starttime) - { - rune_respawn(); - return; - } - - self.nextthink = time + 0.1; - - // count runes my owner holds - rcount = 0; - rune = find(world, classname, "rune"); - rnum = -1; - while(rune) - { - if(rune.owner == self.owner) - rcount = rcount + 1; - if(rune == self) - rnum = rcount; - rune = find(rune, classname, "rune"); - } - - ang_y = rnum*(360 / rcount) + mod(time, 360)*45;//180; - - makevectors(ang); - - setorigin(self, v_forward*32); -} - -void rune_touch() -{ - if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) - { - self.think = rune_respawn; - self.nextthink = time; - return; - } - - if(other.classname != "player" || other.health < 1) - return; - if(self.wait > time) - return; // "notouch" time isn't finished - - // detach from the spawn point you're on - rune_unmark_spot(self); - - self.owner = other; - self.enemy.owner = other; - setattachment(self, other, ""); - - other.runes = other.runes | self.runes | self.enemy.runes; - - //self.think = func_null; - //self.nextthink = 0; - self.think = RuneCarriedThink; - self.nextthink = time; - self.touch = func_null; - - self.solid = SOLID_NOT; - setorigin(self, self.origin); - - //sprint(other, strcat("^3You have picked up ", - // RuneName(self.runes & (RUNE_LAST*2-1)), " and ")); - //sprint(other, strcat(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n")); - - bprint("^3", other.netname, "^7 has picked up ", - RuneName(self.runes & (RUNE_LAST*2-1)), "^7 and "); - bprint(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n"); -} - -void rune_respawn() -{ - rune_unmark_spot(self); - if(rune_spawn_somewhere(self)) - { - self.solid = SOLID_TRIGGER; - self.touch = rune_touch; - self.think = rune_respawn; - self.nextthink = time + autocvar_g_runematch_shuffletime;//30 + random()*5; // fixme: cvar - } - else - { - // try again later - self.think = rune_respawn; - self.nextthink = time; - } -} - -entity FindRune(entity own, string clname, float r) -{ - entity rune; - float _count, c; - - c = _count = 0; - rune = world; - - do - { - rune = find(rune, classname, clname); - if(!rune) - rune = find(rune, classname, clname); - if(!rune) - break; - if(rune.owner == own) - { - _count = _count + 1; - if(_count >= r) - return rune; - if(r <= 1) - return rune; - } - c = c + 1; - }while(c < 30); - return world; -} - - -void DropRune(entity pl, entity e) -{ - //entity pl; - - //pl = e.owner; - // detach from player - setattachment(e, world, ""); - e.owner = world; - e.enemy.owner = world; - // don't instantly touch player again - e.wait = time + 1; // "notouch" time - e.movetype = MOVETYPE_TOSS; - e.solid = SOLID_TRIGGER; - // reposition itself if not picked up soon - e.think = rune_respawn; - e.nextthink = time + autocvar_g_runematch_respawntime;//15 + random()*5; // fixme: cvar - e.touch = rune_touch; - - pl.runes = pl.runes - (pl.runes & (e.runes | e.enemy.runes)); - - // toss from player - setorigin(e, pl.origin + '0 0 10'); - e.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom(); - - - bprint("^3", pl.netname, "^7 has lost ", - RuneName(e.runes & (RUNE_LAST*2-1)), "^7 and "); - bprint(RuneName(e.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n"); -} - -float RuneMatchesCurse(float r, float c) -{ - float cr; - if(r & RUNE_STRENGTH) - cr = CURSE_WEAK; - else if(r & RUNE_DEFENSE) - cr = CURSE_VULNER; - else if(r & RUNE_REGEN) - cr = CURSE_VENOM; - else if(r & RUNE_SPEED) - cr = CURSE_SLOW; - else if(r & RUNE_VAMPIRE) - cr = CURSE_EMPATHY; - else return FALSE; // fixme: error? - - if(c & cr) - return TRUE; - return FALSE; -} - -// player died, drop runes -// each rune should pair up with a random curse and then be tossed from the player -void DropAllRunes(entity pl) -{ - entity rune, curse; - float rcount, ccount, r, c, rand, prevent_same, numtodrop, tries; - - entity curse1, rune1, curse2, rune2; - - rcount = ccount = r = c = 0; - rune = find(world, classname, "rune"); - while(rune) - { - if(rune.owner == pl) - rcount = rcount + 1; - rune = find(rune, classname, "rune"); - } - curse = find(world, classname, "curse"); - while(curse) - { - if(curse.owner == pl) - ccount = ccount + 1; - curse = find(curse, classname, "curse"); - } - - numtodrop = autocvar_g_runematch_drop_runes_max; - prevent_same = !autocvar_g_runematch_allow_same; - - do - { - rune = find(rune, classname, "rune"); - if(!rune) - break; - if(rune.owner != pl) - continue; - - - // find a random curse - tries = 15; - if(ccount > 1 && prevent_same) - { - // avoid pairing runes and curses that match each other - do{ - rand = floor(random()*ccount) + 1; - curse = FindRune(pl, "curse", rand); - tries = tries - 1; - }while(RuneMatchesCurse(rune.runes, curse.runes) && tries > 0); - if(tries <= 0) - { - bprint("warning: couldn't prevent same rune\n"); - } - } - else - { - rand = floor(random()*ccount) + 1; - curse = FindRune(pl, "curse", rand); - } - - if(!curse) - error("Couldn't fine curse to bind rune to\n"); - - // pair rune and curse - - rune1 = rune; - curse1 = curse; - rune2 = curse1.enemy; - curse2 = rune1.enemy; - - if(rune1 != rune2) // not already attached to each other - { - rune1.enemy = curse1; - curse1.enemy = rune1; - setattachment(curse1, rune1, ""); - rune2.enemy = curse2; - curse2.enemy = rune2; - setattachment(curse2, rune2, ""); - //DropRune(pl, rune2); - //ccount = ccount - 1; - //rcount = rcount - 1; - } - DropRune(pl, rune1); - - if(numtodrop <=0) - { - rune1.think = rune_respawn; - rune1.nextthink = time; - } - - numtodrop = numtodrop - 1; - - ccount = ccount - 1; - rcount = rcount - 1; - - }while(rune); -} - -void rune_reset() -{ - if(self.owner) - if(self.owner.classname != "runematch_spawn_point") - DropAllRunes(self.owner); - rune_respawn(); -} - -void spawn_runes() -{ - float rn, cs, runes_used, curses_used, prevent_same, numrunes; - entity e; - - if(self) - remove(self); - - // fixme: instead of placing them all now, why not - // simply create them all and let them call rune_respawn() as their think? - - runes_used = 0; - curses_used = 0; - - prevent_same = !autocvar_g_runematch_allow_same; - numrunes = RUNE_COUNT; - - while(numrunes > 0) - { - RandomSelection_Init(); - for(rn = RUNE_FIRST; rn <= RUNE_LAST; rn *= 2) - if not(runes_used & rn) - RandomSelection_Add(world, rn, string_null, 1, 1); - rn = RandomSelection_chosen_float; - - RandomSelection_Init(); - for(cs = CURSE_FIRST; cs <= CURSE_LAST; cs *= 2) - if not(curses_used & cs) - if not(prevent_same && cs == RuneMatchesCurse(rn, cs)) - RandomSelection_Add(world, cs, string_null, 1, 1); - cs = RandomSelection_chosen_float; - - if(!rn || !cs) - error("No rune/curse left"); - - runes_used |= rn; - curses_used |= cs; - - e = spawn(); - e.runes = rn; - e.classname = "rune"; - e.touch = rune_touch; - e.think = rune_respawn; - e.nextthink = time; - e.movetype = MOVETYPE_TOSS; - e.solid = SOLID_TRIGGER; - e.flags = FL_ITEM; - e.reset = rune_reset; - setmodel(e, "models/runematch/rune.mdl"); // precision set below - setsize(e, '0 0 -35', '0 0 0'); - - e.enemy = spawn(); - e.enemy.enemy = e; - e.enemy.classname = "curse"; - e.enemy.runes = cs; - //e.enemy.avelocity = '300 500 200'; - setmodel(e.enemy, "models/runematch/curse.mdl"); // precision set below - setorigin(e, '0 0 0'); - setattachment(e.enemy, e, ""); - - e.colormod = RuneColormod(rn); - e.enemy.colormod = RuneColormod(cs); - - e.alpha = e.enemy.alpha = autocvar_g_runematch_rune_alpha;//0.78; - e.effects = e.enemy.effects = autocvar_g_runematch_rune_effects | EF_LOWPRECISION;//EF_ADDITIVE;// | EF_FULLBRIGHT; - - //e.glow_size = e.enemy.glow_size = cvar("g_runematch_rune_glow_size"); - //e.glow_color = e.enemy.glow_color = cvar("g_runematch_rune_glow_color"); - - //rn = RUNE_FIRST; - //cs = CURSE_FIRST; - - numrunes = numrunes - 1; - } -} - -void runematch_init() -{ - if(!g_runematch) - return; - - entity e; - e = spawn(); - e.think = spawn_runes; - e.nextthink = time + 0.1; -} - - -float runematch_point_time; - -// give points to players who are holding runes -void RuneMatchGivePoints() -{ - entity rune; - - if(!g_runematch || !autocvar_g_runematch_pointamt) - return; - - if(gameover) - return; - - if(runematch_point_time > time) - return; - - runematch_point_time = time + autocvar_g_runematch_pointrate; - - rune = world; - do - { - rune = find(rune, classname, "rune"); - if(!rune) - return; - - if(rune.owner.classname == "player") - { - UpdateFrags(rune.owner, autocvar_g_runematch_pointamt); - } - }while(rune); -} - -float RunematchHandleFrags(entity attacker, entity targ, float f) -{ - entity head; - float arunes, trunes, newfrags; - - if(f <= 0) - return f; - if(attacker == targ) - return f; - - arunes = trunes = 0; - - head = find(world, classname, "rune"); - while(head) - { - if(head.owner == attacker) - { - arunes = arunes + 1; - } - else if(head.owner == targ) - { - trunes = trunes + 1; - } - - head = find(head, classname, "rune"); - } - - if(!arunes && !trunes) - return f - 1 + autocvar_g_runematch_frags_norune; // don't give points to players when no runes are involved. - - newfrags = 0; - if(arunes) - { // got a kill while holding runes - newfrags = newfrags + autocvar_g_runematch_frags_killedby_runeholder;//5; - } - if(trunes) - { // killed an enemy holding runes - newfrags = newfrags + autocvar_g_runematch_frags_killed_runeholder;//5; - } - if(newfrags) - f = f - 1 + newfrags; - - return f; -} diff --git a/qcsrc/server/sv_main.qc b/qcsrc/server/sv_main.qc index c91c1ac18..d80b777a6 100644 --- a/qcsrc/server/sv_main.qc +++ b/qcsrc/server/sv_main.qc @@ -153,7 +153,6 @@ Called before each frame by the server float game_delay; float game_delay_last; -void RuneMatchGivePoints(); float RedirectionThink(); entity SelectSpawnPoint (float anypoint); void StartFrame (void) @@ -238,7 +237,6 @@ void StartFrame (void) CreatureFrame (); CheckRules_World (); - RuneMatchGivePoints(); bot_serverframe(); FOR_EACH_PLAYER(self) diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 1ed2f533b..ab586a1ac 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -52,7 +52,6 @@ string TeamNoName(float t) return "Neutral Team"; } -void runematch_init(); void tdm_init(); void entcs_init(); @@ -146,14 +145,6 @@ void InitGameplayMode() have_team_spawns = -1; // request team spawns } - if(g_runematch) - { - // ActivateTeamplay(); - fraglimit_override = autocvar_g_runematch_point_limit; - leadlimit_override = autocvar_g_runematch_point_leadlimit; - runematch_init(); - } - if(g_lms) { fraglimit_override = autocvar_g_lms_lives_override;