From: Samual Lenks Date: Fri, 10 May 2013 05:11:27 +0000 (-0400) Subject: Merge remote-tracking branch 'origin/master' into Mario/classname_checks X-Git-Tag: xonotic-v0.7.0~57^2^2~1 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=c1fc567698f48fbfa3866c7a93406edad4823a1f;p=xonotic%2Fxonotic-data.pk3dir.git Merge remote-tracking branch 'origin/master' into Mario/classname_checks Conflicts: qcsrc/server/cl_client.qc qcsrc/server/g_damage.qc qcsrc/server/t_items.qc qcsrc/server/w_common.qc qcsrc/server/waypointsprites.qc --- c1fc567698f48fbfa3866c7a93406edad4823a1f diff --cc qcsrc/server/attic/assault.qc index 000000000,7a5662c97..71ac7239a mode 000000,100644..100644 --- a/qcsrc/server/attic/assault.qc +++ b/qcsrc/server/attic/assault.qc @@@ -1,0 -1,376 +1,376 @@@ + void spawnfunc_func_breakable(); + void target_objective_decrease_activate(); + .entity assault_decreaser; + .entity assault_sprite; + + void spawnfunc_info_player_attacker() { + if(!g_assault) + { + remove(self); + return; + } + self.team = NUM_TEAM_1; // red, gets swapped every round + spawnfunc_info_player_deathmatch(); + } + + void spawnfunc_info_player_defender() { + if(!g_assault) + { + remove(self); + return; + } + self.team = NUM_TEAM_2; // blue, gets swapped every round + spawnfunc_info_player_deathmatch(); + } + + // reset this objective. Used when spawning an objective + // and when a new round starts + void assault_objective_reset() { + self.health = ASSAULT_VALUE_INACTIVE; + } + + void assault_objective_use() { + // activate objective + self.health = 100; + //print("^2Activated objective ", self.targetname, "=", etos(self), "\n"); + //print("Activator is ", activator.classname, "\n"); + + entity oldself; + oldself = self; + + for(self = world; (self = find(self, target, oldself.targetname)); ) + { + if(self.classname == "target_objective_decrease") + target_objective_decrease_activate(); + } + + self = oldself; + } + + vector target_objective_spawn_evalfunc(entity player, entity spot, vector current) + { + if(self.health < 0 || self.health >= ASSAULT_VALUE_INACTIVE) + return '-1 0 0'; + return current; + } + + void spawnfunc_target_objective() { + if(!g_assault) + { + remove(self); + return; + } + self.classname = "target_objective"; + self.use = assault_objective_use; + assault_objective_reset(); + self.reset = assault_objective_reset; + self.spawn_evalfunc = target_objective_spawn_evalfunc; + } + + + // decrease the health of targeted objectives + void assault_objective_decrease_use() { + if(activator.team != assault_attacker_team) { + // wrong team triggered decrease + return; + } + + if(other.assault_sprite) + { + WaypointSprite_Disown(other.assault_sprite, waypointsprite_deadlifetime); + if(other.classname == "func_assault_destructible") + other.sprite = world; + } + else + return; // already activated! cannot activate again! + + if(self.enemy.health < ASSAULT_VALUE_INACTIVE) + { + if(self.enemy.health - self.dmg > 0.5) + { + PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.dmg); + self.enemy.health = self.enemy.health - self.dmg; + } + else + { + PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.enemy.health); + PlayerTeamScore_Add(activator, SP_ASSAULT_OBJECTIVES, ST_ASSAULT_OBJECTIVES, 1); + self.enemy.health = -1; + + entity oldself, oldactivator; + + oldself = self; + self = oldself.enemy; + if(self.message) + { + entity player; + string s; + FOR_EACH_PLAYER(player) + { + s = strcat(self.message, "\n"); + centerprint(player, s); + } + } + + oldactivator = activator; + activator = oldself; + SUB_UseTargets(); + activator = oldactivator; + self = oldself; + } + } + } + + void assault_setenemytoobjective() + { + entity objective; + for(objective = world; (objective = find(objective, targetname, self.target)); ) { + if(objective.classname == "target_objective") { + if(self.enemy == world) + self.enemy = objective; + else + objerror("more than one objective as target - fix the map!"); + break; + } + } + + if(self.enemy == world) + objerror("no objective as target - fix the map!"); + } + + float assault_decreaser_sprite_visible(entity e) + { + entity decreaser; + + decreaser = self.assault_decreaser; + + if(decreaser.enemy.health >= ASSAULT_VALUE_INACTIVE) + return FALSE; + + return TRUE; + } + + void target_objective_decrease_activate() + { + entity ent, spr; + self.owner = world; + for(ent = world; (ent = find(ent, target, self.targetname)); ) + { + if(ent.assault_sprite != world) + { + WaypointSprite_Disown(ent.assault_sprite, waypointsprite_deadlifetime); + if(ent.classname == "func_assault_destructible") + ent.sprite = world; + } + + spr = WaypointSprite_SpawnFixed("", 0.5 * (ent.absmin + ent.absmax), ent, assault_sprite, RADARICON_OBJECTIVE, '1 0.5 0'); + spr.assault_decreaser = self; + spr.waypointsprite_visible_for_player = assault_decreaser_sprite_visible; + spr.classname = "sprite_waypoint"; + WaypointSprite_UpdateRule(spr, assault_attacker_team, SPRITERULE_TEAMPLAY); + if(ent.classname == "func_assault_destructible") + { + WaypointSprite_UpdateSprites(spr, "as-defend", "as-destroy", "as-destroy"); + WaypointSprite_UpdateMaxHealth(spr, ent.max_health); + WaypointSprite_UpdateHealth(spr, ent.health); + ent.sprite = spr; + } + else + WaypointSprite_UpdateSprites(spr, "as-defend", "as-push", "as-push"); + } + } + + void target_objective_decrease_findtarget() + { + assault_setenemytoobjective(); + } + + //============================================================================= + + void spawnfunc_target_objective_decrease() { + if(!g_assault) + { + remove(self); + return; + } + + self.classname = "target_objective_decrease"; + + if(!self.dmg) { + self.dmg = 101; + } + self.use = assault_objective_decrease_use; + self.health = ASSAULT_VALUE_INACTIVE; + self.max_health = ASSAULT_VALUE_INACTIVE; + self.enemy = world; + + InitializeEntity(self, target_objective_decrease_findtarget, INITPRIO_FINDTARGET); + } + + // destructible walls that can be used to trigger target_objective_decrease + void spawnfunc_func_assault_destructible() { + if(!g_assault) + { + remove(self); + return; + } + self.spawnflags = 3; + self.classname = "func_assault_destructible"; + if(assault_attacker_team == NUM_TEAM_1) { + self.team = NUM_TEAM_2; + } else { + self.team = NUM_TEAM_1; + } + spawnfunc_func_breakable(); + } + + void assault_wall_think() { + if(self.enemy.health < 0) { + self.model = ""; + self.solid = SOLID_NOT; + } else { + self.model = self.mdl; + self.solid = SOLID_BSP; + } + + self.nextthink = time + 0.2; + } + + void spawnfunc_func_assault_wall() { + if(!g_assault) + { + remove(self); + return; + } + self.classname = "func_assault_wall"; + self.mdl = self.model; + setmodel(self, self.mdl); + self.solid = SOLID_BSP; + self.think = assault_wall_think; + self.nextthink = time; + InitializeEntity(self, assault_setenemytoobjective, INITPRIO_FINDTARGET); + } + + + void target_assault_roundend_reset() { + //print("round end reset\n"); + self.cnt = self.cnt + 1; // up round counter + self.winning = 0; // up round + } + + void target_assault_roundend_use() { + self.winning = 1; // round has been won by attackers + } + + void spawnfunc_target_assault_roundend() { + if(!g_assault) + { + remove(self); + return; + } + self.winning = 0; // round not yet won by attackers + self.classname = "target_assault_roundend"; + self.use = target_assault_roundend_use; + self.cnt = 0; // first round + self.reset = target_assault_roundend_reset; + } + + void assault_roundstart_use() { + + activator = self; + SUB_UseTargets(); + + + #ifdef TTURRETS_ENABLED + entity ent, oldself; + + //(Re)spawn all turrets + oldself = self; + ent = find(world, classname, "turret_main"); + while(ent) { + // Swap turret teams + if(ent.team == NUM_TEAM_1) + ent.team = NUM_TEAM_2; + else + ent.team = NUM_TEAM_1; + + self = ent; + + // Dubbles as teamchange + turret_stdproc_respawn(); + + ent = find(ent, classname, "turret_main"); + } + self = oldself; + #endif + + + } + + void spawnfunc_target_assault_roundstart() { + if(!g_assault) + { + remove(self); + return; + } + assault_attacker_team = NUM_TEAM_1; + self.classname = "target_assault_roundstart"; + self.use = assault_roundstart_use; + self.reset2 = assault_roundstart_use; + InitializeEntity(self, assault_roundstart_use, INITPRIO_FINDTARGET); + } + + // trigger new round + // reset objectives, toggle spawnpoints, reset triggers, ... + void vehicles_clearrturn(); + void vehicles_spawn(); + void assault_new_round() + { + entity oldself; + //bprint("ASSAULT: new round\n"); + + oldself = self; + // Eject players from vehicles + FOR_EACH_PLAYER(self) + { + if(self.vehicle) + vehicles_exit(VHEF_RELESE); + } + + self = findchainflags(vehicle_flags, VHF_ISVEHICLE); + while(self) + { + vehicles_clearrturn(); + vehicles_spawn(); + self = self.chain; + } + + self = oldself; + + // up round counter + self.winning = self.winning + 1; + + // swap attacker/defender roles + if(assault_attacker_team == NUM_TEAM_1) { + assault_attacker_team = NUM_TEAM_2; + } else { + assault_attacker_team = NUM_TEAM_1; + } + + + entity ent; + for(ent = world; (ent = nextent(ent)); ) + { - if(clienttype(ent) == CLIENTTYPE_NOTACLIENT) ++ if(IS_NOT_A_CLIENT(ent)) + { + if(ent.team_saved == NUM_TEAM_1) + ent.team_saved = NUM_TEAM_2; + else if(ent.team_saved == NUM_TEAM_2) + ent.team_saved = NUM_TEAM_1; + } + } + + // reset the level with a countdown + cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60)); + ReadyRestart_force(); // sets game_starttime + } diff --cc qcsrc/server/command/vote.qc index 125182c8a,e34464f16..dcbf4f32e --- a/qcsrc/server/command/vote.qc +++ b/qcsrc/server/command/vote.qc @@@ -330,11 -332,8 +330,8 @@@ void reset_map(float dorespawn race_ReadyRestart(); else MUTATOR_CALLHOOK(reset_map_global); - lms_lowest_lives = 999; - lms_next_place = player_count; - for(self = world; (self = nextent(self)); ) - if(clienttype(self) == CLIENTTYPE_NOTACLIENT) + if(IS_NOT_A_CLIENT(self)) { if(self.reset) { diff --cc qcsrc/server/g_damage.qc index c057619f6,8425308ac..da013fc75 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@@ -809,14 -754,9 +745,9 @@@ void Damage (entity targ, entity inflic if not(DEATH_ISSPECIAL(deathtype)) { - if(targ.classname == "player") // don't do this for vehicles + if(IS_PLAYER(targ)) // don't do this for vehicles - if(!g_minstagib) if(IsFlying(victim)) yoda = 1; - - if(g_minstagib) - if(victim.items & IT_STRENGTH) - yoda = 1; } } } diff --cc qcsrc/server/waypointsprites.qc index c45268443,c692b6e4a..d58985312 --- a/qcsrc/server/waypointsprites.qc +++ b/qcsrc/server/waypointsprites.qc @@@ -237,15 -237,9 +237,9 @@@ float WaypointSprite_Customize( // make spectators see what the player would see entity e; e = WaypointSprite_getviewentity(other); - + - // as a GENERAL rule: - // if you have the invisibility powerup, sprites ALWAYS are restricted to your team - // but only apply this to real players, not to spectators - if(g_minstagib && IS_CLIENT(self.owner) && (self.owner.items & IT_STRENGTH) && (e == other)) - { - if(!WaypointSprite_isteammate(self.owner, e)) - return FALSE; - } + if(MUTATOR_CALLHOOK(CustomizeWaypoint)) + return FALSE; return self.waypointsprite_visible_for_player(e); }