From: Samual Lenks Date: Tue, 11 Jun 2013 07:12:55 +0000 (-0400) Subject: Delete the "attic" folder-- we have git history for a reason, no need for X-Git-Tag: xonotic-v0.8.0~366^2~18^2 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=e557ad1d2eaf0e18be5931c5548049aa4cfecb39;p=xonotic%2Fxonotic-data.pk3dir.git Delete the "attic" folder-- we have git history for a reason, no need for this folder to remain in master --- diff --git a/qcsrc/server/attic/assault.qc b/qcsrc/server/attic/assault.qc deleted file mode 100644 index 71ac7239a..000000000 --- a/qcsrc/server/attic/assault.qc +++ /dev/null @@ -1,376 +0,0 @@ -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(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 --git a/qcsrc/server/attic/bot/havocbot/role_assault.qc b/qcsrc/server/attic/bot/havocbot/role_assault.qc deleted file mode 100644 index 4456802d5..000000000 --- a/qcsrc/server/attic/bot/havocbot/role_assault.qc +++ /dev/null @@ -1,205 +0,0 @@ -#define HAVOCBOT_AST_ROLE_NONE 0 -#define HAVOCBOT_AST_ROLE_DEFENSE 2 -#define HAVOCBOT_AST_ROLE_OFFENSE 4 - -.float havocbot_role_flags; -.float havocbot_attack_time; - -.void() havocbot_role; -.void() havocbot_previous_role; - -void() havocbot_role_ast_defense; -void() havocbot_role_ast_offense; -.entity havocbot_ast_target; - -void(entity bot) havocbot_ast_reset_role; - -void(float ratingscale, vector org, float sradius) havocbot_goalrating_items; -void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers; - -void havocbot_goalrating_ast_targets(float ratingscale) -{ - entity ad, best, wp, tod; - float radius, found, bestvalue; - vector p; - - ad = findchain(classname, "func_assault_destructible"); - - for (; ad; ad = ad.chain) - { - if (ad.target == "") - continue; - - if not(ad.bot_attack) - continue; - - found = FALSE; - for(tod = world; (tod = find(tod, targetname, ad.target)); ) - { - if(tod.classname == "target_objective_decrease") - { - if(tod.enemy.health > 0 && tod.enemy.health < ASSAULT_VALUE_INACTIVE) - { - // dprint(etos(ad),"\n"); - found = TRUE; - break; - } - } - } - - if(!found) - { - /// dprint("target not found\n"); - continue; - } - /// dprint("target #", etos(ad), " found\n"); - - - p = 0.5 * (ad.absmin + ad.absmax); - // dprint(vtos(ad.origin), " ", vtos(ad.absmin), " ", vtos(ad.absmax),"\n"); - // te_knightspike(p); - // te_lightning2(world, '0 0 0', p); - - // Find and rate waypoints around it - found = FALSE; - best = world; - bestvalue = 99999999999; - for(radius=0; radius<1500 && !found; radius+=500) - { - for(wp=findradius(p, radius); wp; wp=wp.chain) - { - if(!(wp.wpflags & WAYPOINTFLAG_GENERATED)) - if(wp.classname=="waypoint") - if(checkpvs(wp.origin, ad)) - { - found = TRUE; - if(wp.cnt self.havocbot_role_timeout) - { - havocbot_ast_reset_role(self); - return; - } - - if(self.havocbot_attack_time>time) - return; - - if (self.bot_strategytime < time) - { - navigation_goalrating_start(); - havocbot_goalrating_enemyplayers(20000, self.origin, 650); - havocbot_goalrating_ast_targets(20000); - havocbot_goalrating_items(15000, self.origin, 10000); - navigation_goalrating_end(); - - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - } -} - -void havocbot_role_ast_defense() -{ - if(self.deadflag != DEAD_NO) - { - self.havocbot_attack_time = 0; - havocbot_ast_reset_role(self); - return; - } - - // Set the role timeout if necessary - if (!self.havocbot_role_timeout) - self.havocbot_role_timeout = time + 120; - - if (time > self.havocbot_role_timeout) - { - havocbot_ast_reset_role(self); - return; - } - - if(self.havocbot_attack_time>time) - return; - - if (self.bot_strategytime < time) - { - navigation_goalrating_start(); - havocbot_goalrating_enemyplayers(20000, self.origin, 3000); - havocbot_goalrating_ast_targets(20000); - havocbot_goalrating_items(15000, self.origin, 10000); - navigation_goalrating_end(); - - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - } -} - -void havocbot_role_ast_setrole(entity bot, float role) -{ - switch(role) - { - case HAVOCBOT_AST_ROLE_DEFENSE: - bot.havocbot_role = havocbot_role_ast_defense; - bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_DEFENSE; - bot.havocbot_role_timeout = 0; - break; - case HAVOCBOT_AST_ROLE_OFFENSE: - bot.havocbot_role = havocbot_role_ast_offense; - bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_OFFENSE; - bot.havocbot_role_timeout = 0; - break; - } -} - -void havocbot_ast_reset_role(entity bot) -{ - if(self.deadflag != DEAD_NO) - return; - - if(bot.team==assault_attacker_team) - havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_OFFENSE); - else - havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_DEFENSE); -} - -void havocbot_chooserole_ast() -{ - havocbot_ast_reset_role(self); -} diff --git a/qcsrc/server/attic/bot/havocbot/role_ctf.qc b/qcsrc/server/attic/bot/havocbot/role_ctf.qc deleted file mode 100644 index 0946f4342..000000000 --- a/qcsrc/server/attic/bot/havocbot/role_ctf.qc +++ /dev/null @@ -1,684 +0,0 @@ -#define HAVOCBOT_CTF_ROLE_NONE 0 -#define HAVOCBOT_CTF_ROLE_DEFENSE 2 -#define HAVOCBOT_CTF_ROLE_MIDDLE 4 -#define HAVOCBOT_CTF_ROLE_OFFENSE 8 -#define HAVOCBOT_CTF_ROLE_CARRIER 16 -#define HAVOCBOT_CTF_ROLE_RETRIEVER 32 -#define HAVOCBOT_CTF_ROLE_ESCORT 64 - -.void() havocbot_role; -.void() havocbot_previous_role; - -void() havocbot_role_ctf_middle; -void() havocbot_role_ctf_defense; -void() havocbot_role_ctf_offense; -void() havocbot_role_ctf_carrier; -void() havocbot_role_ctf_retriever; -void() havocbot_role_ctf_escort; - -void(entity bot) havocbot_ctf_reset_role; -void(float ratingscale, vector org, float sradius) havocbot_goalrating_items; -void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers; - -.float havocbot_cantfindflag; -.float havocbot_role_timeout; -.entity ctf_worldflagnext; -.entity bot_basewaypoint; - -entity ctf_worldflaglist; -vector havocbot_ctf_middlepoint; -float havocbot_ctf_middlepoint_radius; - -entity havocbot_ctf_find_flag(entity bot) -{ - entity f; - f = ctf_worldflaglist; - while (f) - { - if (bot.team == f.team) - return f; - f = f.ctf_worldflagnext; - } - return world; -} - -entity havocbot_ctf_find_enemy_flag(entity bot) -{ - entity f; - f = ctf_worldflaglist; - while (f) - { - if (bot.team != f.team) - return f; - f = f.ctf_worldflagnext; - } - return world; -} - -float havocbot_ctf_teamcount(entity bot, vector org, float radius) -{ - if not(teamplay) - return 0; - - float c = 0; - entity head; - - FOR_EACH_PLAYER(head) - { - if(head.team!=bot.team || head.deadflag != DEAD_NO || head == bot) - continue; - - if(vlen(head.origin - org) < radius) - ++c; - } - - return c; -} - -void havocbot_goalrating_ctf_ourflag(float ratingscale) -{ - entity head; - head = ctf_worldflaglist; - while (head) - { - if (self.team == head.team) - break; - head = head.ctf_worldflagnext; - } - if (head) - navigation_routerating(head, ratingscale, 10000); -} - -void havocbot_goalrating_ctf_ourbase(float ratingscale) -{ - entity head; - head = ctf_worldflaglist; - while (head) - { - if (self.team == head.team) - break; - head = head.ctf_worldflagnext; - } - if not(head) - return; - - navigation_routerating(head.bot_basewaypoint, ratingscale, 10000); -} - -void havocbot_goalrating_ctf_enemyflag(float ratingscale) -{ - entity head; - head = ctf_worldflaglist; - while (head) - { - if (self.team != head.team) - break; - head = head.ctf_worldflagnext; - } - if (head) - navigation_routerating(head, ratingscale, 10000); -} - -void havocbot_goalrating_ctf_enemybase(float ratingscale) -{ - if not(bot_waypoints_for_items) - { - havocbot_goalrating_ctf_enemyflag(ratingscale); - return; - } - - entity head; - - head = havocbot_ctf_find_enemy_flag(self); - - if not(head) - return; - - navigation_routerating(head.bot_basewaypoint, ratingscale, 10000); -} - -void havocbot_goalrating_ctf_ourstolenflag(float ratingscale) -{ - entity mf; - - mf = havocbot_ctf_find_flag(self); - - if(mf.ctf_status == FLAG_BASE) - return; - - if(mf.tag_entity) - navigation_routerating(mf.tag_entity, ratingscale, 10000); -} - -void havocbot_goalrating_ctf_droppedflags(float ratingscale, vector org, float radius) -{ - entity head; - head = ctf_worldflaglist; - while (head) - { - // flag is out in the field - if(head.ctf_status != FLAG_BASE) - if(head.tag_entity==world) // dropped - { - if(radius) - { - if(vlen(org-head.origin) 0) - navigation_routerating(head, t * ratingscale, 500); - } - head = head.chain; - } -} - -void havocbot_role_ctf_setrole(entity bot, float role) -{ - dprint(strcat(bot.netname," switched to ")); - switch(role) - { - case HAVOCBOT_CTF_ROLE_CARRIER: - dprint("carrier"); - bot.havocbot_role = havocbot_role_ctf_carrier; - bot.havocbot_role_timeout = 0; - bot.havocbot_cantfindflag = time + 10; - bot.bot_strategytime = 0; - break; - case HAVOCBOT_CTF_ROLE_DEFENSE: - dprint("defense"); - bot.havocbot_role = havocbot_role_ctf_defense; - bot.havocbot_role_timeout = 0; - break; - case HAVOCBOT_CTF_ROLE_MIDDLE: - dprint("middle"); - bot.havocbot_role = havocbot_role_ctf_middle; - bot.havocbot_role_timeout = 0; - break; - case HAVOCBOT_CTF_ROLE_OFFENSE: - dprint("offense"); - bot.havocbot_role = havocbot_role_ctf_offense; - bot.havocbot_role_timeout = 0; - break; - case HAVOCBOT_CTF_ROLE_RETRIEVER: - dprint("retriever"); - bot.havocbot_previous_role = bot.havocbot_role; - bot.havocbot_role = havocbot_role_ctf_retriever; - bot.havocbot_role_timeout = time + 10; - bot.bot_strategytime = 0; - break; - case HAVOCBOT_CTF_ROLE_ESCORT: - dprint("escort"); - bot.havocbot_previous_role = bot.havocbot_role; - bot.havocbot_role = havocbot_role_ctf_escort; - bot.havocbot_role_timeout = time + 30; - bot.bot_strategytime = 0; - break; - } - dprint("\n"); -} - -void havocbot_role_ctf_carrier() -{ - if(self.deadflag != DEAD_NO) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.flagcarried == world) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.bot_strategytime < time) - { - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - - navigation_goalrating_start(); - havocbot_goalrating_ctf_ourbase(50000); - - if(self.health<100) - havocbot_goalrating_ctf_carrieritems(1000, self.origin, 1000); - - navigation_goalrating_end(); - - if (self.navigation_hasgoals) - self.havocbot_cantfindflag = time + 10; - else if (time > self.havocbot_cantfindflag) - { - // Can't navigate to my own base, suicide! - // TODO: drop it and wander around - Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0'); - return; - } - } -} - -void havocbot_role_ctf_escort() -{ - entity mf, ef; - - if(self.deadflag != DEAD_NO) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.flagcarried) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER); - return; - } - - // If enemy flag is back on the base switch to previous role - ef = havocbot_ctf_find_enemy_flag(self); - if(ef.ctf_status==FLAG_BASE) - { - self.havocbot_role = self.havocbot_previous_role; - self.havocbot_role_timeout = 0; - return; - } - - // If the flag carrier reached the base switch to defense - mf = havocbot_ctf_find_flag(self); - if(mf.ctf_status!=FLAG_BASE) - if(vlen(ef.origin - mf.dropped_origin) < 300) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_DEFENSE); - return; - } - - // Set the role timeout if necessary - if (!self.havocbot_role_timeout) - { - self.havocbot_role_timeout = time + random() * 30 + 60; - } - - // If nothing happened just switch to previous role - if (time > self.havocbot_role_timeout) - { - self.havocbot_role = self.havocbot_previous_role; - self.havocbot_role_timeout = 0; - return; - } - - // Chase the flag carrier - if (self.bot_strategytime < time) - { - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - navigation_goalrating_start(); - havocbot_goalrating_ctf_enemyflag(30000); - havocbot_goalrating_ctf_ourstolenflag(40000); - havocbot_goalrating_items(10000, self.origin, 10000); - navigation_goalrating_end(); - } -} - -void havocbot_role_ctf_offense() -{ - entity mf, ef; - vector pos; - - if(self.deadflag != DEAD_NO) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.flagcarried) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER); - return; - } - - // Check flags - mf = havocbot_ctf_find_flag(self); - ef = havocbot_ctf_find_enemy_flag(self); - - // Own flag stolen - if(mf.ctf_status!=FLAG_BASE) - { - if(mf.tag_entity) - pos = mf.tag_entity.origin; - else - pos = mf.origin; - - // Try to get it if closer than the enemy base - if(vlen(self.origin-ef.dropped_origin)>vlen(self.origin-pos)) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER); - return; - } - } - - // Escort flag carrier - if(ef.ctf_status!=FLAG_BASE) - { - if(ef.tag_entity) - pos = ef.tag_entity.origin; - else - pos = ef.origin; - - if(vlen(pos-mf.dropped_origin)>700) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_ESCORT); - return; - } - } - - // About to fail, switch to middlefield - if(self.health<50) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_MIDDLE); - return; - } - - // Set the role timeout if necessary - if (!self.havocbot_role_timeout) - self.havocbot_role_timeout = time + 120; - - if (time > self.havocbot_role_timeout) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.bot_strategytime < time) - { - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - navigation_goalrating_start(); - havocbot_goalrating_ctf_ourstolenflag(50000); - havocbot_goalrating_ctf_enemybase(20000); - havocbot_goalrating_items(5000, self.origin, 1000); - havocbot_goalrating_items(1000, self.origin, 10000); - navigation_goalrating_end(); - } -} - -// Retriever (temporary role): -void havocbot_role_ctf_retriever() -{ - entity mf; - - if(self.deadflag != DEAD_NO) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.flagcarried) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER); - return; - } - - // If flag is back on the base switch to previous role - mf = havocbot_ctf_find_flag(self); - if(mf.ctf_status==FLAG_BASE) - { - havocbot_ctf_reset_role(self); - return; - } - - if (!self.havocbot_role_timeout) - self.havocbot_role_timeout = time + 20; - - if (time > self.havocbot_role_timeout) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.bot_strategytime < time) - { - float radius; - radius = 10000; - - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - navigation_goalrating_start(); - havocbot_goalrating_ctf_ourstolenflag(50000); - havocbot_goalrating_ctf_droppedflags(40000, self.origin, radius); - havocbot_goalrating_ctf_enemybase(30000); - havocbot_goalrating_items(500, self.origin, radius); - navigation_goalrating_end(); - } -} - -void havocbot_role_ctf_middle() -{ - entity mf; - - if(self.deadflag != DEAD_NO) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.flagcarried) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER); - return; - } - - mf = havocbot_ctf_find_flag(self); - if(mf.ctf_status!=FLAG_BASE) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER); - return; - } - - if (!self.havocbot_role_timeout) - self.havocbot_role_timeout = time + 10; - - if (time > self.havocbot_role_timeout) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.bot_strategytime < time) - { - vector org; - - org = havocbot_ctf_middlepoint; - org_z = self.origin_z; - - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - navigation_goalrating_start(); - havocbot_goalrating_ctf_ourstolenflag(50000); - havocbot_goalrating_ctf_droppedflags(30000, self.origin, 10000); - havocbot_goalrating_enemyplayers(10000, org, havocbot_ctf_middlepoint_radius * 0.5); - havocbot_goalrating_items(5000, org, havocbot_ctf_middlepoint_radius * 0.5); - havocbot_goalrating_items(2500, self.origin, 10000); - havocbot_goalrating_ctf_enemybase(2500); - navigation_goalrating_end(); - } -} - -void havocbot_role_ctf_defense() -{ - entity mf; - - if(self.deadflag != DEAD_NO) - { - havocbot_ctf_reset_role(self); - return; - } - - if (self.flagcarried) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER); - return; - } - - // If own flag was captured - mf = havocbot_ctf_find_flag(self); - if(mf.ctf_status!=FLAG_BASE) - { - havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER); - return; - } - - if (!self.havocbot_role_timeout) - self.havocbot_role_timeout = time + 30; - - if (time > self.havocbot_role_timeout) - { - havocbot_ctf_reset_role(self); - return; - } - if (self.bot_strategytime < time) - { - float radius; - vector org; - - org = mf.dropped_origin; - radius = havocbot_ctf_middlepoint_radius; - - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - navigation_goalrating_start(); - - // if enemies are closer to our base, go there - entity head, closestplayer = world; - float distance, bestdistance = 10000; - FOR_EACH_PLAYER(head) - { - if(head.deadflag!=DEAD_NO) - continue; - - distance = vlen(org - head.origin); - if(distance1000) - if(checkpvs(self.origin,closestplayer)||random()<0.5) - havocbot_goalrating_ctf_ourbase(30000); - - havocbot_goalrating_ctf_ourstolenflag(20000); - havocbot_goalrating_ctf_droppedflags(20000, org, radius); - havocbot_goalrating_enemyplayers(15000, org, radius); - havocbot_goalrating_items(10000, org, radius); - havocbot_goalrating_items(5000, self.origin, 10000); - navigation_goalrating_end(); - } -} - -void havocbot_calculate_middlepoint() -{ - entity f; - vector s = '0 0 0'; - vector fo = '0 0 0'; - float n = 0; - - f = ctf_worldflaglist; - while (f) - { - fo = f.origin; - s = s + fo; - f = f.ctf_worldflagnext; - } - if(!n) - return; - havocbot_ctf_middlepoint = s * (1.0 / n); - havocbot_ctf_middlepoint_radius = vlen(fo - havocbot_ctf_middlepoint); -} - -void havocbot_ctf_reset_role(entity bot) -{ - float cdefense, cmiddle, coffense; - entity mf, ef, head; - float c; - - if(bot.deadflag != DEAD_NO) - return; - - if(vlen(havocbot_ctf_middlepoint)==0) - havocbot_calculate_middlepoint(); - - // Check ctf flags - if (bot.flagcarried) - { - havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_CARRIER); - return; - } - - mf = havocbot_ctf_find_flag(bot); - ef = havocbot_ctf_find_enemy_flag(bot); - - // Retrieve stolen flag - if(mf.ctf_status!=FLAG_BASE) - { - havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_RETRIEVER); - return; - } - - // If enemy flag is taken go to the middle to intercept pursuers - if(ef.ctf_status!=FLAG_BASE) - { - havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_MIDDLE); - return; - } - - // if there is only me on the team switch to offense - c = 0; - FOR_EACH_PLAYER(head) - if(head.team==bot.team) - ++c; - - if(c==1) - { - havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_OFFENSE); - return; - } - - // Evaluate best position to take - // Count mates on middle position - cmiddle = havocbot_ctf_teamcount(bot, havocbot_ctf_middlepoint, havocbot_ctf_middlepoint_radius * 0.5); - - // Count mates on defense position - cdefense = havocbot_ctf_teamcount(bot, mf.dropped_origin, havocbot_ctf_middlepoint_radius * 0.5); - - // Count mates on offense position - coffense = havocbot_ctf_teamcount(bot, ef.dropped_origin, havocbot_ctf_middlepoint_radius); - - if(cdefense<=coffense) - havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_DEFENSE); - else if(coffense<=cmiddle) - havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_OFFENSE); - else - havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_MIDDLE); -} - -void havocbot_chooserole_ctf() -{ - havocbot_ctf_reset_role(self); -} diff --git a/qcsrc/server/attic/bot/havocbot/role_freezetag.qc b/qcsrc/server/attic/bot/havocbot/role_freezetag.qc deleted file mode 100644 index 4e5669eb2..000000000 --- a/qcsrc/server/attic/bot/havocbot/role_freezetag.qc +++ /dev/null @@ -1,109 +0,0 @@ -void() havocbot_role_ft_freeing; -void() havocbot_role_ft_offense; - -void havocbot_goalrating_freeplayers(float ratingscale, vector org, float sradius) -{ - entity head; - float distance; - - FOR_EACH_PLAYER(head) - { - if ((head != self) && (head.team == self.team)) - { - if (head.freezetag_frozen) - { - distance = vlen(head.origin - org); - if (distance > sradius) - continue; - navigation_routerating(head, ratingscale, 2000); - } - else - { - // If teamate is not frozen still seek them out as fight better - // in a group. - navigation_routerating(head, ratingscale/3, 2000); - } - } - } -} - -void havocbot_role_ft_offense() -{ - entity head; - float unfrozen; - - if(self.deadflag != DEAD_NO) - return; - - if (!self.havocbot_role_timeout) - self.havocbot_role_timeout = time + random() * 10 + 20; - - // Count how many players on team are unfrozen. - unfrozen = 0; - FOR_EACH_PLAYER(head) - { - if ((head.team == self.team) && (!head.freezetag_frozen)) - unfrozen++; - } - - // If only one left on team or if role has timed out then start trying to free players. - if (((unfrozen == 0) && (!self.freezetag_frozen)) || (time > self.havocbot_role_timeout)) - { - dprint("changing role to freeing\n"); - self.havocbot_role = havocbot_role_ft_freeing; - self.havocbot_role_timeout = 0; - return; - } - - if (time > self.bot_strategytime) - { - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - - navigation_goalrating_start(); - havocbot_goalrating_items(10000, self.origin, 10000); - havocbot_goalrating_enemyplayers(20000, self.origin, 10000); - havocbot_goalrating_freeplayers(9000, self.origin, 10000); - //havocbot_goalrating_waypoints(1, self.origin, 1000); - navigation_goalrating_end(); - } -} - -void havocbot_role_ft_freeing() -{ - if(self.deadflag != DEAD_NO) - return; - - if (!self.havocbot_role_timeout) - self.havocbot_role_timeout = time + random() * 10 + 20; - - if (time > self.havocbot_role_timeout) - { - dprint("changing role to offense\n"); - self.havocbot_role = havocbot_role_ft_offense; - self.havocbot_role_timeout = 0; - return; - } - - if (time > self.bot_strategytime) - { - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - - navigation_goalrating_start(); - havocbot_goalrating_items(8000, self.origin, 10000); - havocbot_goalrating_enemyplayers(10000, self.origin, 10000); - havocbot_goalrating_freeplayers(20000, self.origin, 10000); - //havocbot_goalrating_waypoints(1, self.origin, 1000); - navigation_goalrating_end(); - } -} - -void havocbot_chooserole_ft() -{ - if(self.deadflag != DEAD_NO) - return; - - if (random() < 0.5) - self.havocbot_role = havocbot_role_ft_freeing; - else - self.havocbot_role = havocbot_role_ft_offense; -} diff --git a/qcsrc/server/attic/bot/havocbot/role_keepaway.qc b/qcsrc/server/attic/bot/havocbot/role_keepaway.qc deleted file mode 100644 index ede6208a1..000000000 --- a/qcsrc/server/attic/bot/havocbot/role_keepaway.qc +++ /dev/null @@ -1,82 +0,0 @@ -void() havocbot_role_ka_carrier; -void() havocbot_role_ka_collector; -void() havocbot_chooserole_ka; - -entity ka_ball; - -// Keepaway -// If you don't have the ball, get it; if you do, kill people. - -void havocbot_goalrating_ball(float ratingscale, vector org) -{ - float t; - entity ball_owner; - ball_owner = ka_ball.owner; - - if (ball_owner == self) - return; - - // If ball is carried by player then hunt them down. - if (ball_owner) - { - t = (self.health + self.armorvalue) / (ball_owner.health + ball_owner.armorvalue); - navigation_routerating(ball_owner, t * ratingscale, 2000); - } - - // Ball has been dropped so collect. - navigation_routerating(ka_ball, ratingscale, 2000); -} - -void havocbot_role_ka_carrier() -{ - if (self.deadflag != DEAD_NO) - return; - - if (time > self.bot_strategytime) - { - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - - navigation_goalrating_start(); - havocbot_goalrating_items(10000, self.origin, 10000); - havocbot_goalrating_enemyplayers(20000, self.origin, 10000); - //havocbot_goalrating_waypoints(1, self.origin, 1000); - navigation_goalrating_end(); - } - - if (!self.ballcarried) - { - self.havocbot_role = havocbot_role_ka_collector; - self.bot_strategytime = 0; - } -} - -void havocbot_role_ka_collector() -{ - if (self.deadflag != DEAD_NO) - return; - - if (time > self.bot_strategytime) - { - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - - navigation_goalrating_start(); - havocbot_goalrating_items(10000, self.origin, 10000); - havocbot_goalrating_enemyplayers(1000, self.origin, 10000); - havocbot_goalrating_ball(20000, self.origin); - navigation_goalrating_end(); - } - - if (self.ballcarried) - { - self.havocbot_role = havocbot_role_ka_carrier; - self.bot_strategytime = 0; - } -} - -void havocbot_chooserole_ka() -{ - if (self.ballcarried) - self.havocbot_role = havocbot_role_ka_carrier; - else - self.havocbot_role = havocbot_role_ka_collector; -} diff --git a/qcsrc/server/attic/ctf.qc b/qcsrc/server/attic/ctf.qc deleted file mode 100644 index b86e84369..000000000 --- a/qcsrc/server/attic/ctf.qc +++ /dev/null @@ -1,1226 +0,0 @@ -#define FLAG_MIN (PL_MIN + '0 0 -13') -#define FLAG_MAX (PL_MAX + '0 0 -13') - -.entity basewaypoint; -.entity sprite; -entity ctf_worldflaglist; // CTF flags in the map -.entity ctf_worldflagnext; -.float dropperid; -.float ctf_droptime; - -.float next_take_time; // the next time a player can pick up a flag (time + blah) - /// I used this, in part, to fix the looping score bug. - avirox -//float FLAGSCORE_PICKUP = 1; -//float FLAGSCORE_RETURN = 5; // returned by owner team -//float FLAGSCORE_RETURNROGUE = 10; // returned by rogue team -//float FLAGSCORE_CAPTURE = 5; - -#define FLAG_CARRY_POS '-15 0 7' - -.float ctf_captureshielded; // set to 1 if the player is too bad to be allowed to capture - -float captureshield_min_negscore; // punish at -20 points -float captureshield_max_ratio; // punish at most 30% of each team -float captureshield_force; // push force of the shield - -float ctf_captureshield_shielded(entity p) -{ - float s, se; - entity e; - float players_worseeq, players_total; - - if(captureshield_max_ratio <= 0) - return FALSE; - - s = PlayerScore_Add(p, SP_SCORE, 0); - if(s >= -captureshield_min_negscore) - return FALSE; - - players_total = players_worseeq = 0; - FOR_EACH_PLAYER(e) - { - if(e.team != p.team) - continue; - se = PlayerScore_Add(e, SP_SCORE, 0); - if(se <= s) - ++players_worseeq; - ++players_total; - } - - // player is in the worse half, if >= half the players are better than him, or consequently, if < half of the players are worse - // use this rule here - - if(players_worseeq >= players_total * captureshield_max_ratio) - return FALSE; - - return TRUE; -} - -void ctf_captureshield_update(entity p, float dir) -{ - float should; - if(dir == p.ctf_captureshielded) // 0: shield only, 1: unshield only - { - should = ctf_captureshield_shielded(p); - if(should != dir) - { - if(should) - { - Send_CSQC_Centerprint_Generic(other, CPID_CTF_CAPTURESHIELD, "^3You are ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Get some defensive scores before trying again.", 5, 0); - // TODO csqc notifier for this - } - else - { - Send_CSQC_Centerprint_Generic(p, CPID_CTF_CAPTURESHIELD, "^3You are now free.\n\n^3Feel free to ^1try to capture^3 the flag again\n^3if you think you will succeed.", 5, 0); - // TODO csqc notifier for this - } - p.ctf_captureshielded = should; - } - } -} - -float ctf_captureshield_customize() -{ - if not(other.ctf_captureshielded) - return FALSE; - if(self.team == other.team) - return FALSE; - return TRUE; -} - -.float ctf_captureshield_touch_msgtime; -void ctf_captureshield_touch() -{ - if not(other.ctf_captureshielded) - return; - if(self.team == other.team) - return; - vector mymid; - vector othermid; - mymid = (self.absmin + self.absmax) * 0.5; - othermid = (other.absmin + other.absmax) * 0.5; - Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * captureshield_force); - if (time - other.ctf_captureshield_touch_msgtime > 2) - Send_CSQC_Centerprint_Generic(other, CPID_CTF_CAPTURESHIELD, "^3You are ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Get some defensive scores before trying again.", 5, 0); - other.ctf_captureshield_touch_msgtime = time; -} - -void ctf_flag_spawnstuff() -{ - entity e; - e = spawn(); - e.enemy = self; - e.team = self.team; - e.touch = ctf_captureshield_touch; - e.customizeentityforclient = ctf_captureshield_customize; - e.classname = "ctf_captureshield"; - e.effects = EF_ADDITIVE; - e.movetype = MOVETYPE_NOCLIP; - e.solid = SOLID_TRIGGER; - e.avelocity = '7 0 11'; - setorigin(e, self.origin); - setmodel(e, "models/ctf/shield.md3"); - e.scale = 0.5; - setsize(e, e.scale * e.mins, e.scale * e.maxs); - - waypoint_spawnforitem_force(self, self.origin); - self.nearestwaypointtimeout = 0; // activate waypointing again - self.basewaypoint = self.nearestwaypoint; - - if(self.team == NUM_TEAM_1) - WaypointSprite_SpawnFixed("redbase", self.origin + '0 0 61', self, sprite, RADARICON_FLAG, colormapPaletteColor(NUM_TEAM_1 - 1, FALSE)); - else - WaypointSprite_SpawnFixed("bluebase", self.origin + '0 0 61', self, sprite, RADARICON_FLAG, colormapPaletteColor(NUM_TEAM_2 - 1, FALSE)); -} - -float ctf_score_value(string parameter) -{ - return cvar(strcat("g_ctf_personal", parameter)); -} - -void FakeTimeLimit(entity e, float t) -{ - msg_entity = e; - WriteByte(MSG_ONE, 3); // svc_updatestat - WriteByte(MSG_ONE, 236); // STAT_TIMELIMIT - if(t < 0) - WriteCoord(MSG_ONE, autocvar_timelimit); - else - WriteCoord(MSG_ONE, (t + 1) / 60); -} - -float flagcaptimerecord; -.float flagpickuptime; -//.float iscommander; -//.float ctf_state; - -void() FlagThink; -void() FlagTouch; - -void place_flag() -{ - if(self.classname != "item_flag_team") - { - backtrace("PlaceFlag a non-flag"); - return; - } - - setattachment(self, world, ""); - self.mdl = self.model; - self.flags = FL_ITEM | FL_NOTARGET; - self.solid = SOLID_TRIGGER; - self.movetype = MOVETYPE_NONE; - self.velocity = '0 0 0'; - self.origin_z = self.origin_z + 6; - self.think = FlagThink; - self.touch = FlagTouch; - self.nextthink = time + 0.1; - self.cnt = FLAG_BASE; - self.mangle = self.angles; - self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; - //self.effects = self.effects | EF_DIMLIGHT; - if(self.noalign) - { - self.dropped_origin = self.origin; - } - else - { - droptofloor(); - self.movetype = MOVETYPE_TOSS; - } - - InitializeEntity(self, ctf_flag_spawnstuff, INITPRIO_SETLOCATION); -} - -void LogCTF(string mode, float flagteam, entity actor) -{ - string s; - if(!autocvar_sv_eventlog) - return; - s = strcat(":ctf:", mode); - s = strcat(s, ":", ftos(flagteam)); - if(actor != world) - s = strcat(s, ":", ftos(actor.playerid)); - GameLogEcho(s); -} - -void RegenFlag(entity e) -{ - if(e.classname != "item_flag_team") - { - backtrace("RegenFlag a non-flag"); - return; - } - - if(e.waypointsprite_attachedforcarrier) - WaypointSprite_DetachCarrier(e); - - setattachment(e, world, ""); - e.damageforcescale = 0; - e.takedamage = DAMAGE_NO; - e.movetype = MOVETYPE_NONE; - if(!e.noalign) - e.movetype = MOVETYPE_TOSS; - e.velocity = '0 0 0'; - e.solid = SOLID_TRIGGER; - // TODO: play a sound here - setorigin(e, e.dropped_origin); - e.angles = e.mangle; - e.cnt = FLAG_BASE; - e.owner = world; - e.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND and any other junk -} - -void ReturnFlag(entity e) -{ - if(e.classname != "item_flag_team") - { - backtrace("ReturnFlag a non-flag"); - return; - } - - if (e.owner) - if (e.owner.flagcarried == e) - { - WaypointSprite_DetachCarrier(e.owner); - e.owner.flagcarried = world; - - if(e.speedrunning) - FakeTimeLimit(e.owner, -1); - } - e.owner = world; - RegenFlag(e); -} - -void DropFlag(entity e, entity penalty_receiver, entity attacker) -{ - entity p; - - if(e.classname != "item_flag_team") - { - backtrace("DropFlag a non-flag"); - return; - } - - if(e.speedrunning) - { - ReturnFlag(e); - return; - } - - if (!e.owner) - { - dprint("FLAG: drop - no owner?!?!\n"); - return; - } - p = e.owner; - if (p.flagcarried != e) - { - dprint("FLAG: drop - owner is not carrying this flag??\n"); - return; - } - //bprint(p.netname, "^7 lost the ", e.netname, "\n"); - Send_KillNotification (p.netname, e.netname, "", INFO_LOSTFLAG, MSG_INFO); - - if(penalty_receiver) - UpdateFrags(penalty_receiver, -ctf_score_value("penalty_suicidedrop")); - else - UpdateFrags(p, -ctf_score_value("penalty_drop")); - PlayerScore_Add(p, SP_CTF_DROPS, +1); - ctf_captureshield_update(p, 0); // shield only - e.playerid = attacker.playerid; - e.ctf_droptime = time; - WaypointSprite_Spawn("flagdropped", 0, 0, e, '0 0 1' * 61, world, NUM_TEAM_1 + NUM_TEAM_2 - e.team, e, waypointsprite_attachedforcarrier, FALSE, RADARICON_FLAG, '0 1 1'); - WaypointSprite_Ping(e.waypointsprite_attachedforcarrier); - - if(p.waypointsprite_attachedforcarrier) - { - WaypointSprite_DetachCarrier(p); - } - else - { - bprint("\{1}^1Flag carrier had no flag sprite?!?\n"); - backtrace("Flag carrier had no flag sprite?!?"); - } - LogCTF("dropped", p.team, p); - sound (p, CH_TRIGGER, self.noise4, VOL_BASE, ATTN_NONE); - - setattachment(e, world, ""); - e.damageforcescale = autocvar_g_balance_ctf_damageforcescale; - e.takedamage = DAMAGE_YES; - - if (p.flagcarried == e) - p.flagcarried = world; - e.owner = world; - - e.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND and any other junk - e.solid = SOLID_TRIGGER; - e.movetype = MOVETYPE_TOSS; - // setsize(e, '-16 -16 0', '16 16 74'); - setorigin(e, p.origin - '0 0 24' + '0 0 37'); - e.cnt = FLAG_DROPPED; - e.velocity = '0 0 300'; - e.pain_finished = time + autocvar_g_ctf_flag_returntime;//30; - - trace_startsolid = FALSE; - tracebox(e.origin, e.mins, e.maxs, e.origin, TRUE, e); - if(trace_startsolid) - dprint("FLAG FALLTHROUGH will happen SOON\n"); -} - -void FlagThink() -{ - entity e; - - self.nextthink = time + 0.1; - - // sorry, we have to reset the flag size if it got squished by something - if(self.mins != FLAG_MIN || self.maxs != FLAG_MAX) - { - // if we can grow back, grow back - tracebox(self.origin, FLAG_MIN, FLAG_MAX, self.origin, MOVE_NOMONSTERS, self); - if(!trace_startsolid) - setsize(self, FLAG_MIN, FLAG_MAX); - } - - if(self == ctf_worldflaglist) // only for the first flag - { - FOR_EACH_CLIENT(e) - ctf_captureshield_update(e, 1); // release shield only - } - - if(self.speedrunning) - if(self.cnt == FLAG_CARRY) - { - if(self.owner) - if(flagcaptimerecord) - if(time >= self.flagpickuptime + flagcaptimerecord) - { - bprint("The ", self.netname, " became impatient after ", ftos_decimals(flagcaptimerecord, 2), " seconds and returned itself\n"); - - sound (self, CH_TRIGGER, self.noise3, VOL_BASE, ATTN_NONE); - self.owner.impulse = 141; // returning! - - e = self; - self = self.owner; - ReturnFlag(e); - ImpulseCommands(); - self = e; - return; - } - } - - if (self.cnt == FLAG_BASE) - return; - - if (self.cnt == FLAG_DROPPED) - { - // flag fallthrough? FIXME remove this if bug is really fixed now - if(self.origin_z < -131072) - { - dprint("FLAG FALLTHROUGH just happened\n"); - self.pain_finished = 0; - } - setattachment(self, world, ""); - if (time > self.pain_finished) - { - bprint("The ", self.netname, " has returned to base\n"); - sound (self, CH_TRIGGER, self.noise3, VOL_BASE, ATTN_NONE); - LogCTF("returned", self.team, world); - ReturnFlag(self); - } - return; - } - - e = self.owner; - if (e.classname != "player" || (e.deadflag) || (e.flagcarried != self)) - { - dprint("CANNOT HAPPEN - player dead and STILL had a flag!\n"); - DropFlag(self, world, world); - return; - } -} - -float ctf_usekey() -{ - if(self.flagcarried) - { - DropFlag(self.flagcarried, self, world); - return TRUE; - } - return FALSE; -} - -void flag_cap_ring_spawn(vector org) -{ - shockwave_spawn("models/ctf/shockwavetransring.md3", org - '0 0 15', -0.8, 0, 1); -} - -// TODO add FlagDamage, replace weird hurttrigger handling inside trigger_hurt code by it -void FlagTouch() -{ - if(gameover) return; - - float t; - entity player; - string s, s0, h0, h1; - - if (self.cnt == FLAG_CARRY) - return; - - if (self.cnt == FLAG_DROPPED) - { - if(ITEM_TOUCH_NEEDKILL()) - { - self.pain_finished = 0; // return immediately - return; - } - } - - if (other.classname != "player") - return; - if (other.health < 1) // ignore dead players - return; - - if (self.cnt == FLAG_BASE) - if (other.team == self.team) - if (other.flagcarried) // he's got a flag - if (other.flagcarried.team != self.team) // capture - { - if (other.flagcarried == world) - { - return; - } - if(autocvar_g_ctf_captimerecord_always || player_count - currentbots <= 1) // at most one human - { - t = time - other.flagcarried.flagpickuptime; - s = ftos_decimals(t, 2); - s0 = ftos_decimals(flagcaptimerecord, 2); - h0 = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname")); - h1 = other.netname; - if(h0 == h1) - h0 = "their"; - else - h0 = strcat(h0, "^7's"); // h0: display text for previous netname - if (flagcaptimerecord == 0) - { - s = strcat(" in ", s, " seconds"); - flagcaptimerecord = t; - db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(t)); - db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), h1); - write_recordmarker(other, time - t, t); - } - else if (t < flagcaptimerecord) - { - s = strcat(" in ", s, " seconds, breaking ", h0, " previous record of ", s0, " seconds"); - flagcaptimerecord = t; - db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(t)); - db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), h1); - write_recordmarker(other, time - t, t); - } - else - { - s = strcat(" in ", s, " seconds, failing to break ", h0, " record of ", s0, " seconds"); - } - } - else - s = ""; - - Send_KillNotification (other.netname, other.flagcarried.netname, s, INFO_CAPTUREFLAG, MSG_INFO); - - PlayerTeamScore_Add(other, SP_CTF_CAPS, ST_CTF_CAPS, 1); - LogCTF("capture", other.flagcarried.team, other); - // give credit to the individual player - UpdateFrags(other, ctf_score_value("score_capture")); - - if (autocvar_g_ctf_flag_capture_effects) { - if (other.team == NUM_TEAM_1) { // red team scores effect - pointparticles(particleeffectnum("red_ground_quake"), self.origin, '0 0 0', 1); - flag_cap_ring_spawn(self.origin); - } - if (other.team == NUM_TEAM_2) { // blue team scores effect - pointparticles(particleeffectnum("blue_ground_quake"), self.origin, '0 0 0', 1); - flag_cap_ring_spawn(self.origin); - } - } - - sound (other, CH_TRIGGER, self.noise2, VOL_BASE, ATTN_NONE); - WaypointSprite_DetachCarrier(other); - if(self.speedrunning) - FakeTimeLimit(other, -1); - RegenFlag (other.flagcarried); - other.flagcarried = world; - other.next_take_time = time + 1; - } - if (self.cnt == FLAG_BASE) - if (other.team == NUM_TEAM_1 || other.team == NUM_TEAM_2) // only red and blue team can steal flags - if (other.team != self.team) - if (!other.flagcarried) - if (!other.ctf_captureshielded) - { - if(MUTATOR_CALLHOOK(ItemTouch)) - return; - - if (other.next_take_time > time) - return; - - if (autocvar_g_ctf_flag_pickup_effects) // pickup effect - pointparticles(particleeffectnum("smoke_ring"), 0.5 * (self.absmin + self.absmax), '0 0 0', 1); - - // pick up - self.flagpickuptime = time; // used for timing runs - self.speedrunning = other.speedrunning; // if speedrunning, flag will self-return and teleport the owner back after the record - if(other.speedrunning) - if(flagcaptimerecord) - FakeTimeLimit(other, time + flagcaptimerecord); - self.solid = SOLID_NOT; - setorigin(self, self.origin); // relink - self.owner = other; - other.flagcarried = self; - self.cnt = FLAG_CARRY; - self.angles = '0 0 0'; - //bprint(other.netname, "^7 got the ", self.netname, "\n"); - Send_KillNotification (other.netname, self.netname, "", INFO_GOTFLAG, MSG_INFO); - UpdateFrags(other, ctf_score_value("score_pickup_base")); - self.dropperid = other.playerid; - PlayerScore_Add(other, SP_CTF_PICKUPS, 1); - LogCTF("steal", self.team, other); - sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NONE); - - FOR_EACH_PLAYER(player) - if(player.team == self.team) - centerprint(player, "The enemy got your flag! Retrieve it!"); - - self.movetype = MOVETYPE_NONE; - setorigin(self, FLAG_CARRY_POS); - setattachment(self, other, ""); - WaypointSprite_AttachCarrier("flagcarrier", other, RADARICON_FLAGCARRIER, '1 1 0'); - WaypointSprite_Ping(self.sprite); - - return; - } - - if (self.cnt == FLAG_DROPPED) - { - self.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND and any other junk - if (other.team == self.team || (other.team != NUM_TEAM_1 && other.team != NUM_TEAM_2)) - { - // return flag - Send_KillNotification (other.netname, self.netname, "", INFO_RETURNFLAG, MSG_INFO); - //bprint(other.netname, "^7 returned the ", self.netname, "\n"); - - // punish the player who last had it - FOR_EACH_PLAYER(player) - if(player.playerid == self.dropperid) - { - PlayerScore_Add(player, SP_SCORE, -ctf_score_value("penalty_returned")); - ctf_captureshield_update(player, 0); // shield only - } - - // punish the team who was last carrying it - if(self.team == NUM_TEAM_1) - TeamScore_AddToTeam(NUM_TEAM_2, ST_SCORE, -ctf_score_value("penalty_returned")); - else - TeamScore_AddToTeam(NUM_TEAM_1, ST_SCORE, -ctf_score_value("penalty_returned")); - - // reward the player who returned it - if(other.playerid == self.playerid) // is this the guy who killed the FC last? - { - if (other.team == NUM_TEAM_1 || other.team == NUM_TEAM_2) - UpdateFrags(other, ctf_score_value("score_return_by_killer")); - else - UpdateFrags(other, ctf_score_value("score_return_rogue_by_killer")); - } - else - { - if (other.team == NUM_TEAM_1 || other.team == NUM_TEAM_2) - UpdateFrags(other, ctf_score_value("score_return")); - else - UpdateFrags(other, ctf_score_value("score_return_rogue")); - } - PlayerScore_Add(other, SP_CTF_RETURNS, 1); - LogCTF("return", self.team, other); - sound (other, CH_TRIGGER, self.noise1, VOL_BASE, ATTN_NONE); - ReturnFlag(self); - } - else if (!other.flagcarried && (other.playerid != self.dropperid || time > self.ctf_droptime + autocvar_g_balance_ctf_delay_collect)) - { - if(self.waypointsprite_attachedforcarrier) - WaypointSprite_DetachCarrier(self); - - if (autocvar_g_ctf_flag_pickup_effects) // field pickup effect - pointparticles(particleeffectnum("smoke_ring"), 0.5 * (self.absmin + self.absmax), '0 0 0', 1); - - // pick up - self.solid = SOLID_NOT; - setorigin(self, self.origin); // relink - self.owner = other; - other.flagcarried = self; - self.cnt = FLAG_CARRY; - Send_KillNotification (other.netname, self.netname, "", INFO_PICKUPFLAG, MSG_INFO); - //bprint(other.netname, "^7 picked up the ", self.netname, "\n"); - - float f; - f = bound(0, (self.pain_finished - time) / autocvar_g_ctf_flag_returntime, 1); - //print("factor is ", ftos(f), "\n"); - f = ctf_score_value("score_pickup_dropped_late") * (1-f) - + ctf_score_value("score_pickup_dropped_early") * f; - f = floor(f + 0.5); - self.dropperid = other.playerid; - //print("score is ", ftos(f), "\n"); - - UpdateFrags(other, f); - PlayerScore_Add(other, SP_CTF_PICKUPS, 1); - LogCTF("pickup", self.team, other); - sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NONE); - - FOR_EACH_PLAYER(player) - if(player.team == self.team) - centerprint(player, "The enemy got your flag! Retrieve it!"); - - self.movetype = MOVETYPE_NONE; // flag must have MOVETYPE_NONE here, otherwise it will drop through the floor... - setorigin(self, FLAG_CARRY_POS); - setattachment(self, other, ""); - self.damageforcescale = 0; - self.takedamage = DAMAGE_NO; - WaypointSprite_AttachCarrier("flagcarrier", other, RADARICON_FLAGCARRIER, '1 1 0'); - } - } -} - -/*QUAKED spawnfunc_info_player_team1 (1 0 0) (-16 -16 -24) (16 16 24) -CTF Starting point for a player -in team one (Red). - -Keys: -"angle" - viewing angle when spawning -*/ -void spawnfunc_info_player_team1() -{ - if(g_assault) - { - remove(self); - return; - } - self.team = NUM_TEAM_1; // red - spawnfunc_info_player_deathmatch(); -} -//self.team = 4;self.classname = "info_player_start";spawnfunc_info_player_start();} - -/*QUAKED spawnfunc_info_player_team2 (1 0 0) (-16 -16 -24) (16 16 24) -CTF Starting point for a player in -team two (Blue). - -Keys: -"angle" - viewing angle when spawning -*/ -void spawnfunc_info_player_team2() -{ - if(g_assault) - { - remove(self); - return; - } - self.team = NUM_TEAM_2; // blue - spawnfunc_info_player_deathmatch(); -} -//self.team = 13;self.classname = "info_player_start";spawnfunc_info_player_start();} - -/*QUAKED spawnfunc_info_player_team3 (1 0 0) (-16 -16 -24) (16 16 24) -CTF Starting point for a player in -team three (Yellow). - -Keys: -"angle" - viewing angle when spawning -*/ -void spawnfunc_info_player_team3() -{ - if(g_assault) - { - remove(self); - return; - } - self.team = NUM_TEAM_3; // yellow - spawnfunc_info_player_deathmatch(); -} - - -/*QUAKED spawnfunc_info_player_team4 (1 0 0) (-16 -16 -24) (16 16 24) -CTF Starting point for a player in -team four (Magenta). - -Keys: -"angle" - viewing angle when spawning -*/ -void spawnfunc_info_player_team4() -{ - if(g_assault) - { - remove(self); - return; - } - self.team = NUM_TEAM_4; // purple - spawnfunc_info_player_deathmatch(); -} - -void item_flag_reset() -{ - DropFlag(self, world, world); - if(self.waypointsprite_attachedforcarrier) - WaypointSprite_DetachCarrier(self); - ReturnFlag(self); -} - -void item_flag_postspawn() -{ // Check CTF Item Flag Post Spawn - - // Flag Glow Trail Support - if(autocvar_g_ctf_flag_glowtrails) - { // Provide Flag Glow Trail - if(self.team == NUM_TEAM_1) - // Red - self.glow_color = 251; - else - if(self.team == NUM_TEAM_2) - // Blue - self.glow_color = 210; - - self.glow_size = 25; - self.glow_trail = 1; - } -} - -/*QUAKED spawnfunc_item_flag_team1 (0 0.5 0.8) (-48 -48 -37) (48 48 37) -CTF flag for team one (Red). -Multiple are allowed. - -Keys: -"angle" - Angle the flag will point -(minus 90 degrees) -"model" - model to use, note this needs red and blue as skins 0 and 1 - (default models/ctf/flag.md3) -"noise" - sound played when flag is picked up - (default ctf/take.wav) -"noise1" - sound played when flag is returned by a teammate - (default ctf/return.wav) -"noise2" - sound played when flag is captured - (default ctf/redcapture.wav) -"noise3" - sound played when flag is lost in the field and respawns itself - (default ctf/respawn.wav) -*/ - -void spawnfunc_item_flag_team2(); -void spawnfunc_item_flag_team1() -{ - if (!g_ctf) - { - remove(self); - return; - } - - if (g_ctf_reverse) - { - float old_g_ctf_reverse = g_ctf_reverse; - g_ctf_reverse = 0; // avoid an endless loop - spawnfunc_item_flag_team2(); - g_ctf_reverse = old_g_ctf_reverse; - return; - } - - // link flag into ctf_worldflaglist - self.ctf_worldflagnext = ctf_worldflaglist; - ctf_worldflaglist = self; - - self.classname = "item_flag_team"; - self.team = NUM_TEAM_1; // color 4 team (red) - self.items = IT_KEY2; // gold key (redish enough) - self.netname = "^1RED^7 flag"; - self.target = "###item###"; - self.skin = autocvar_g_ctf_flag_red_skin; - if(self.spawnflags & 1) - self.noalign = 1; - if (!self.model) - self.model = autocvar_g_ctf_flag_red_model; - if (!self.noise) - self.noise = "ctf/red_taken.wav"; - if (!self.noise1) - self.noise1 = "ctf/red_returned.wav"; - if (!self.noise2) - self.noise2 = "ctf/red_capture.wav"; // blue team scores by capturing the red flag - if (!self.noise3) - self.noise3 = "ctf/flag_respawn.wav"; - if (!self.noise4) - self.noise4 = "ctf/red_dropped.wav"; - precache_model (self.model); - setmodel (self, self.model); // precision set below - precache_sound (self.noise); - precache_sound (self.noise1); - precache_sound (self.noise2); - precache_sound (self.noise3); - precache_sound (self.noise4); - //setsize(self, '-16 -16 -37', '16 16 37'); - setsize(self, FLAG_MIN, FLAG_MAX); - setorigin(self, self.origin + '0 0 37'); - self.nextthink = time + 0.2; // start after doors etc - self.think = place_flag; - - if(!self.scale) - self.scale = 0.6; - //if(!self.glow_size) - // self.glow_size = 50; - - self.effects = self.effects | EF_LOWPRECISION; - if(autocvar_g_ctf_fullbrightflags) - self.effects |= EF_FULLBRIGHT; - if(autocvar_g_ctf_dynamiclights) - self.effects |= EF_RED; - - // From Spidflisk - item_flag_postspawn(); - - precache_model("models/ctf/shield.md3"); - precache_model("models/ctf/shockwavetransring.md3"); - - self.reset = item_flag_reset; -} - -/*QUAKED spawnfunc_item_flag_team2 (0 0.5 0.8) (-48 -48 -24) (48 48 64) -CTF flag for team two (Blue). -Multiple are allowed. - -Keys: -"angle" - Angle the flag will point -(minus 90 degrees) -"model" - model to use, note this needs red and blue as skins 0 and 1 - (default models/ctf/flag.md3) -"noise" - sound played when flag is picked up - (default ctf/take.wav) -"noise1" - sound played when flag is returned by a teammate - (default ctf/return.wav) -"noise2" - sound played when flag is captured - (default ctf/bluecapture.wav) -"noise3" - sound played when flag is lost in the field and respawns itself - (default ctf/respawn.wav) -*/ - -void spawnfunc_item_flag_team2() -{ - if (!g_ctf) - { - remove(self); - return; - } - - if (g_ctf_reverse) - { - float old_g_ctf_reverse = g_ctf_reverse; - g_ctf_reverse = 0; // avoid an endless loop - spawnfunc_item_flag_team1(); - g_ctf_reverse = old_g_ctf_reverse; - return; - } - - // link flag into ctf_worldflaglist - self.ctf_worldflagnext = ctf_worldflaglist; - ctf_worldflaglist = self; - - self.classname = "item_flag_team"; - self.team = NUM_TEAM_2; // color 13 team (blue) - self.items = IT_KEY1; // silver key (bluish enough) - self.netname = "^4BLUE^7 flag"; - self.target = "###item###"; - self.skin = autocvar_g_ctf_flag_blue_skin; - if(self.spawnflags & 1) - self.noalign = 1; - if (!self.model) - self.model = autocvar_g_ctf_flag_blue_model; - if (!self.noise) - self.noise = "ctf/blue_taken.wav"; - if (!self.noise1) - self.noise1 = "ctf/blue_returned.wav"; - if (!self.noise2) - self.noise2 = "ctf/blue_capture.wav"; // blue team scores by capturing the red flag - if (!self.noise3) - self.noise3 = "ctf/flag_respawn.wav"; - if (!self.noise4) - self.noise4 = "ctf/blue_dropped.wav"; - precache_model (self.model); - setmodel (self, self.model); // precision set below - precache_sound (self.noise); - precache_sound (self.noise1); - precache_sound (self.noise2); - precache_sound (self.noise3); - precache_sound (self.noise4); - //setsize(self, '-16 -16 -37', '16 16 37'); - setsize(self, FLAG_MIN, FLAG_MAX); - setorigin(self, self.origin + '0 0 37'); - self.nextthink = time + 0.2; // start after doors etc - self.think = place_flag; - - if(!self.scale) - self.scale = 0.6; - //if(!self.glow_size) - // self.glow_size = 50; - - self.effects = self.effects | EF_LOWPRECISION; - if(autocvar_g_ctf_fullbrightflags) - self.effects |= EF_FULLBRIGHT; - if(autocvar_g_ctf_dynamiclights) - self.effects |= EF_BLUE; - - // From Spidflisk - item_flag_postspawn(); - - precache_model("models/ctf/shield.md3"); - precache_model("models/ctf/shockwavetransring.md3"); - - self.reset = item_flag_reset; -} - - -/*QUAKED spawnfunc_ctf_team (0 .5 .8) (-16 -16 -24) (16 16 32) -Team declaration for CTF gameplay, this allows you to decide what team -names and control point models are used in your map. - -Note: If you use spawnfunc_ctf_team entities you must define at least 2! However, unlike -domination, you don't need to make a blank one too. - -Keys: -"netname" - Name of the team (for example Red, Blue, Green, Yellow, Life, Death, Offense, Defense, etc) -"cnt" - Scoreboard color of the team (for example 4 is red and 13 is blue) - -*/ - -void spawnfunc_ctf_team() -{ - if (!g_ctf) - { - remove(self); - return; - } - self.classname = "ctf_team"; - self.team = self.cnt + 1; -} - -// code from here on is just to support maps that don't have control point and team entities -void ctf_spawnteam (string teamname, float teamcolor) -{ - entity oldself; - oldself = self; - self = spawn(); - self.classname = "ctf_team"; - self.netname = teamname; - self.cnt = teamcolor; - - spawnfunc_ctf_team(); - - self = oldself; -} - -// spawn some default teams if the map is not set up for ctf -void ctf_spawnteams() -{ - float numteams; - - numteams = 2;//cvar("g_ctf_default_teams"); - - ctf_spawnteam("Red", NUM_TEAM_1 - 1); - ctf_spawnteam("Blue", NUM_TEAM_2 - 1); -} - -void ctf_delayedinit() -{ - // if no teams are found, spawn defaults - if (find(world, classname, "ctf_team") == world) - ctf_spawnteams(); - - ScoreRules_ctf(); -} - -void ctf_init() -{ - InitializeEntity(world, ctf_delayedinit, INITPRIO_GAMETYPE); - flagcaptimerecord = stof(db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"))); - - captureshield_min_negscore = autocvar_g_ctf_shield_min_negscore; - captureshield_max_ratio = autocvar_g_ctf_shield_max_ratio; - captureshield_force = autocvar_g_ctf_shield_force; -} - -void ctf_setstatus2(entity flag, float shift) -{ - if (flag.cnt == FLAG_CARRY) - if (flag.owner == self) - self.items |= shift * 3; - else - self.items |= shift * 1; - else if (flag.cnt == FLAG_DROPPED) - self.items |= shift * 2; - else - { - // no status bits - } -} - -void ctf_setstatus() -{ - self.items &~= IT_RED_FLAG_TAKEN; - self.items &~= IT_RED_FLAG_LOST; - self.items &~= IT_BLUE_FLAG_TAKEN; - self.items &~= IT_BLUE_FLAG_LOST; - self.items &~= IT_CTF_SHIELDED; - - entity flag; - float redflags, blueflags; - - if(self.ctf_captureshielded) - self.items |= IT_CTF_SHIELDED; - - redflags = 0; - blueflags = 0; - - for (flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext) if(flag.cnt != FLAG_BASE) - { - if(flag.items & IT_KEY2) // blue - ++redflags; - else if(flag.items & IT_KEY1) // red - ++blueflags; - } - - // blinking magic: if there is more than one flag, show one of these in a clever way - if(redflags) - redflags = mod(floor(time * redflags * 0.75), redflags); - if(blueflags) - blueflags = mod(floor(time * blueflags * 0.75), blueflags); - - for (flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext) if(flag.cnt != FLAG_BASE) - { - if(flag.items & IT_KEY2) // blue - { - if(--redflags == -1) // happens exactly once (redflags is in 0..count-1, and will --'ed count times) - ctf_setstatus2(flag, IT_RED_FLAG_TAKEN); - } - else if(flag.items & IT_KEY1) // red - { - if(--blueflags == -1) // happens exactly once - ctf_setstatus2(flag, IT_BLUE_FLAG_TAKEN); - } - } -} -/* -entity ctf_team_has_commander(float cteam) -{ - entity pl; - if(cteam != NUM_TEAM_1 || cteam != NUM_TEAM_2) - return world; - - FOR_EACH_REALPLAYER(pl) { - if(pl.team == cteam && pl.iscommander) { - return pl; - } - } - return world; -} - -void ctf_setstate(entity e, float st) -{ - e.ctf_state = st; - ++e.version; -} - -void ctf_new_commander(float cteam) -{ - entity pl, plmax; - - plmax = world; - FOR_EACH_REALPLAYER(pl) { - if(pl.team == cteam) { - if(pl.iscommander) { // don't reassign if alreay there - return; - } - if(plmax == world || plmax.frags < pl.frags) <<<<<<<<<<<<<<<<< BROKEN in new scoring system - plmax = pl; - } - } - if(plmax == world) { - bprint(strcat(ColoredTeamName(cteam), " Team has no Commander!\n")); - return; - } - - plmax.iscommander = TRUE; - ctf_setstate(plmax, 3); - sprint(plmax, "^3You're the commander now!\n"); - centerprint(plmax, "^3You're the commander now!\n"); -} - -void ctf_clientconnect() -{ - self.iscommander = FALSE; - - if(!self.team || self.classname != "player") { - ctf_setstate(self, -1); - } else - ctf_setstate(self, 0); - - self.team_saved = self.team; - - if(self.team != 0 && self.classname == "player" && !ctf_team_has_commander(self.team)) { - ctf_new_commander(self.team); - } -} - -void ctf_playerchanged() -{ - if(!self.team || self.classname != "player") { - ctf_setstate(self, -1); - } else if(self.ctf_state < 0 && self.classname == "player") { - ctf_setstate(self, 0); - } - - if(self.iscommander && - (self.classname != "player" || self.team != self.team_saved) - ) - { - self.iscommander = FALSE; - if(self.classname == "player") - ctf_setstate(self, 0); - else - ctf_setstate(self, -1); - ctf_new_commander(self.team_saved); - } - - self.team_saved = self.team; - - ctf_new_commander(self.team); -} - -void ctf_clientdisconnect() -{ - if(self.iscommander) - { - ctf_new_commander(self.team); - } -} - -entity GetPlayer(string); -float ctf_clientcommand() -{ - entity e; - if(argv(0) == "order") { - if(!g_ctf) { - sprint(self, "This command is not supported in this gamemode.\n"); - return TRUE; - } - if(!self.iscommander) { - sprint(self, "^1You are not the commander!\n"); - return TRUE; - } - if(argv(2) == "") { - sprint(self, "Usage: order #player status - (playernumber as in status)\n"); - return TRUE; - } - e = GetPlayer(argv(1)); - if(e == world) { - sprint(self, "Invalid player.\nUsage: order #player status - (playernumber as in status)\n"); - return TRUE; - } - if(e.team != self.team) { - sprint(self, "^3You can only give orders to your own team!\n"); - return TRUE; - } - if(argv(2) == "attack") { - sprint(self, strcat("Ordering ", e.netname, " to attack!\n")); - sprint(e, "^1Attack!\n"); - centerprint(e, "^7You've been ordered to^9\n^1Attack!\n"); - ctf_setstate(e, 1); - } else if(argv(2) == "defend") { - sprint(self, strcat("Ordering ", e.netname, " to defend!\n")); - sprint(e, "^Defend!\n"); - centerprint(e, "^7You've been ordered to^9\n^2Defend!\n"); - ctf_setstate(e, 2); - } else { - sprint(self, "^7Invalid command, use ^3attack^7, or ^3defend^7.\n"); - } - return TRUE; - } - return FALSE; -} -*/ diff --git a/qcsrc/server/attic/domination.qc b/qcsrc/server/attic/domination.qc deleted file mode 100644 index a898b53e9..000000000 --- a/qcsrc/server/attic/domination.qc +++ /dev/null @@ -1,525 +0,0 @@ - -/* -Domination as a plugin for netquake mods -by LordHavoc (lordhavoc@ghdigital.com) - -How to add domination points to a mod: -1. Add this line to progs.src above world.qc: -domination.qc -2. Comment out all lines in ClientObituary in client.qc that begin with targ.frags or attacker.frags. -3. Add this above spawnfunc_worldspawn in world.qc: -void() dom_init; -4. Add this line to the end of spawnfunc_worldspawn in world.qc: -dom_init(); - -Note: The only teams who can use dom control points are identified by spawnfunc_dom_team entities (if none exist these default to red and blue and use only quake models/sounds). -*/ - -#define DOMPOINTFRAGS frags - -.float enemy_playerid; -.entity sprite; -.float captime; - -// pps: points per second -.float dom_total_pps; -.float dom_pps_red; -.float dom_pps_blue; -.float dom_pps_yellow; -.float dom_pps_pink; -float total_pps; -float pps_red; -float pps_blue; -float pps_yellow; -float pps_pink; -void set_dom_state(entity e) -{ - e.dom_total_pps = total_pps; - e.dom_pps_red = pps_red; - e.dom_pps_blue = pps_blue; - if(c3 >= 0) - e.dom_pps_yellow = pps_yellow; - if(c4 >= 0) - e.dom_pps_pink = pps_pink; -} - -void() dom_controlpoint_setup; - -void LogDom(string mode, float team_before, entity actor) -{ - string s; - if(!autocvar_sv_eventlog) - return; - s = strcat(":dom:", mode); - s = strcat(s, ":", ftos(team_before)); - s = strcat(s, ":", ftos(actor.playerid)); - GameLogEcho(s); -} - -void() dom_spawnteams; - -void dompoint_captured () -{ - entity head; - float old_delay, old_team, real_team; - - // now that the delay has expired, switch to the latest team to lay claim to this point - head = self.owner; - - real_team = self.cnt; - self.cnt = -1; - - LogDom("taken", self.team, self.dmg_inflictor); - self.dmg_inflictor = world; - - self.goalentity = head; - self.model = head.mdl; - self.modelindex = head.dmg; - self.skin = head.skin; - - //bprint(head.message); - //bprint("\n"); - - //bprint(^3head.netname); - //bprint(head.netname); - //bprint(self.message); - //bprint("\n"); - - float points, wait_time; - if (autocvar_g_domination_point_amt) - points = autocvar_g_domination_point_amt; - else - points = self.frags; - if (autocvar_g_domination_point_rate) - wait_time = autocvar_g_domination_point_rate; - else - wait_time = self.wait; - - bprint("^3", head.netname, "^3", self.message); - if (points != 1) - bprint(" ^7(", ftos(points), " points every ", ftos(wait_time), " seconds)\n"); - else - bprint(" ^7(", ftos(points), " point every ", ftos(wait_time), " seconds)\n"); - - if(self.enemy.playerid == self.enemy_playerid) - PlayerScore_Add(self.enemy, SP_DOM_TAKES, 1); - else - self.enemy = world; - - if (head.noise != "") - if(self.enemy) - sound(self.enemy, CH_TRIGGER, head.noise, VOL_BASE, ATTN_NORM); - else - sound(self, CH_TRIGGER, head.noise, VOL_BASE, ATTN_NORM); - if (head.noise1 != "") - play2all(head.noise1); - - //self.nextthink = time + autocvar_g_domination_point_rate; - //self.think = dompointthink; - - self.delay = time + wait_time; - - // do trigger work - old_delay = self.delay; - old_team = self.team; - self.team = real_team; - self.delay = 0; - activator = self; - SUB_UseTargets (); - self.delay = old_delay; - self.team = old_team; - - switch(self.goalentity.team) - { - case NUM_TEAM_1: - WaypointSprite_UpdateSprites(self.sprite, "dom-red", "", ""); - break; - case NUM_TEAM_2: - WaypointSprite_UpdateSprites(self.sprite, "dom-blue", "", ""); - break; - case NUM_TEAM_3: - WaypointSprite_UpdateSprites(self.sprite, "dom-yellow", "", ""); - break; - case NUM_TEAM_4: - WaypointSprite_UpdateSprites(self.sprite, "dom-pink", "", ""); - } - - total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0; - for(head = world; (head = find(head, classname, "dom_controlpoint")) != world; ) - { - if (autocvar_g_domination_point_amt) - points = autocvar_g_domination_point_amt; - else - points = head.frags; - if (autocvar_g_domination_point_rate) - wait_time = autocvar_g_domination_point_rate; - else - wait_time = head.wait; - switch(head.goalentity.team) - { - case NUM_TEAM_1: - pps_red += points/wait_time; - break; - case NUM_TEAM_2: - pps_blue += points/wait_time; - break; - case NUM_TEAM_3: - pps_yellow += points/wait_time; - break; - case NUM_TEAM_4: - pps_pink += points/wait_time; - } - total_pps += points/wait_time; - } - - WaypointSprite_UpdateTeamRadar(self.sprite, RADARICON_DOMPOINT, colormapPaletteColor(self.goalentity.team - 1, 0)); - WaypointSprite_Ping(self.sprite); - - self.captime = time; - - FOR_EACH_REALCLIENT(head) - set_dom_state(head); -} - -void AnimateDomPoint() -{ - if(self.pain_finished > time) - return; - self.pain_finished = time + self.t_width; - if(self.nextthink > self.pain_finished) - self.nextthink = self.pain_finished; - - self.frame = self.frame + 1; - if(self.frame > self.t_length) - self.frame = 0; -} - -void dompointthink() -{ - float fragamt; - - self.nextthink = time + 0.1; - - //self.frame = self.frame + 1; - //if(self.frame > 119) - // self.frame = 0; - AnimateDomPoint(); - - // give points - - if (gameover || self.delay > time || time < game_starttime) // game has ended, don't keep giving points - return; - - if(autocvar_g_domination_point_rate) - self.delay = time + autocvar_g_domination_point_rate; - else - self.delay = time + self.wait; - - // give credit to the team - // NOTE: this defaults to 0 - if (self.goalentity.netname != "") - { - if(autocvar_g_domination_point_amt) - fragamt = autocvar_g_domination_point_amt; - else - fragamt = self.DOMPOINTFRAGS; - TeamScore_AddToTeam(self.goalentity.team, ST_SCORE, fragamt); - TeamScore_AddToTeam(self.goalentity.team, ST_DOM_TICKS, fragamt); - - // give credit to the individual player, if he is still there - if (self.enemy.playerid == self.enemy_playerid) - { - PlayerScore_Add(self.enemy, SP_SCORE, fragamt); - PlayerScore_Add(self.enemy, SP_DOM_TICKS, fragamt); - } - else - self.enemy = world; - } -} - -void dompointtouch() -{ - entity head; - if (other.classname != "player") - return; - if (other.health < 1) - return; - - if(time < self.captime + 0.3) - return; - - // only valid teams can claim it - head = find(world, classname, "dom_team"); - while (head && head.team != other.team) - head = find(head, classname, "dom_team"); - if (!head || head.netname == "" || head == self.goalentity) - return; - - // delay capture - - self.team = self.goalentity.team; // this stores the PREVIOUS team! - - self.cnt = other.team; - self.owner = head; // team to switch to after the delay - self.dmg_inflictor = other; - - // self.state = 1; - // self.delay = time + cvar("g_domination_point_capturetime"); - //self.nextthink = time + cvar("g_domination_point_capturetime"); - //self.think = dompoint_captured; - - // go to neutral team in the mean time - head = find(world, classname, "dom_team"); - while (head && head.netname != "") - head = find(head, classname, "dom_team"); - if(head == world) - return; - - WaypointSprite_UpdateSprites(self.sprite, "dom-neut", "", ""); - WaypointSprite_UpdateTeamRadar(self.sprite, RADARICON_DOMPOINT, '0 1 1'); - WaypointSprite_Ping(self.sprite); - - self.goalentity = head; - self.model = head.mdl; - self.modelindex = head.dmg; - self.skin = head.skin; - - self.enemy = other; // individual player scoring - self.enemy_playerid = other.playerid; - dompoint_captured(); -} - -/*QUAKED spawnfunc_dom_team (0 .5 .8) (-32 -32 -24) (32 32 32) -Team declaration for Domination gameplay, this allows you to decide what team -names and control point models are used in your map. - -Note: If you use spawnfunc_dom_team entities you must define at least 3 and only two -can have netname set! The nameless team owns all control points at start. - -Keys: -"netname" - Name of the team (for example Red Team, Blue Team, Green Team, Yellow Team, Life, Death, etc) -"cnt" - Scoreboard color of the team (for example 4 is red and 13 is blue) -"model" - Model to use for control points owned by this team (for example - "progs/b_g_key.mdl" is a gold keycard, and "progs/b_s_key.mdl" is a silver - keycard) -"skin" - Skin of the model to use (for team skins on a single model) -"noise" - Sound to play when this team captures a point. - (this is a localized sound, like a small alarm or other effect) -"noise1" - Narrator speech to play when this team captures a point. - (this is a global sound, like "Red team has captured a control point") -*/ - -void spawnfunc_dom_team() -{ - if(!g_domination || autocvar_g_domination_teams_override >= 2) - { - remove(self); - return; - } - precache_model(self.model); - if (self.noise != "") - precache_sound(self.noise); - if (self.noise1 != "") - precache_sound(self.noise1); - self.classname = "dom_team"; - setmodel(self, self.model); // precision not needed - self.mdl = self.model; - self.dmg = self.modelindex; - self.model = ""; - self.modelindex = 0; - // this would have to be changed if used in quakeworld - if(self.cnt) - self.team = self.cnt + 1; // WHY are these different anyway? -} - -void dom_controlpoint_setup() -{ - entity head; - // find the spawnfunc_dom_team representing unclaimed points - head = find(world, classname, "dom_team"); - while(head && head.netname != "") - head = find(head, classname, "dom_team"); - if (!head) - objerror("no spawnfunc_dom_team with netname \"\" found\n"); - - // copy important properties from spawnfunc_dom_team entity - self.goalentity = head; - setmodel(self, head.mdl); // precision already set - self.skin = head.skin; - - self.cnt = -1; - - if(self.message == "") - self.message = " has captured a control point"; - - if(self.DOMPOINTFRAGS <= 0) - self.DOMPOINTFRAGS = 1; - if(self.wait <= 0) - self.wait = 5; - - float points, waittime; - if (autocvar_g_domination_point_amt) - points = autocvar_g_domination_point_amt; - else - points = self.frags; - if (autocvar_g_domination_point_rate) - waittime = autocvar_g_domination_point_rate; - else - waittime = self.wait; - - total_pps += points/waittime; - - if(!self.t_width) - self.t_width = 0.02; // frame animation rate - if(!self.t_length) - self.t_length = 239; // maximum frame - - self.think = dompointthink; - self.nextthink = time; - self.touch = dompointtouch; - self.solid = SOLID_TRIGGER; - self.flags = FL_ITEM; - setsize(self, '-32 -32 -32', '32 32 32'); - setorigin(self, self.origin + '0 0 20'); - droptofloor(); - - waypoint_spawnforitem(self); - WaypointSprite_SpawnFixed("dom-neut", self.origin + '0 0 32', self, sprite, RADARICON_DOMPOINT, '0 1 1'); -} - - - -/*QUAKED spawnfunc_dom_controlpoint (0 .5 .8) (-16 -16 -24) (16 16 32) -Control point for Domination gameplay. -*/ -void spawnfunc_dom_controlpoint() -{ - if(!g_domination) - { - remove(self); - return; - } - self.think = dom_controlpoint_setup; - self.nextthink = time + 0.1; - self.reset = dom_controlpoint_setup; - - if(!self.scale) - self.scale = 0.6; - - //if(!self.glow_size) - // self.glow_size = cvar("g_domination_point_glow"); - self.effects = self.effects | EF_LOWPRECISION; - if (autocvar_g_domination_point_fullbright) - self.effects |= EF_FULLBRIGHT; -} - -// code from here on is just to support maps that don't have control point and team entities -void dom_spawnteam (string teamname, float teamcolor, string pointmodel, float pointskin, string capsound, string capnarration, string capmessage) -{ - entity oldself; - oldself = self; - self = spawn(); - self.classname = "dom_team"; - self.netname = teamname; - self.cnt = teamcolor; - self.model = pointmodel; - self.skin = pointskin; - self.noise = capsound; - self.noise1 = capnarration; - self.message = capmessage; - - // this code is identical to spawnfunc_dom_team - setmodel(self, self.model); // precision not needed - self.mdl = self.model; - self.dmg = self.modelindex; - self.model = ""; - self.modelindex = 0; - // this would have to be changed if used in quakeworld - self.team = self.cnt + 1; - - //eprint(self); - self = oldself; -} - -void dom_spawnpoint(vector org) -{ - entity oldself; - oldself = self; - self = spawn(); - self.classname = "dom_controlpoint"; - self.think = spawnfunc_dom_controlpoint; - self.nextthink = time; - setorigin(self, org); - spawnfunc_dom_controlpoint(); - self = oldself; -} - -// spawn some default teams if the map is not set up for domination -void dom_spawnteams() -{ - float numteams; - if(autocvar_g_domination_teams_override < 2) - numteams = autocvar_g_domination_default_teams; - else - numteams = autocvar_g_domination_teams_override; - // LordHavoc: edit this if you want to change defaults - dom_spawnteam("Red", NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, "domination/claim.wav", "", "Red team has captured a control point"); - dom_spawnteam("Blue", NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, "domination/claim.wav", "", "Blue team has captured a control point"); - if(numteams > 2) - dom_spawnteam("Yellow", NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, "domination/claim.wav", "", "Yellow team has captured a control point"); - if(numteams > 3) - dom_spawnteam("Pink", NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, "domination/claim.wav", "", "Pink team has captured a control point"); - dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", ""); -} - -void dom_delayedinit() -{ - entity head; - - // if no teams are found, spawn defaults, if custom teams are set, use them - if (find(world, classname, "dom_team") == world || autocvar_g_domination_teams_override >= 2) - dom_spawnteams(); - // if no control points are found, spawn defaults - if (find(world, classname, "dom_controlpoint") == world) - { - // TODO in a few months (maybe 2011/08): change this into error() and remove this very poor dom point selection - backtrace("This map contains no dom_controlpoint entities. A very poor dom point placement will be chosen. Please fix the map."); - - // if no supported map was found, make every deathmatch spawn a point - head = find(world, classname, "info_player_deathmatch"); - while (head) - { - dom_spawnpoint(head.origin); - head = find(head, classname, "info_player_deathmatch"); - } - } - - ScoreRules_dom(); -} - -void dom_init() -{ - // we have to precache default models/sounds even if they might not be - // used because spawnfunc_worldspawn is executed before any other entities are read, - // so we don't even know yet if this map is set up for domination... - precache_model("models/domination/dom_red.md3"); - precache_model("models/domination/dom_blue.md3"); - precache_model("models/domination/dom_yellow.md3"); - precache_model("models/domination/dom_pink.md3"); - precache_model("models/domination/dom_unclaimed.md3"); - precache_sound("domination/claim.wav"); - InitializeEntity(world, dom_delayedinit, INITPRIO_GAMETYPE); - - addstat(STAT_DOM_TOTAL_PPS, AS_FLOAT, dom_total_pps); - addstat(STAT_DOM_PPS_RED, AS_FLOAT, dom_pps_red); - addstat(STAT_DOM_PPS_BLUE, AS_FLOAT, dom_pps_blue); - if(c3 >= 0) addstat(STAT_DOM_PPS_YELLOW, AS_FLOAT, dom_pps_yellow); - if(c4 >= 0) addstat(STAT_DOM_PPS_PINK, AS_FLOAT, dom_pps_pink); -} - diff --git a/qcsrc/server/attic/monsters/ai.qc b/qcsrc/server/attic/monsters/ai.qc deleted file mode 100644 index 59989e7a8..000000000 --- a/qcsrc/server/attic/monsters/ai.qc +++ /dev/null @@ -1,891 +0,0 @@ -void() movetarget_f; -void() t_movetarget; -void() FoundTarget; - -float MONSTER_WANDER = 64; // disable wandering around -float MONSTER_APPEAR = 128; // spawn invisible, and appear when triggered - -.float ismonster; -.float monsterawaitingteleport; // avoid awaking monsters in teleport rooms - -// when a monster becomes angry at a player, that monster will be used -// as the sight target the next frame so that monsters near that one -// will wake up even if they wouldn't have noticed the player -// -entity sight_entity; -float sight_entity_time; - -/* - -.enemy -Will be world if not currently angry at anyone. - -.movetarget -The next path spot to walk toward. If .enemy, ignore .movetarget. -When an enemy is killed, the monster will try to return to it's path. - -.huntt_ime -Set to time + something when the player is in sight, but movement straight for -him is blocked. This causes the monster to use wall following code for -movement direction instead of sighting on the player. - -.ideal_yaw -A yaw angle of the intended direction, which will be turned towards at up -to 45 deg / state. If the enemy is in view and hunt_time is not active, -this will be the exact line towards the enemy. - -.pausetime -A monster will leave it's stand state and head towards it's .movetarget when -time > .pausetime. - -walkmove(angle, speed) primitive is all or nothing -*/ - - -// -// globals -// -//float current_yaw; - -float(float v) anglemod = -{ - v = v - 360 * floor(v / 360); - return v; -} - -/* -============================================================================== - -MOVETARGET CODE - -The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which allways heads to the next target. - -targetname -must be present. The name of this movetarget. - -target -the next spot to move to. If not present, stop here for good. - -pausetime -The number of seconds to spend standing or bowing for path_stand or path_bow - -============================================================================== -*/ - - -void() movetarget_f = -{ - if (!self.targetname) - objerror ("monster_movetarget: no targetname"); - - self.solid = SOLID_TRIGGER; - self.touch = t_movetarget; - setsize (self, '-8 -8 -8', '8 8 8'); -} - -/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8) -Monsters will continue walking towards the next target corner. -*/ -void() path_corner = -{ - movetarget_f (); -} - -/* -============= -t_movetarget - -Something has bumped into a movetarget. If it is a monster -moving towards it, change the next destination and continue. -============== -*/ -void() t_movetarget = -{ - entity temp; - - if (other.health < 1) - return; - if (other.movetarget != self) - return; - - if (other.enemy) - return; // fighting, not following a path - - temp = self; - self = other; - other = temp; - - /* PLEASE FIX THE SOUND CHANNEL BEFORE ACTIVATING THIS - if (self.classname == "monster_ogre") - sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound - */ - -//dprint ("t_movetarget\n"); - self.goalentity = self.movetarget = find (world, targetname, other.target); - self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); - if (!self.movetarget) - { - self.pausetime = time + 999999; - self.th_stand (); - return; - } -} - -void() monster_wanderpaththink = -{ - vector v, v1; - float b, c; - self.nextthink = time + random() * 10 + 1; - if (self.owner.health < 1) // dead, also handled in death code - { - self.owner.movetarget = world; - remove(self); - return; - } - b = -1; - c = 10; - while (c > 0) - { - c = c - 1; - v = randomvec(); - traceline(self.owner.origin, v * 1024 + self.owner.origin, FALSE, self); - v = trace_endpos - (normalize(v) * 16) - self.owner.origin; - if (vlen(v) > b) - { - b = vlen(v); - v1 = v; - } - } - setorigin(self, v1 + self.owner.origin); - self.owner.ideal_yaw = vectoyaw(self.origin - self.owner.origin); -} - -void() monster_wanderpathtouch = -{ - if (other.health < 1) - return; - if (other.movetarget != self) - return; - - if (other.enemy) - return; // fighting, not following a path - - /* PLEASE FIX THE SOUND CHANNEL BEFORE ACTIVATING THIS - if (other.classname == "monster_ogre") - sound (other, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound - */ - monster_wanderpaththink(); -} - -void() monster_spawnwanderpath = -{ - newmis = spawn(); - newmis.classname = "monster_wanderpath"; - newmis.solid = SOLID_TRIGGER; - newmis.touch = monster_wanderpathtouch; - setsize (newmis, '-8 -8 -8', '8 8 8'); - newmis.think = monster_wanderpaththink; - newmis.nextthink = time + random() * 10 + 1; - newmis.owner = self; - self.goalentity = self.movetarget = newmis; -} - -void() monster_checkbossflag = -{ -//#NO AUTOCVARS START -#if 0 - float healthboost; - float r; - - // monsterbosses cvar or spawnflag 64 causes a monster to be a miniboss - if ((self.spawnflags & 64) || (random() * 100 < cvar("monsterbosspercent"))) - { - self.radsuit_finished = time + 1000000000; - r = random() * 4; - if (r < 2) - { - self.super_damage_finished = time + 1000000000; - healthboost = 30 + self.health * 0.5; - self.effects = self.effects | (EF_FULLBRIGHT | EF_BLUE); - } - if (r >= 1) - { - healthboost = 30 + self.health * bound(0.5, skill * 0.5, 1.5); - self.effects = self.effects | (EF_FULLBRIGHT | EF_RED); - self.healthregen = max(self.healthregen, min(skill * 10, 30)); - } - self.health = self.health + healthboost; - self.max_health = self.health; - self.bodyhealth = self.bodyhealth * 2 + healthboost; - do - { - self.colormod_x = random(); - self.colormod_y = random(); - self.colormod_z = random(); - self.colormod = normalize(self.colormod); - } - while (self.colormod_x > 0.6 && self.colormod_y > 0.6 && self.colormod_z > 0.6); - } -#endif -//#NO AUTOCVARS END -} - - -//============================================================================ - -/* -============= -range - -returns the range catagorization of an entity reletive to self -0 melee range, will become hostile even if back is turned -1 visibility and infront, or visibility and show hostile -2 infront and show hostile -3 only triggered by damage -============= -*/ -float(entity targ) range = -{ - float r; - r = vlen ((self.origin + self.view_ofs) - (targ.origin + targ.view_ofs)); - if (r < 120) - return RANGE_MELEE; - if (r < 500) - return RANGE_NEAR; - if (r < 2000) // increased from 1000 for DP - return RANGE_MID; - return RANGE_FAR; -} - -/* -============= -visible - -returns 1 if the entity is visible to self, even if not infront () -============= -*/ -float (entity targ) visible = -{ - if (vlen(targ.origin - self.origin) > 5000) // long traces are slow - return FALSE; - - traceline ((self.origin + self.view_ofs), (targ.origin + targ.view_ofs), TRUE, self); // see through other monsters - - if (trace_inopen && trace_inwater) - return FALSE; // sight line crossed contents - - if (trace_fraction == 1) - return TRUE; - return FALSE; -} - - -/* -============= -infront - -returns 1 if the entity is in front (in sight) of self -============= -*/ -float(entity targ) infront = -{ - float dot; - - makevectors (self.angles); - dot = normalize (targ.origin - self.origin) * v_forward; - - return (dot > 0.3); -} -// returns 0 if not infront, or the dotproduct if infront -float(vector dir, entity targ) infront2 = -{ - float dot; - - dir = normalize(dir); - dot = normalize (targ.origin - self.origin) * dir; - - if (dot >= 0.3) return dot; // infront - return 0; -} - - -//============================================================================ - -/* -=========== -ChangeYaw - -Turns towards self.ideal_yaw at self.yaw_speed -Sets the global variable current_yaw -Called every 0.1 sec by monsters -============ -*/ -/* - -void() ChangeYaw = -{ - float ideal, move; - -//current_yaw = self.ideal_yaw; -// mod down the current angle - current_yaw = anglemod( self.angles_y ); - ideal = self.ideal_yaw; - - if (current_yaw == ideal) - return; - - move = ideal - current_yaw; - if (ideal > current_yaw) - { - if (move > 180) - move = move - 360; - } - else - { - if (move < -180) - move = move + 360; - } - - if (move > 0) - { - if (move > self.yaw_speed) - move = self.yaw_speed; - } - else - { - if (move < 0-self.yaw_speed ) - move = 0-self.yaw_speed; - } - - current_yaw = anglemod (current_yaw + move); - - self.angles_y = current_yaw; -} - -*/ - - -//============================================================================ - -void() HuntTarget = -{ - self.goalentity = self.enemy; - self.think = self.th_run; - self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); - self.nextthink = time + 0.1; - SUB_AttackFinished (1); // wait a while before first attack -} - -.void() th_sightsound; - -void() SightSound = -{ - if (self.health < 1) - return; - // skill 5 does not play sight sounds, instead you only hear the appear sound as they are about to attack - if (skill >= 5) - if (self.classname != "monster_hellfish") - return; - - if (self.th_sightsound) - self.th_sightsound(); -} - -void() FoundTarget = -{ - if (self.health < 1 || !self.th_run) - return; - if (self.enemy.health < 1 || !self.enemy.takedamage) - return; - if (self.enemy.classname == "player") - { - // let other monsters see this monster for a while - sight_entity = self; - sight_entity_time = time + 0.1; - } - - self.show_hostile = time + 1; // wake up other monsters - - SightSound (); - HuntTarget (); -} - -/* -//float checkplayertime; -entity lastcheckplayer; -entity havocbot_list; - - -entity() checkplayer = -{ - entity check; - float worldcount; - // we can just fallback on checkclient if there are no bots - if (!havocbot_list) - return checkclient(); -*/ - /* - if (time < checkplayertime) - { - traceline(self.origin + self.view_ofs, lastcheckplayer.origin + lastcheckplayer.view_ofs, TRUE, self); - if (trace_fraction == 1) - return lastcheckplayer; - if (trace_ent == lastcheckplayer) - return lastcheckplayer; - } - checkplayertime = time + 0.1; - */ -/* - check = lastcheckplayer; - worldcount = 0; - c = 0; - do - { - c = c + 1; - check = findfloat(check, havocattack, TRUE); - if (check.classname == "player" || check.classname == "turretbase") - { - traceline(self.origin + self.view_ofs, check.origin + check.view_ofs, TRUE, self); - if (trace_fraction == 1) - return lastcheckplayer = check; - if (trace_ent == check) - return lastcheckplayer = check; - } - else if (check == world) - { - worldcount = worldcount + 1; - if (worldcount >= 2) - return lastcheckplayer = check; - } - } - while(check != lastcheckplayer && c < 100); - return world; -} -*/ - -/* -=========== -FindTarget - -Self is currently not attacking anything, so try to find a target - -Returns TRUE if an enemy was sighted - -When a player fires a missile, the point of impact becomes a fakeplayer so -that monsters that see the impact will respond as if they had seen the -player. - -To avoid spending too much time, only a single client (or fakeclient) is -checked each frame. This means multi player games will have slightly -slower noticing monsters. -============ -*/ -.float findtarget; -float() FindTarget = -{ - entity client; - float r; - - if (self.health < 1) - return FALSE; - - // if the first or second spawnflag bit is set, the monster will only - // wake up on really seeing the player, not another monster getting angry - - if (self.spawnflags & 3) - { - // don't wake up on seeing another monster getting angry - client = checkclient (); - if (!client) - return FALSE; // current check entity isn't in PVS - } - else - { - if (sight_entity_time >= time) - { - client = sight_entity; - if (client.enemy == self.enemy) - return TRUE; - } - else - { - client = checkclient (); - if (!client) - return FALSE; // current check entity isn't in PVS - } - } - - if (client == self.enemy) - return FALSE; - - if (client.flags & FL_NOTARGET) - return FALSE; - -#if 0 - if (client.items & IT_INVISIBILITY) - return FALSE; -#endif - - // on skill 5 the monsters usually ignore the player and remain ghostlike - if (skill >= 5) - if (self.classname != "monster_hellfish") - if (random() < 0.99) - return FALSE; - - r = range(client); - if (r == RANGE_FAR) - return FALSE; - - if (!visible (client)) - return FALSE; - - if (r == RANGE_NEAR) - { - if (client.show_hostile < time && !infront (client)) - return FALSE; - } - else if (r == RANGE_MID) - { - // LordHavoc: was if ( /* client.show_hostile < time || */ !infront (client)) - if (client.show_hostile < time && !infront (client)) - return FALSE; - } - - // - // got one - // - - if (client.model == "") - return FALSE; - self.enemy = client; - if (self.enemy.classname != "player" && self.enemy.classname != "turretbase") - { - self.enemy = self.enemy.enemy; - if (self.enemy.classname != "player" && self.enemy.classname != "turretbase") - { - self.enemy = world; - return FALSE; - } - } - - FoundTarget (); - - return TRUE; -} - - -//============================================================================= - -void(float dist) ai_forward = -{ - walkmove (self.angles_y, dist); -} - -void(float dist) ai_back = -{ - walkmove ( (self.angles_y+180), dist); -} - - -void(float a) monster_setalpha; - -/* -============= -ai_pain - -stagger back a bit -============= -*/ -void(float dist) ai_pain = -{ - if (self.health < 1) - return; - ai_back (dist); -} - -/* -============= -ai_painforward - -stagger back a bit -============= -*/ -void(float dist) ai_painforward = -{ - if (self.health < 1) - return; - walkmove (self.ideal_yaw, dist); -} - -/* -============= -ai_walk - -The monster is walking it's beat -============= -*/ -void(float dist) ai_walk = -{ - if (self.health < 1) - return; - - movedist = dist; - - // check for noticing a player - if (self.oldenemy.takedamage) - if (self.oldenemy.health >= 1) - { - self.enemy = self.oldenemy; - self.oldenemy = world; - FoundTarget(); - monster_setalpha(0); - return; - } - if (self.enemy) - { - if (self.enemy.takedamage) - { - if (self.enemy.health >= 1) - { - FoundTarget(); - monster_setalpha(0); - return; - } - else - self.enemy = world; - } - else - self.enemy = world; - } - - self.findtarget = TRUE; - - movetogoal (dist); - monster_setalpha(0); -} - - -/* -============= -ai_stand - -The monster is staying in one place for a while, with slight angle turns -============= -*/ -void() ai_stand = -{ - if (self.health < 1) - return; - if (self.enemy) - { - if (self.enemy.takedamage) - { - if (self.enemy.health >= 1) - { - FoundTarget(); - monster_setalpha(0); - return; - } - else - self.enemy = world; - } - else - self.enemy = world; - } - self.findtarget = TRUE; - - if (time > self.pausetime) - { - self.th_walk (); - monster_setalpha(0); - return; - } - -// change angle slightly - - monster_setalpha(0); -} - -/* -============= -ai_turn - -don't move, but turn towards ideal_yaw -============= -*/ -void() ai_turn = -{ - if (self.enemy) - { - if (self.enemy.takedamage) - { - if (self.enemy.health >= 1) - { - FoundTarget(); - monster_setalpha(0); - return; - } - else - self.enemy = world; - } - else - self.enemy = world; - } - self.findtarget = TRUE; - - ChangeYaw (); - monster_setalpha(0); -} - -//============================================================================= - -/* -============= -ChooseTurn -============= -*/ -void(vector pDestvec) ChooseTurn = -{ - vector dir, newdir; - - dir = self.origin - pDestvec; - - newdir_x = trace_plane_normal_y; - newdir_y = 0 - trace_plane_normal_x; - newdir_z = 0; - - if (dir * newdir > 0) - { - dir_x = 0 - trace_plane_normal_y; - dir_y = trace_plane_normal_x; - } - else - { - dir_x = trace_plane_normal_y; - dir_y = 0 - trace_plane_normal_x; - } - - dir_z = 0; - self.ideal_yaw = vectoyaw(dir); -} - -/* -============ -FacingIdeal - -============ -*/ -float() FacingIdeal = -{ - float delta; - - delta = anglemod(self.angles_y - self.ideal_yaw); - if (delta > 45 && delta < 315) - return FALSE; - return TRUE; -} - - -//============================================================================= - -.float() th_checkattack; - - - -/* -============= -ai_run - -The monster has an enemy it is trying to kill -============= -*/ -void(float dist) ai_run = -{ - float ofs; - if (self.health < 1) - return; - movedist = dist; - // see if the enemy is dead - if (self.enemy.health < 1 || self.enemy.takedamage == DAMAGE_NO) - { - self.enemy = world; - // FIXME: look all around for other targets - if (self.oldenemy.health >= 1 && self.oldenemy.takedamage) - { - self.enemy = self.oldenemy; - self.oldenemy = world; - HuntTarget (); - } - else - { - if (self.movetarget) - self.th_walk (); - else - self.th_stand (); - return; - } - } - - // wake up other monsters - self.show_hostile = time + 1; - - // check knowledge of enemy - enemy_range = range(self.enemy); - - self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); - ChangeYaw (); - - if (self.attack_state == AS_MELEE) - { - //dprint ("ai_run_melee\n"); - //Turn and close until within an angle to launch a melee attack - if (FacingIdeal()) - { - self.th_melee (); - self.attack_state = AS_STRAIGHT; - } - return; - } - else if (self.attack_state == AS_MISSILE) - { - //dprint ("ai_run_missile\n"); - //Turn in place until within an angle to launch a missile attack - if (FacingIdeal()) - if (self.th_missile ()) - self.attack_state = AS_STRAIGHT; - return; - } - - if (self.th_checkattack()) - return; // beginning an attack - - if (visible(self.enemy)) - self.search_time = time + 5; - else if (coop) - { - // look for other coop players - if (self.search_time < time) - self.findtarget = TRUE; - } - - if (self.attack_state == AS_SLIDING) - { - //dprint ("ai_run_slide\n"); - //Strafe sideways, but stay at aproximately the same range - if (self.lefty) - ofs = 90; - else - ofs = -90; - - if (walkmove (self.ideal_yaw + ofs, movedist)) - return; - - self.lefty = !self.lefty; - - walkmove (self.ideal_yaw - ofs, movedist); - } - - // head straight in - movetogoal (dist); // done in C code... -} - diff --git a/qcsrc/server/attic/monsters/defs.qc b/qcsrc/server/attic/monsters/defs.qc deleted file mode 100644 index 19821429c..000000000 --- a/qcsrc/server/attic/monsters/defs.qc +++ /dev/null @@ -1,55 +0,0 @@ -.entity movetarget; -.float pausetime; - -.void() th_stand; -.void() th_walk; -.void() th_run; -.float() th_missile; // LordHavoc: changed from void() to float(), returns true if attacking -.void() th_melee; -//.void(entity attacker, float damage, float damgtype, string dethtype) th_pain; // TODO Xonotic uses event_damage -//.void() th_die; // TODO never called directly by Xonotic -.entity oldenemy; // mad at this player before taking damage -entity newmis; // launch_spike sets this after spawning it - -// range values -float RANGE_MELEE = 0; -float RANGE_NEAR = 1; -float RANGE_MID = 2; -float RANGE_FAR = 3; - -float DMG_KNIGHT_MELEE_BASE = 0; -float DMG_KNIGHT_MELEE_RANDOM1 = 3; -float DMG_KNIGHT_MELEE_RANDOM2 = 3; -float DMG_KNIGHT_MELEE_RANDOM3 = 3; - -.float show_hostile; - // set to time+0.2 whenever a client fires a - // weapon or takes damage. Used to alert - // monsters that otherwise would let the player go - -float movedist; -.float lefty; -.float search_time; -.float attack_state; - -float AS_STRAIGHT = 1; -float AS_SLIDING = 2; -float AS_MELEE = 3; -float AS_MISSILE = 4; - -float SKILL4_MINALPHA = 0.4; - -float monsterwander; -//#NO AUTOCVARS START -/* - monsterwander = cvar("monsterwander"); - // monsterwander is always on in skill 5 - if (skill >= 5) - monsterwander = TRUE; -*/ -//#NO AUTOCVARS END - -.float candrown; - -.void(vector org, float bodydamage, float armordamage, vector vel, float damgtype) bleedfunc; -void(vector org, float bodydamage, float armordamage, vector vel, float damgtype) genericbleedfunc; diff --git a/qcsrc/server/attic/monsters/fight.qc b/qcsrc/server/attic/monsters/fight.qc deleted file mode 100644 index a8fcd8e70..000000000 --- a/qcsrc/server/attic/monsters/fight.qc +++ /dev/null @@ -1,252 +0,0 @@ - -/* - -A monster is in fight mode if it thinks it can effectively attack its -enemy. - -When it decides it can't attack, it goes into hunt mode. - -*/ - -void SUB_AttackFinished (float normal) -{ - self.cnt = 0; // refire count for nightmare - if (skill < 3) - ATTACK_FINISHED(self) = time + normal; -} - -float CanDamage(entity targ, entity inflictor) -{ - if (targ.movetype == MOVETYPE_PUSH) - { - traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self); - if (trace_fraction == 1) - return TRUE; - if (trace_ent == targ) - return TRUE; - return FALSE; - } - - traceline(inflictor.origin, targ.origin, TRUE, self); - if (trace_fraction == 1) - return TRUE; - traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self); - if (trace_fraction == 1) - return TRUE; - traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self); - if (trace_fraction == 1) - return TRUE; - traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self); - if (trace_fraction == 1) - return TRUE; - traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self); - if (trace_fraction == 1) - return TRUE; - - return FALSE; -} - -float(float v) anglemod; - -void(vector dest) ChooseTurn; - -void() ai_face; - - -float enemy_range; - - -//============================================================================= - -/* -=========== -GenericCheckAttack - -The player is in view, so decide to move or launch an attack -Returns FALSE if movement should continue -============ -*/ -float() GenericCheckAttack = -{ - vector spot1, spot2; - entity targ; - float chance; - - if (self.health < 1) - return FALSE; - targ = self.enemy; - - if (vlen(targ.origin - self.origin) > 5000) // long traces are slow - return FALSE; - -// see if any entities are in the way of the shot - spot1 = self.origin + self.view_ofs; - spot2 = targ.origin + targ.view_ofs; - - traceline (spot1, spot2, FALSE, self); - - if (trace_ent != targ) - return FALSE; // don't have a clear shot - - if (trace_inopen && trace_inwater) - return FALSE; // sight line crossed contents - - if (enemy_range == RANGE_MELEE) - { // melee attack - if (self.th_melee) - { - self.th_melee (); - return TRUE; - } - } - -// missile attack - if (time < ATTACK_FINISHED(self)) - return FALSE; - - if (!self.th_missile) - return FALSE; - - if (enemy_range == RANGE_FAR) - return FALSE; - - if (enemy_range == RANGE_MELEE) - { - chance = 0.9; - ATTACK_FINISHED(self) = 0; - } - else if (enemy_range == RANGE_NEAR) - { - if (self.th_melee) - chance = 0.2; - else - chance = 0.4; - } - else if (enemy_range == RANGE_MID) - { - if (self.th_melee) - chance = 0.05; - else - chance = 0.1; - } - else - chance = 0; - - if (random () < chance) - if (self.th_missile ()) - { - SUB_AttackFinished (2*random()); - return TRUE; - } - - return FALSE; -} - - -/* -============= -ai_face - -Stay facing the enemy -============= -*/ -void() ai_face = -{ - self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); - ChangeYaw (); -} - -/* -============= -ai_charge - -The monster is in a melee attack, so get as close as possible to .enemy -============= -*/ -float (entity targ) visible; -float(entity targ) infront; -float(entity targ) range; - -void(float d) ai_charge = -{ - if (self.health < 1) - return; - ai_face (); - movetogoal (d); // done in C code... -} - -void() ai_charge_side = -{ - if (self.health < 1) - return; - vector dtemp; - float heading; - -// aim to the left of the enemy for a flyby - - self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); - ChangeYaw (); - - makevectors (self.angles); - dtemp = self.enemy.origin - 30*v_right; - heading = vectoyaw(dtemp - self.origin); - - walkmove(heading, 20); -} - - -/* -============= -ai_melee - -============= -*/ -void() ai_melee = -{ - vector delta; - float ldmg; - - if (self.health < 1) - return; - if (!self.enemy) - return; // removed before stroke - - delta = self.enemy.origin - self.origin; - - if (vlen(delta) > 60) - return; - - ldmg = DMG_KNIGHT_MELEE_BASE + DMG_KNIGHT_MELEE_RANDOM1 * random(); - ldmg = ldmg + DMG_KNIGHT_MELEE_RANDOM2 * random(); - ldmg = ldmg + DMG_KNIGHT_MELEE_RANDOM3 * random(); - traceline(self.origin, self.enemy.origin, FALSE, self); - - Damage (self.enemy, self, self, ldmg, self.projectiledeathtype, trace_endpos, '0 0 0'); // TODO add force to monster melee attacks? -} - - -void() ai_melee_side = -{ - vector delta; - float ldmg; - - if (self.health < 1) - return; - if (!self.enemy) - return; // removed before stroke - - ai_charge_side(); - - delta = self.enemy.origin - self.origin; - - if (vlen(delta) > 60) - return; - if (!CanDamage (self.enemy, self)) - return; - ldmg = DMG_KNIGHT_MELEE_BASE + DMG_KNIGHT_MELEE_RANDOM1 * random(); - ldmg = ldmg + DMG_KNIGHT_MELEE_RANDOM2 * random(); - ldmg = ldmg + DMG_KNIGHT_MELEE_RANDOM3 * random(); - traceline(self.origin, self.enemy.origin, FALSE, self); - Damage (self.enemy, self, self, ldmg, self.projectiledeathtype, trace_endpos, '0 0 0'); -} - diff --git a/qcsrc/server/attic/monsters/m_monsters.qc b/qcsrc/server/attic/monsters/m_monsters.qc deleted file mode 100644 index 0259a5756..000000000 --- a/qcsrc/server/attic/monsters/m_monsters.qc +++ /dev/null @@ -1,478 +0,0 @@ -/* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */ - -// name =[framenum, nexttime, nextthink] {code} -// expands to: -// name () -// { -// self.frame=framenum; -// self.nextthink = time + nexttime; -// self.think = nextthink -// -// } - -.float ismonster; - -.float modelindex2; - -/* -================ -monster_use - -Using a monster makes it angry at the current activator -LordHavoc: using a monster with the spawnflag 'Appear' makes it appear -================ -*/ -void() monster_use = -{ - if (self.enemy) - return; - if (self.health < 1) - return; - if (self.mdl) - if (self.spawnflags & MONSTER_APPEAR) - { - self.nextthink = time + 0.1; - self.spawnflags = self.spawnflags - MONSTER_APPEAR; - self.solid = SOLID_SLIDEBOX; - self.takedamage = DAMAGE_AIM; - //self.movetype = MOVETYPE_STEP; - self.model = self.mdl; - self.mdl = ""; - self.modelindex = self.modelindex2; - self.modelindex2 = 0; - //setorigin(self, self.origin + '0 0 1'); - spawn_tdeath(self.origin, self, self.origin); - return; - } - -#if 0 - if (activator.items & IT_INVISIBILITY) - return; -#endif - if (activator.flags & FL_NOTARGET) - return; - if (activator.classname != "player") - return; - - // delay reaction so if the monster is teleported, its sound is still heard - self.enemy = activator; - self.nextthink = time + 0.1; - self.think = FoundTarget; -} - -void() monster_appearsetup = -{ - if ((self.spawnflags & MONSTER_APPEAR) == 0) - return; - self.mdl = self.model; - self.modelindex2 = self.modelindex; - self.modelindex = 0; - self.solid = SOLID_NOT; - self.takedamage = DAMAGE_NO; - //self.movetype = MOVETYPE_NONE; - self.nextthink = -1; - self.model = ""; -} - -/* -================ -monster_setalpha - -Sets relative alpha of monster in skill 4 mode. -================ -*/ -void(float a) monster_setalpha = -{ - if (skill < 4 || self.classname == "monster_hellfish") - { - self.alpha = 1.0; - return; - } - - if (skill >= 5) - { - // randomly forget enemy, this makes monsters randomly return to their normal ghostlike state - if (a == 0) - if (self.enemy) - if (random() < 0.1) - self.enemy = world; - // randomly blink (playing the same alarming sound as if attacking) - if (self.enemy == world) - { - a = 0; - if (time >= 0.3) // don't blink during the init process because it might become permanent - if (random() < 0.005) - { - // blink for an instant, this causes the appear sound, alarming the player as if under attack - /* PLEASE FIX THE SOUND CHANNEL BEFORE ACTIVATING THIS - sound(self, CHAN_AUTO, "wizard/wsight.wav", 1, ATTN_NORM); - */ - a = 1; - } - } - // if ghosted, become non-solid and immune to damage - if (a <= 0 || self.enemy == world) - { - self.solid = SOLID_NOT; - self.takedamage = DAMAGE_NO; - } - else - { - // if unghosting, make sure we have an enemy, otherwise stay ghosted (even if blinking) so we can't be shot while blinking - /* PLEASE FIX THE SOUND CHANNEL BEFORE ACTIVATING THIS - if (self.solid != SOLID_SLIDEBOX) - sound(self, CHAN_AUTO, "wizard/wsight.wav", 1, ATTN_NORM); - */ - self.solid = SOLID_SLIDEBOX; - self.takedamage = DAMAGE_AIM; - } - } - self.alpha = SKILL4_MINALPHA + (1 - SKILL4_MINALPHA) * bound(0, a, 1); -} - -/* -================ -monster_death_use - -When a mosnter dies, it fires all of its targets with the current -enemy as activator. -================ -*/ -void() monster_death_use = -{ -// fall to ground - if (self.flags & FL_FLY) - self.flags = self.flags - FL_FLY; - if (self.flags & FL_SWIM) - self.flags = self.flags - FL_SWIM; - - if (!self.target) - return; - - activator = self.enemy; - SUB_UseTargets (); -} - - -void() monsterinwall = -{ - entity e; - if (!autocvar_developer) - return; - // this is handy for level designers, - // puts a spikey ball where the error is... - e = spawn(); - setorigin(e, self.origin); - setmodel (e, "models/ebomb.mdl"); - e.movetype = MOVETYPE_NONE; - e.solid = SOLID_NOT; - e.think = func_null; - e.nextthink = -1; - e.scale = 16; -} - -//============================================================================ - -void() walkmonster_start_go = -{ - self.origin_z = self.origin_z + 1; // raise off floor a bit - - tracebox(self.origin, self.mins, self.maxs, self.origin, TRUE, self); - if (trace_startsolid) - { - dprint("walkmonster in wall at: "); - dprint(vtos(self.origin)); - dprint("\n"); - monsterinwall(); - droptofloor(); - } - else - { - droptofloor(); - if (!walkmove(0,0)) - { - dprint("walkmonster in wall at: "); - dprint(vtos(self.origin)); - dprint("\n"); - monsterinwall(); - } - } - - //self.cantrigger = TRUE; - - self.takedamage = DAMAGE_AIM; - - self.ideal_yaw = self.angles * '0 1 0'; - if (!self.yaw_speed) - self.yaw_speed = 20; - self.view_ofs = '0 0 25'; - self.use = monster_use; - - self.flags = self.flags | FL_MONSTER; - - if (monsterwander) - self.spawnflags = self.spawnflags | MONSTER_WANDER; - - if (self.target) - { - self.goalentity = self.movetarget = find(world, targetname, self.target); - self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); - if (!self.movetarget) - { - dprint("Monster can't find target at "); - dprint(vtos(self.origin)); - dprint("\n"); - } - // this used to be an objerror - if (self.movetarget.classname == "path_corner") - self.th_walk (); - else - { - if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp")) - { - monster_spawnwanderpath(); - self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); - self.th_walk (); - } - else - { - self.pausetime = 99999999; - self.th_stand (); - } - } - } - else - { - if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp")) - { - monster_spawnwanderpath(); - self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); - self.th_walk (); - } - else - { - self.pausetime = 99999999; - self.th_stand (); - } - } - -// spread think times so they don't all happen at same time - self.nextthink = self.nextthink + random()*0.5 + 0.1; - self.iscreature = TRUE; - self.teleportable = TELEPORT_NORMAL; - self.damagedbycontents = TRUE; - - force_retouch = 2; // mainly to detect teleports - - monster_appearsetup(); -} - - -void() walkmonster_start = -{ - self.candrown = 1; // this is turned off by some monsters like zombies - // delay drop to floor to make sure all doors have been spawned - // spread think times so they don't all happen at same time - self.nextthink = time + random()*0.5 + 0.3; - self.think = walkmonster_start_go; - total_monsters = total_monsters + 1; - self.bot_attack = TRUE; - self.frags = 2; // actually just used to get havocbots to attack it... - self.bleedfunc = genericbleedfunc; - self.ismonster = TRUE; - - monster_setalpha (0); -} - - - -void() flymonster_start_go = -{ - self.takedamage = DAMAGE_AIM; - - self.ideal_yaw = self.angles * '0 1 0'; - if (!self.yaw_speed) - self.yaw_speed = 10; - self.view_ofs = '0 0 25'; - self.use = monster_use; - - self.flags = self.flags | FL_FLY; - self.flags = self.flags | FL_MONSTER; - - if (!walkmove(0,0)) - { - dprint("flymonster in wall at: "); - dprint(vtos(self.origin)); - dprint("\n"); - monsterinwall(); - } - - //self.cantrigger = TRUE; - - if (monsterwander) - self.spawnflags = self.spawnflags | MONSTER_WANDER; - - if (self.target) - { - self.goalentity = self.movetarget = find(world, targetname, self.target); - if (!self.movetarget) - { - dprint("Monster can't find target at "); - dprint(vtos(self.origin)); - dprint("\n"); - } - // this used to be an objerror - if (self.movetarget.classname == "path_corner") - self.th_walk (); - else - { - if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp")) - { - monster_spawnwanderpath(); - self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); - self.th_walk (); - } - else - { - self.pausetime = 99999999; - self.th_stand (); - } - } - } - else - { - if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp")) - { - monster_spawnwanderpath(); - self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); - self.th_walk (); - } - else - { - self.pausetime = 99999999; - self.th_stand (); - } - } - self.iscreature = TRUE; - self.teleportable = TELEPORT_NORMAL; - self.damagedbycontents = TRUE; - - force_retouch = 2; // mainly to detect teleports - - monster_appearsetup(); -} - -void() flymonster_start = -{ - self.candrown = 1; - // spread think times so they don't all happen at same time - self.nextthink = time + random()*0.5 + 0.1; - self.think = flymonster_start_go; - total_monsters = total_monsters + 1; - self.bot_attack = TRUE; - self.frags = 2; // actually just used to get havocbots to attack it... - self.bleedfunc = genericbleedfunc; - self.ismonster = TRUE; - - monster_setalpha (0); -} - - -void() swimmonster_start_go = -{ - if (deathmatch) - { - remove(self); - return; - } - - //self.cantrigger = TRUE; - - self.takedamage = DAMAGE_AIM; - - self.ideal_yaw = self.angles * '0 1 0'; - if (!self.yaw_speed) - self.yaw_speed = 10; - self.view_ofs = '0 0 10'; - self.use = monster_use; - - self.flags = self.flags | FL_SWIM; - self.flags = self.flags | FL_MONSTER; - - if (monsterwander) - self.spawnflags = self.spawnflags | MONSTER_WANDER; - - if (self.target) - { - self.goalentity = self.movetarget = find(world, targetname, self.target); - if (!self.movetarget) - { - dprint("Monster can't find target at "); - dprint(vtos(self.origin)); - dprint("\n"); - } - // this used to be an objerror - if (self.movetarget.classname == "path_corner") - self.th_walk (); - else - { - if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp")) - { - monster_spawnwanderpath(); - self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); - self.th_walk (); - } - else - { - self.pausetime = 99999999; - self.th_stand (); - } - } - } - else - { - if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp")) - { - monster_spawnwanderpath(); - self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); - self.th_walk (); - } - else - { - self.pausetime = 99999999; - self.th_stand (); - } - } - self.iscreature = TRUE; - self.teleportable = TELEPORT_NORMAL; - self.damagedbycontents = TRUE; - - force_retouch = 2; // mainly to detect teleports - - monster_appearsetup(); -} - -void() swimmonster_start = -{ - // spread think times so they don't all happen at same time - self.candrown = 0; - self.nextthink = time + random()*0.5 + 0.1; - self.think = swimmonster_start_go; - total_monsters = total_monsters + 1; - self.bot_attack = TRUE; - self.frags = 2; // actually just used to get havocbots to attack it... - self.bleedfunc = genericbleedfunc; - self.ismonster = TRUE; - - monster_setalpha(0); -} - -void(vector org, float bodydamage, float armordamage, vector force, float damgtype) genericbleedfunc = -{ - vector v; - v = '0 0 0' - force * 0.05; - if (armordamage > 0) - te_spark(org, v, armordamage * 3); - if (bodydamage > 0) - te_blood(org, v, bodydamage); -} diff --git a/qcsrc/server/attic/monsters/monster_zombie.qc b/qcsrc/server/attic/monsters/monster_zombie.qc deleted file mode 100644 index eb1105b93..000000000 --- a/qcsrc/server/attic/monsters/monster_zombie.qc +++ /dev/null @@ -1,575 +0,0 @@ -//#define MONSTES_ENABLED -#ifdef MONSTES_ENABLED - -float autocvar_g_monster_zombie_attack_run_damage; -float autocvar_g_monster_zombie_attack_run_delay; -float autocvar_g_monster_zombie_attack_run_force; -float autocvar_g_monster_zombie_attack_run_hitrange; -float autocvar_g_monster_zombie_attack_run_range; -float autocvar_g_monster_zombie_attack_stand_damage; -float autocvar_g_monster_zombie_attack_stand_delay; -float autocvar_g_monster_zombie_attack_stand_force; -float autocvar_g_monster_zombie_attack_stand_range; -float autocvar_g_monster_zombie_health; -float autocvar_g_monster_zombie_idle_timer_max; -float autocvar_g_monster_zombie_idle_timer_min; -float autocvar_g_monster_zombie_movespeed; -float autocvar_g_monster_zombie_respawntime; -float autocvar_g_monster_zombie_stopspeed; -float autocvar_g_monster_zombie_targetrange; -float autocvar_g_monster_zombie_turnspeed; -float autocvar_g_monsters; - - -#define zombie_anim_attackleap 0 -#define zombie_anim_attackrun1 1 -#define zombie_anim_attackrun2 2 -#define zombie_anim_attackrun3 3 -#define zombie_anim_attackstanding1 4 -#define zombie_anim_attackstanding2 5 -#define zombie_anim_attackstanding3 6 -#define zombie_anim_blockend 7 -#define zombie_anim_blockstart 8 -#define zombie_anim_deathback1 9 -#define zombie_anim_deathback2 10 -#define zombie_anim_deathback3 11 -#define zombie_anim_deathfront1 12 -#define zombie_anim_deathfront2 13 -#define zombie_anim_deathfront3 14 -#define zombie_anim_deathleft1 15 -#define zombie_anim_deathleft2 16 -#define zombie_anim_deathright1 17 -#define zombie_anim_deathright2 18 -#define zombie_anim_idle 19 -#define zombie_anim_painback1 20 -#define zombie_anim_painback2 21 -#define zombie_anim_painfront1 22 -#define zombie_anim_painfront2 23 -#define zombie_anim_runbackwards 24 -#define zombie_anim_runbackwardsleft 25 -#define zombie_anim_runbackwardsright 26 -#define zombie_anim_runforward 27 -#define zombie_anim_runforwardleft 28 -#define zombie_anim_runforwardright 29 -#define zombie_anim_spawn 30 - -#define ZOMBIE_MIN '-18 -18 -25' -#define ZOMBIE_MAX '18 18 47' - -#define ZV_IDLE 10 - -#define ZV_PATH 100 -#define ZV_HUNT 200 - -#define ZV_ATTACK_FIND 10 -#define ZV_ATTACK_RUN 20 -#define ZV_ATTACK_STAND 30 - -#define ZV_PATH2 10000 - -//.entity verbs_idle; -//.entity verbs_attack; -//.entity verbs_move; - -//.float state_timeout; -//.void() monster_state; -#define MONSTERFLAG_NORESPAWN 2 - -void zombie_spawn(); - -float zombie_scoretarget(entity trg) -{ - float tmp; - vector ang1; - - if (trg.takedamage == DAMAGE_AIM) - if not (trg.flags & FL_NOTARGET) - if (trg.deadflag == DEAD_NO) - if (trg.team != self.team) - { - if((self.origin_z - trg.origin_z) < 128) - { - ang1 = normalize(self.origin - trg.origin); - tmp = vlen(ang1 - v_forward); - if(tmp > 1.5) - { - traceline(self.origin + '0 0 47',trg.origin + '0 0 32',MOVE_NORMAL,self); - if(trace_ent != trg) - return 0; - - return (autocvar_g_monster_zombie_targetrange - vlen(self.origin - trg.origin)) * tmp; - } - else if(self.enemy == trg) - return (autocvar_g_monster_zombie_targetrange - vlen(self.origin - trg.origin)) * tmp; - } - } - - return 0; -} - -void zombie_corpse_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) -{ - //dprint("zombie_corpse_damage\n"); - Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, self, attacker); - - self.health -= damage; - - if(self.health < 0) - { - Violence_GibSplash(self, 1, 1, attacker); - remove(self); - } -} - -void zombie_die(vector dir) -{ - vector v; - float f; - - entity dummy; - - dummy = spawn(); - setmodel(dummy,"models/monsters/zombie.dpm"); - setorigin(dummy, self.origin); - dummy.velocity = self.velocity; - dummy.movetype = MOVETYPE_BOUNCE; - dummy.think = SUB_Remove; - dummy.nextthink = time + 3; - dummy.health = 50; - dummy.takedamage = DAMAGE_YES; - dummy.event_damage = zombie_corpse_damage; - dummy.solid = SOLID_CORPSE; - setsize(dummy,self.mins,self.maxs); - - SUB_SetFade(dummy,time + 5,2); - - - v = normalize(self.origin - dir); - f = vlen(v_forward - v) - 1; - if(f > 0.5) - dummy.frame = zombie_anim_deathfront1 + rint(random() * 2); - else if(f < 0.5) - dummy.frame = zombie_anim_deathback1 + rint(random() * 2); - else - { - f = vlen(v_right - v) - 1; - if(f > 0.5) - dummy.frame = zombie_anim_deathright1 + rint(random() * 2); - else if(f < 0.5) - dummy.frame = zombie_anim_deathleft1 + rint(random() * 2); - } - - - if(self.spawnflags & MONSTERFLAG_NORESPAWN) - { - self.think = SUB_Remove; - self.nextthink = time; - return; - } - - setmodel(self,""); - self.solid = SOLID_NOT; - self.takedamage = DAMAGE_NO; - self.event_damage = func_null; - self.enemy = world; - self.think = zombie_spawn; - self.nextthink = time + autocvar_g_monster_zombie_respawntime; - self.pain_finished = self.nextthink; -} - -void zombie_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) -{ - - vector v; - float f; - - v = normalize(self.origin - hitloc); - f = vlen(v_forward - v) - 1; - - - self.health -= damage; - self.velocity = self.velocity + force; - if(self.health <= 0) - { - zombie_die(hitloc); - return; - } - - Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, self, attacker); - - if (damage > 50) - Violence_GibSplash_At(hitloc, force * -0.1, 3, 1, self, attacker); - if (damage > 100) - Violence_GibSplash_At(hitloc, force * -0.2, 3, 1, self, attacker); - - if (time > self.pain_finished) - { - if(f < 0.5) - { - if(random() < 0.5) - self.frame = zombie_anim_painback1; - else - self.frame = zombie_anim_painback2; - } - else - { - if(random() < 0.5) - self.frame = zombie_anim_painfront1; - else - self.frame = zombie_anim_painfront2; - } - - self.pain_finished = time + 0.36; - } -} - -.vector bvec; -.float bvec_time; - -void zombie_move() -{ - vector real_angle; - float vz, tdiff, tspeed; - - tdiff = time - self.zoomstate; - tspeed = tdiff * autocvar_g_monster_zombie_turnspeed; - vz = self.velocity_z; - self.zoomstate = time; - - if(self.bvec_time < time) - { - self.bvec_time = time + 0.2; - self.bvec = steerlib_beamsteer(steerlib_attract2(self.moveto,0.5,500,0.95),512,32,34,64); - } - - if(self.enemy) - self.moveto = self.enemy.origin; - else - self.moveto = self.origin + v_forward; - - self.steerto = normalize(steerlib_attract2(self.moveto,0.5,500,0.95) + self.bvec); - - self.angles_y = safeangle(self.angles_y); - real_angle = vectoangles(self.steerto) - self.angles; - self.angles_y += bound(-10, real_angle_y, 10); - - if(vlen(self.origin - self.moveto) > 64) - { - movelib_move_simple(v_forward ,autocvar_g_monster_zombie_movespeed,0.6); - if(time > self.pain_finished) - if(self.attack_finished_single < time) - self.frame = zombie_anim_runforward; - } - else - { - movelib_beak_simple(autocvar_g_monster_zombie_stopspeed); - if(time > self.pain_finished) - if(self.attack_finished_single < time) - self.frame = zombie_anim_idle; - } - - self.velocity_z = vz; - self.steerto = self.origin; -} - -float zombie_verb_idle_roam(float eval) -{ - switch (eval) - { - case VCM_EVAL: - - if(self.enemy) - return VS_CALL_NO; - - return verb.verb_static_value; - - case VCM_DO: - - self.moveto = v_forward * 128; - self.steerto = v_forward; //steerlib_beamsteer(v_forward,512,32,34,64); - - return VS_CALL_YES_DOING; - } - - return VS_CALL_YES_DONE; -} - -float zombie_verb_idle_stand(float eval) -{ - switch (eval) - { - case VCM_EVAL: - - if(self.enemy) - return VS_CALL_NO; - - return verb.verb_static_value; - - case VCM_DO: - - self.moveto = self.origin; - self.frame = zombie_anim_idle; - self.velocity = '0 0 0'; - - return VS_CALL_YES_DOING; - } - - return VS_CALL_YES_DONE; -} - -float zombie_verb_idle(float eval) -{ - switch (eval) - { - case VCM_EVAL: - - if(self.enemy) - return VS_CALL_NO; - - return verb.verb_static_value; - - case VCM_DO: - float t; - - t = autocvar_g_monster_zombie_idle_timer_max - autocvar_g_monster_zombie_idle_timer_min; - t = autocvar_g_monster_zombie_idle_timer_min + (random() * t); - - if(random() < 0.5) - verbstack_push(self.verbs_idle, zombie_verb_idle_roam, ZV_IDLE + 1, t, self); - else - verbstack_push(self.verbs_idle, zombie_verb_idle_stand, ZV_IDLE + 1, 0.1, self); - - return VS_CALL_YES_DOING; - } - - return VS_CALL_YES_DONE; -} - -float zombie_verb_attack_findtarget(float eval) -{ - switch (eval) - { - case VCM_EVAL: - if(self.enemy) - return VS_CALL_NO; - - return verb.verb_static_value; - - case VCM_DO: - - entity trg, best_trg; - float trg_score, best_trg_score; - - trg = findradius(self.origin,autocvar_g_monster_zombie_targetrange); - while(trg) - { - trg_score = zombie_scoretarget(trg); - if(trg_score > best_trg_score) - { - best_trg = trg; - best_trg_score = trg_score; - } - - trg = trg.chain; - } - - if(best_trg) - { - self.enemy = best_trg; - dprint("Selected: ",best_trg.netname, " as target.\n"); - } - - return VS_CALL_YES_DOING; - } - - return VS_CALL_YES_DONE; -} - -void zombie_runattack_damage() -{ - entity oldself; - oldself = self; - self = self.owner; - - if(vlen(self.origin - self.enemy.origin) > autocvar_g_monster_zombie_attack_run_hitrange) - return; - - if(vlen(normalize(self.origin - self.enemy.origin) - v_forward) < 1.6) - return; - - Damage(self.enemy, self, self, autocvar_g_monster_zombie_attack_run_damage, DEATH_TURRET, self.enemy.origin, normalize(self.enemy.origin - self.origin) * autocvar_g_monster_zombie_attack_run_force); - - self = oldself; - self.think = SUB_Remove; - self.nextthink = time; -} - -float zombie_verb_attack_run(float eval) -{ - switch (eval) - { - case VCM_EVAL: - if not (self.enemy) - return VS_CALL_NO; - - if(self.attack_finished_single > time) - return VS_CALL_NO; - - if(vlen(self.origin - self.enemy.origin) > autocvar_g_monster_zombie_attack_run_range) - return VS_CALL_NO; - - if(vlen(normalize(self.origin - self.enemy.origin) - v_forward) < 1.6) - return VS_CALL_NO; - - return verb.verb_static_value; - - case VCM_DO: - entity pain; - pain = spawn(); - pain.owner = self; - pain.think = zombie_runattack_damage; - pain.nextthink = time + autocvar_g_monster_zombie_attack_run_delay; - - self.attack_finished_single = time + 0.7; - self.frame = zombie_anim_attackrun1 + rint(random() * 2); - - return VS_CALL_YES_DOING; - } - - return VS_CALL_YES_DONE; -} - -void zombie_standattack_damage() -{ - //entity oldself; - //oldself = self; - //self = self.owner; - - setorigin(self,self.owner.origin + v_forward * 32); - RadiusDamage(self, self.owner, autocvar_g_monster_zombie_attack_stand_damage,autocvar_g_monster_zombie_attack_stand_damage,16,self, autocvar_g_monster_zombie_attack_stand_force,DEATH_TURRET,world); - //float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype, entity directhitentity) - - - //self = oldself; - self.think = SUB_Remove; - self.nextthink = time; -} - -float zombie_verb_attack_stand(float eval) -{ - switch (eval) - { - case VCM_EVAL: - if not (self.enemy) - return VS_CALL_NO; - - if(self.attack_finished_single > time) - return VS_CALL_NO; - - if(vlen(self.origin - self.enemy.origin) > autocvar_g_monster_zombie_attack_stand_range) - return VS_CALL_NO; - - if(vlen(normalize(self.origin - self.enemy.origin) - v_forward) < 1.8) - return VS_CALL_NO; - - return verb.verb_static_value; - - case VCM_DO: - entity pain; - pain = spawn(); - pain.owner = self; - pain.think = zombie_runattack_damage; - pain.nextthink = time + autocvar_g_monster_zombie_attack_stand_delay; - - self.attack_finished_single = time + 0.7; - self.frame = zombie_anim_attackstanding1 + rint(random() * 1); - dprint("frame:",ftos(self.frame),"\n"); - - return VS_CALL_YES_DOING; - } - - return VS_CALL_YES_DONE; -} - -void zombie_think() -{ - self.angles_x *= -1; - makevectors(self.angles); - self.angles_x *= -1; - - if (zombie_scoretarget(self.enemy) == 0) - self.enemy = world; - - verbstack_pop(self.verbs_attack); - //verbstack_pop(self.verbs_move); - - if not (self.enemy) - verbstack_pop(self.verbs_idle); - - zombie_move(); - - if(self.enemy) - self.nextthink = time; - else - self.nextthink = time + 0.2; -} - -void zombie_spawn() -{ - setmodel(self,"models/monsters/zombie.dpm"); - - self.solid = SOLID_BBOX; - self.takedamage = DAMAGE_AIM; - self.event_damage = zombie_damage; - self.enemy = world; - self.frame = zombie_anim_spawn; - self.think = zombie_think; - self.nextthink = time + 2.1; - self.pain_finished = self.nextthink; - self.movetype = MOVETYPE_WALK; - self.health = autocvar_g_monster_zombie_health; - self.velocity = '0 0 0'; - self.angles = self.pos2; - self.moveto = self.origin; - self.flags = FL_MONSTER; - - setorigin(self,self.pos1); - setsize(self,ZOMBIE_MIN,ZOMBIE_MAX); -} - - -void spawnfunc_monster_zombie() -{ - if not(autocvar_g_monsters) - { - remove(self); - return; - } - - precache_model("models/monsters/zombie.dpm"); - - - self.verbs_idle = spawn(); - self.verbs_attack = spawn(); - - self.verbs_idle.owner = self; - self.verbs_attack.owner = self; - - self.think = zombie_spawn; - self.nextthink = time + 2; - - traceline(self.origin + '0 0 10', self.origin - '0 0 32', MOVE_WORLDONLY, self); - - self.pos1 = trace_endpos; - self.pos2 = self.angles; - self.team = MAX_SHOT_DISTANCE -1; - - verbstack_push(self.verbs_idle, zombie_verb_idle, ZV_IDLE,0 , self); - - verbstack_push(self.verbs_attack, zombie_verb_attack_findtarget, ZV_ATTACK_FIND,0 , self); - verbstack_push(self.verbs_attack, zombie_verb_attack_run, ZV_ATTACK_RUN,0 , self); - verbstack_push(self.verbs_attack, zombie_verb_attack_stand, ZV_ATTACK_STAND,0 , self); - -} - -#endif // MONSTES_ENABLED diff --git a/qcsrc/server/attic/nexball.qc b/qcsrc/server/attic/nexball.qc deleted file mode 100644 index dc9c91ce6..000000000 --- a/qcsrc/server/attic/nexball.qc +++ /dev/null @@ -1,741 +0,0 @@ -//EF_BRIGHTFIELD|EF_BRIGHTLIGHT|EF_DIMLIGHT|EF_BLUE|EF_RED|EF_FLAME -#define BALL_EFFECTMASK 1229 -#define BALL_MINS '-16 -16 -16' // The model is 24*24*24 -#define BALL_MAXS '16 16 16' -#define BALL_ATTACHORG '3 0 16' -#define BALL_SPRITECOLOR '.91 .85 .62' -#define BALL_FOOT 1 -#define BALL_BASKET 2 -//spawnflags -#define GOAL_TOUCHPLAYER 1 -//goal types -#define GOAL_FAULT -1 -#define GOAL_OUT -2 - -#define CVTOV(s) s = cvar( #s ) - -float g_nexball_football_boost_forward; -float g_nexball_football_boost_up; -float g_nexball_football_physics; -float g_nexball_delay_idle; -float g_nexball_basketball_delay_hold; -float g_nexball_basketball_delay_hold_forteam; -float g_nexball_basketball_effects_default; -float g_nexball_basketball_teamsteal; -float balls; -float ball_scale; -float nb_teams; - -.float teamtime; - -.float nb_dropperid; -.float nb_droptime; - -void nb_delayedinit(); -void nb_init() // Called early (worldspawn stage) -{ - CVTOV(g_nexball_meter_period); //sent with the client init entity - if (g_nexball_meter_period <= 0) - g_nexball_meter_period = 2; // avoid division by zero etc. due to silly users - g_nexball_meter_period = rint(g_nexball_meter_period * 32) / 32; //Round to 1/32ths to send as a byte multiplied by 32 - addstat(STAT_NB_METERSTART, AS_FLOAT, metertime); - - // General settings - CVTOV(g_nexball_football_boost_forward); //100 - CVTOV(g_nexball_football_boost_up); //200 - CVTOV(g_nexball_delay_idle); //10 - CVTOV(g_nexball_football_physics); //0 - - radar_showennemies = autocvar_g_nexball_radar_showallplayers; - - InitializeEntity(world, nb_delayedinit, INITPRIO_GAMETYPE); -} - -float OtherTeam(float t) //works only if there are two teams on the map! -{ - entity e; - e = find(world, classname, "nexball_team"); - if (e.team == t) - e = find(e, classname, "nexball_team"); - return e.team; -} - -void ResetBall(); - -void LogNB(string mode, entity actor) -{ - string s; - if(!autocvar_sv_eventlog) - return; - s = strcat(":nexball:", mode); - if(actor != world) - s = strcat(s, ":", ftos(actor.playerid)); - GameLogEcho(s); -} - -void ball_restart (void) -{ - if(self.owner) - DropBall(self, self.owner.origin, '0 0 0'); - ResetBall(); -} - -void nexball_setstatus (void) -{ - entity oldself; - self.items &~= IT_KEY1; - if (self.ballcarried) - { - if (self.ballcarried.teamtime && (self.ballcarried.teamtime < time)) - { - bprint("The ", ColoredTeamName(self.team), " held the ball for too long.\n"); - oldself = self; - self = self.ballcarried; - DropBall(self, self.owner.origin, '0 0 0'); - ResetBall(); - self = oldself; - } else - self.items |= IT_KEY1; - } -} - -void relocate_nexball (void) -{ - tracebox(self.origin, BALL_MINS, BALL_MAXS, self.origin, TRUE, self); - if (trace_startsolid) - { - vector o; - o = self.origin; - if(!move_out_of_solid(self)) - objerror("could not get out of solid at all!"); - print("^1NOTE: this map needs FIXING. ", self.classname, " at ", vtos(o - '0 0 1')); - print(" needs to be moved out of solid, e.g. by '", ftos(self.origin_x - o_x)); - print(" ", ftos(self.origin_y - o_y)); - print(" ", ftos(self.origin_z - o_z), "'\n"); - self.origin = o; - } -} - -void basketball_touch(); -void football_touch(); - -void DropOwner (void) -{ - entity ownr; - ownr = self.owner; - DropBall(self, ownr.origin, ownr.velocity); - makevectors(ownr.v_angle_y * '0 1 0'); - ownr.velocity += ('0 0 0.75' - v_forward) * 1000; - ownr.flags &~= FL_ONGROUND; -} - -void GiveBall (entity plyr, entity ball) -{ - entity ownr; - - if ((ownr = ball.owner)) - { - ownr.effects &~= g_nexball_basketball_effects_default; - ownr.ballcarried = world; - if (ownr.metertime) - { - ownr.metertime = 0; - ownr.weaponentity.state = WS_READY; - } - WaypointSprite_Kill(ownr.waypointsprite_attachedforcarrier); - } - else - { - WaypointSprite_Kill(ball.waypointsprite_attachedforcarrier); - } - - setattachment(ball, plyr, ""); - setorigin(ball, BALL_ATTACHORG); - - if (ball.team != plyr.team) - ball.teamtime = time + g_nexball_basketball_delay_hold_forteam; - - ball.owner = ball.pusher = plyr; //"owner" is set to the player carrying, "pusher" to the last player who touched it - ball.team = plyr.team; - plyr.ballcarried = ball; - ball.nb_dropperid = plyr.playerid; - - plyr.effects |= g_nexball_basketball_effects_default; - ball.effects &~= g_nexball_basketball_effects_default; - - ball.velocity = '0 0 0'; - ball.movetype = MOVETYPE_NONE; - ball.touch = func_null; - ball.effects |= EF_NOSHADOW; - ball.scale = 1; // scale down. - - WaypointSprite_AttachCarrier("nb-ball", plyr, RADARICON_FLAGCARRIER, BALL_SPRITECOLOR); - WaypointSprite_UpdateRule(plyr.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT); - - if (g_nexball_basketball_delay_hold) - { - ball.think = DropOwner; - ball.nextthink = time + g_nexball_basketball_delay_hold; - } -} - -void DropBall (entity ball, vector org, vector vel) -{ - ball.effects |= g_nexball_basketball_effects_default; - ball.effects &~= EF_NOSHADOW; - ball.owner.effects &~= g_nexball_basketball_effects_default; - - setattachment(ball, world, ""); - setorigin (ball, org); - ball.movetype = MOVETYPE_BOUNCE; - ball.flags &~= FL_ONGROUND; - ball.scale = ball_scale; - ball.velocity = vel; - ball.nb_droptime = time; - ball.touch = basketball_touch; - ball.think = ResetBall; - ball.nextthink = min(time + g_nexball_delay_idle, ball.teamtime); - - if (ball.owner.metertime) - { - ball.owner.metertime = 0; - ball.owner.weaponentity.state = WS_READY; - } - - WaypointSprite_Kill(ball.owner.waypointsprite_attachedforcarrier); - WaypointSprite_Spawn("nb-ball", 0, 0, ball, '0 0 64', world, ball.team, ball, waypointsprite_attachedforcarrier, FALSE, RADARICON_FLAGCARRIER, BALL_SPRITECOLOR); // no health bar please - WaypointSprite_UpdateRule(ball.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT); - - ball.owner.ballcarried = world; - ball.owner = world; -} - -void InitBall (void) -{ - if (gameover) return; - self.flags &~= FL_ONGROUND; - self.movetype = MOVETYPE_BOUNCE; - if (self.classname == "nexball_basketball") - self.touch = basketball_touch; - else if (self.classname == "nexball_football") - self.touch = football_touch; - self.cnt = 0; - self.think = ResetBall; - self.nextthink = time + g_nexball_delay_idle + 3; - self.teamtime = 0; - self.pusher = world; - self.team = FALSE; - sound (self, CH_TRIGGER, self.noise1, VOL_BASE, ATTN_NORM); - WaypointSprite_Ping(self.waypointsprite_attachedforcarrier); - LogNB("init", world); -} - -void ResetBall (void) -{ - if (self.cnt < 2) { // step 1 - if (time == self.teamtime) - bprint("The ", ColoredTeamName(self.team), " held the ball for too long.\n"); - self.touch = func_null; - self.movetype = MOVETYPE_NOCLIP; - self.velocity = '0 0 0'; // just in case? - if(!self.cnt) - LogNB("resetidle", world); - self.cnt = 2; - self.nextthink = time; - } else if (self.cnt < 4) { // step 2 and 3 -// dprint("Step ", ftos(self.cnt), ": Calculated velocity: ", vtos(self.spawnorigin - self.origin), ", time: ", ftos(time), "\n"); - self.velocity = (self.spawnorigin - self.origin) * (self.cnt - 1); // 1 or 0.5 second movement - self.nextthink = time + 0.5; - self.cnt += 1; - } else { // step 4 -// dprint("Step 4: time: ", ftos(time), "\n"); - if (vlen(self.origin - self.spawnorigin) > 10) // should not happen anymore - dprint("The ball moved too far away from its spawn origin.\nOffset: ", - vtos(self.origin - self.spawnorigin), " Velocity: ", vtos(self.velocity), "\n"); - self.velocity = '0 0 0'; - setorigin(self, self.spawnorigin); // make sure it's positioned correctly anyway - self.movetype = MOVETYPE_NONE; - self.think = InitBall; - self.nextthink = max(time, game_starttime) + autocvar_g_nexball_delay_start; - } -} - -void football_touch (void) -{ - if (other.solid == SOLID_BSP) { - if (time > self.lastground + 0.1) - { - sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NORM); - self.lastground = time; - } - if (vlen(self.velocity) && !self.cnt) - self.nextthink = time + g_nexball_delay_idle; - return; - } - if (other.classname != "player") - return; - if (other.health < 1) - return; - if (!self.cnt) - self.nextthink = time + g_nexball_delay_idle; - - self.pusher = other; - self.team = other.team; - - if (g_nexball_football_physics == -1) { // MrBougo try 1, before decompiling Rev's original - if (vlen(other.velocity)) - self.velocity = other.velocity * 1.5 + '0 0 1' * g_nexball_football_boost_up; - } else if (g_nexball_football_physics == 1) { // MrBougo's modded Rev style: partially independant of the height of the aiming point - makevectors(other.v_angle); - self.velocity = other.velocity + v_forward * g_nexball_football_boost_forward + '0 0 1' * g_nexball_football_boost_up; - } else if (g_nexball_football_physics == 2) { // 2nd mod try: totally independant. Really playable! - makevectors(other.v_angle_y * '0 1 0'); - self.velocity = other.velocity + v_forward * g_nexball_football_boost_forward + v_up * g_nexball_football_boost_up; - } else { // Revenant's original style (from the original mod's disassembly, acknowledged by Revenant) - makevectors(other.v_angle); - self.velocity = other.velocity + v_forward * g_nexball_football_boost_forward + v_up * g_nexball_football_boost_up; - } - self.avelocity = -250 * v_forward; // maybe there is a way to make it look better? -} - -void basketball_touch (void) -{ - if (other.ballcarried) - { - football_touch(); - return; - } - if (!self.cnt && other.classname == "player" && (other.playerid != self.nb_dropperid || time > self.nb_droptime + autocvar_g_nexball_delay_collect)) { - if (other.health <= 0) - return; - LogNB("caught", other); - GiveBall(other, self); - } else if (other.solid == SOLID_BSP) { - sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NORM); - if (vlen(self.velocity) && !self.cnt) - self.nextthink = min(time + g_nexball_delay_idle, self.teamtime); - } -} - -void GoalTouch (void) -{ - entity ball; - float isclient, pscore, otherteam; - string pname; - - if (gameover) return; - if ((self.spawnflags & GOAL_TOUCHPLAYER) && other.ballcarried) - ball = other.ballcarried; - else - ball = other; - if (ball.classname != "nexball_basketball") - if (ball.classname != "nexball_football") - return; - if ((!ball.pusher && self.team != GOAL_OUT) || ball.cnt) - return; - EXACTTRIGGER_TOUCH; - - - if(nb_teams == 2) - otherteam = OtherTeam(ball.team); - - if((isclient = ball.pusher.flags & FL_CLIENT)) - pname = ball.pusher.netname; - else - pname = "Someone (?)"; - - if (ball.team == self.team) //owngoal (regular goals) - { - LogNB("owngoal", ball.pusher); - bprint("Boo! ", pname, "^7 scored a goal against their own team!\n"); - pscore = -1; - } else if (self.team == GOAL_FAULT) { - LogNB("fault", ball.pusher); - if (nb_teams == 2) - bprint(ColoredTeamName(otherteam), " gets a point due to ", pname, "^7's silliness.\n"); - else - bprint(ColoredTeamName(ball.team), " loses a point due to ", pname, "^7's silliness.\n"); - pscore = -1; - } else if (self.team == GOAL_OUT) { - LogNB("out", ball.pusher); - if ((self.spawnflags & GOAL_TOUCHPLAYER) && ball.owner) - bprint(pname, "^7 went out of bounds.\n"); - else - bprint("The ball was returned.\n"); - pscore = 0; - } else { //score - LogNB(strcat("goal:", ftos(self.team)), ball.pusher); - bprint("Goaaaaal! ", pname, "^7 scored a point for the ", ColoredTeamName(ball.team), ".\n"); - pscore = 1; - } - - sound (ball, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NONE); - - if(ball.team && pscore) - { - if (nb_teams == 2 && pscore < 0) - TeamScore_AddToTeam(otherteam, ST_NEXBALL_GOALS, -pscore); - else - TeamScore_AddToTeam(ball.team, ST_NEXBALL_GOALS, pscore); - } - if (isclient) - { - if (pscore > 0) - PlayerScore_Add(ball.pusher, SP_NEXBALL_GOALS, pscore); - else if (pscore < 0) - PlayerScore_Add(ball.pusher, SP_NEXBALL_FAULTS, -pscore); - } - - if (ball.owner) // Happens on spawnflag GOAL_TOUCHPLAYER - DropBall(ball, ball.owner.origin, ball.owner.velocity); - - WaypointSprite_Ping(ball.waypointsprite_attachedforcarrier); - - ball.cnt = 1; - ball.think = ResetBall; - if (ball.classname == "nexball_basketball") - ball.touch = football_touch; // better than func_null: football control until the ball gets reset - ball.nextthink = time + autocvar_g_nexball_delay_goal * (self.team != GOAL_OUT); -} - -//=======================// -// team ents // -//=======================// -void spawnfunc_nexball_team (void) -{ - if(!g_nexball) { remove(self); return; } - self.team = self.cnt + 1; -} - -void nb_spawnteam (string teamname, float teamcolor) -{ - dprint("^2spawned team ", teamname, "\n"); - entity e; - e = spawn(); - e.classname = "nexball_team"; - e.netname = teamname; - e.cnt = teamcolor; - e.team = e.cnt + 1; - nb_teams += 1; -} - -void nb_spawnteams (void) -{ - float t_r, t_b, t_y, t_p; - entity e; - for(e = world; (e = find(e, classname, "nexball_goal")); ) - { - switch(e.team) - { - case NUM_TEAM_1: if(!t_r) { nb_spawnteam ("Red", e.team-1) ; t_r = 1; } break; - case NUM_TEAM_2: if(!t_b) { nb_spawnteam ("Blue", e.team-1) ; t_b = 1; } break; - case NUM_TEAM_3: if(!t_y) { nb_spawnteam ("Yellow", e.team-1); t_y = 1; } break; - case NUM_TEAM_4: if(!t_p) { nb_spawnteam ("Pink", e.team-1) ; t_p = 1; } break; - } - } -} - -void nb_delayedinit (void) -{ - if (find(world, classname, "nexball_team") == world) - nb_spawnteams(); - ScoreRules_nexball(nb_teams); -} - - -//=======================// -// spawnfuncs // -//=======================// - -void SpawnBall (void) -{ - if(!g_nexball) { remove(self); return; } - -// balls += 4; // using the remaining bits to count balls will leave more than the max edict count, so it's fine - - if (!self.model) { - self.model = "models/nexball/ball.md3"; - self.scale = 1.3; - } - - precache_model (self.model); - setmodel (self, self.model); - setsize (self, BALL_MINS, BALL_MAXS); - ball_scale = self.scale; - - relocate_nexball(); - self.spawnorigin = self.origin; - - self.effects = self.effects | EF_LOWPRECISION; - - if (cvar(strcat("g_", self.classname, "_trail"))) //nexball_basketball :p - { - self.glow_color = autocvar_g_nexball_trail_color; - self.glow_trail = TRUE; - } - - self.movetype = MOVETYPE_FLY; - - if (!autocvar_g_nexball_sound_bounce) - self.noise = ""; - else if (!self.noise) - self.noise = "sound/nexball/bounce.wav"; - //bounce sound placeholder (FIXME) - if (!self.noise1) - self.noise1 = "sound/nexball/drop.wav"; - //ball drop sound placeholder (FIXME) - if (!self.noise2) - self.noise2 = "sound/nexball/steal.wav"; - //stealing sound placeholder (FIXME) - if (self.noise) precache_sound (self.noise); - precache_sound (self.noise1); - precache_sound (self.noise2); - - WaypointSprite_AttachCarrier("nb-ball", self, RADARICON_FLAGCARRIER, BALL_SPRITECOLOR); // the ball's team is not set yet, no rule update needed - - self.reset = ball_restart; - self.think = InitBall; - self.nextthink = game_starttime + autocvar_g_nexball_delay_start; -} - -void spawnfunc_nexball_basketball (void) -{ - self.classname = "nexball_basketball"; - if not(balls & BALL_BASKET) - { - CVTOV(g_nexball_basketball_effects_default); - CVTOV(g_nexball_basketball_delay_hold); - CVTOV(g_nexball_basketball_delay_hold_forteam); - CVTOV(g_nexball_basketball_teamsteal); - g_nexball_basketball_effects_default = g_nexball_basketball_effects_default & BALL_EFFECTMASK; - } - if (!self.effects) - self.effects = g_nexball_basketball_effects_default; - self.solid = SOLID_TRIGGER; - balls |= BALL_BASKET; - self.bouncefactor = autocvar_g_nexball_basketball_bouncefactor; - self.bouncestop = autocvar_g_nexball_basketball_bouncestop; - SpawnBall(); -} - -void spawnfunc_nexball_football (void) -{ - self.classname = "nexball_football"; - self.solid = SOLID_TRIGGER; - balls |= BALL_FOOT; - self.bouncefactor = autocvar_g_nexball_football_bouncefactor; - self.bouncestop = autocvar_g_nexball_football_bouncestop; - SpawnBall(); -} - -void SpawnGoal (void) -{ - if(!g_nexball) { remove(self); return; } - EXACTTRIGGER_INIT; - self.classname = "nexball_goal"; - if (!self.noise) - self.noise = "ctf/respawn.wav"; - precache_sound(self.noise); - self.touch = GoalTouch; -} - -void spawnfunc_nexball_redgoal (void) -{ - self.team = NUM_TEAM_1; - SpawnGoal(); -} -void spawnfunc_nexball_bluegoal (void) -{ - self.team = NUM_TEAM_2; - SpawnGoal(); -} -void spawnfunc_nexball_yellowgoal (void) -{ - self.team = NUM_TEAM_3; - SpawnGoal(); -} -void spawnfunc_nexball_pinkgoal (void) -{ - self.team = NUM_TEAM_4; - SpawnGoal(); -} - -void spawnfunc_nexball_fault (void) -{ - self.team = GOAL_FAULT; - if (!self.noise) - self.noise = "misc/typehit.wav"; - SpawnGoal(); -} - -void spawnfunc_nexball_out (void) -{ - self.team = GOAL_OUT; - if (!self.noise) - self.noise = "misc/typehit.wav"; - SpawnGoal(); -} - -// -//Spawnfuncs preserved for compatibility -// - -void spawnfunc_ball (void) { spawnfunc_nexball_football(); } -void spawnfunc_ball_football (void) { spawnfunc_nexball_football(); } -void spawnfunc_ball_basketball (void) { spawnfunc_nexball_basketball(); } -// The "red goal" is defended by blue team. A ball in there counts as a point for red. -void spawnfunc_ball_redgoal (void) { spawnfunc_nexball_bluegoal(); } // I blame Revenant -void spawnfunc_ball_bluegoal (void) { spawnfunc_nexball_redgoal(); } // but he didn't mean to cause trouble :p -void spawnfunc_ball_fault (void) { spawnfunc_nexball_fault(); } -void spawnfunc_ball_bound (void) { spawnfunc_nexball_out(); } - -//=======================// -// Weapon code // -//=======================// - -void W_Nexball_Touch (void) -{ - entity ball, attacker; - attacker = self.owner; - - PROJECTILE_TOUCH; - if(attacker.team != other.team || g_nexball_basketball_teamsteal) - if((ball = other.ballcarried) && (attacker.classname == "player")) - { - other.velocity = other.velocity + normalize(self.velocity) * other.damageforcescale * autocvar_g_balance_nexball_secondary_force; - other.flags &~= FL_ONGROUND; - if(!attacker.ballcarried) - { - LogNB("stole", attacker); - sound (other, CH_TRIGGER, ball.noise2, VOL_BASE, ATTN_NORM); - - if(attacker.team == other.team && time > attacker.teamkill_complain) - { - attacker.teamkill_complain = time + 5; - attacker.teamkill_soundtime = time + 0.4; - attacker.teamkill_soundsource = other; - } - - GiveBall(attacker, other.ballcarried); - } - } - remove(self); -} - -void W_Nexball_Attack (float t) -{ - entity ball; - float mul, mi, ma; - if (!(ball = self.ballcarried)) - return; - - W_SetupShot (self, FALSE, 4, "nexball/shoot1.wav", CH_WEAPON_A, 0); - tracebox(w_shotorg, BALL_MINS, BALL_MAXS, w_shotorg, MOVE_WORLDONLY, world); - if(trace_startsolid) - { - if(self.metertime) - self.metertime = 0; // Shot failed, hide the power meter - return; - } - - //Calculate multiplier - if (t < 0) - mul = 1; - else - { - mi = autocvar_g_nexball_basketball_meter_minpower; - ma = max(mi, autocvar_g_nexball_basketball_meter_maxpower); // avoid confusion - //One triangle wave period with 1 as max - mul = 2 * mod(t, g_nexball_meter_period) / g_nexball_meter_period; - if (mul > 1) - mul = 2 - mul; - mul = mi + (ma - mi) * mul; // range from the minimal power to the maximal power - } - DropBall (ball, w_shotorg, W_CalculateProjectileVelocity(self.velocity, w_shotdir * autocvar_g_balance_nexball_primary_speed * mul, FALSE)); - //TODO: use the speed_up cvar too ?? -} - -void W_Nexball_Attack2 (void) -{ - entity missile; - if (!(balls & BALL_BASKET)) - return; - W_SetupShot (self, FALSE, 2, "nexball/shoot2.wav", CH_WEAPON_A, 0); -// pointparticles(particleeffectnum("grenadelauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1); - missile = spawn (); - - missile.owner = self; - missile.classname = "ballstealer"; - - missile.movetype = MOVETYPE_FLY; - PROJECTILE_MAKETRIGGER(missile); - - setmodel (missile, "models/elaser.mdl"); // precision set below - setsize (missile, '0 0 0', '0 0 0'); - setorigin (missile, w_shotorg); - - W_SetupProjectileVelocity(missile, autocvar_g_balance_nexball_secondary_speed, 0); - missile.angles = vectoangles (missile.velocity); - missile.touch = W_Nexball_Touch; - missile.think = SUB_Remove; - missile.nextthink = time + autocvar_g_balance_nexball_secondary_lifetime; //FIXME: use a distance instead? - - missile.effects = EF_BRIGHTFIELD | EF_LOWPRECISION; - missile.flags = FL_PROJECTILE; -} - -float w_nexball_weapon(float req) -{ - if (req == WR_THINK) - { - if (self.BUTTON_ATCK) - if (weapon_prepareattack(0, autocvar_g_balance_nexball_primary_refire)) - if (autocvar_g_nexball_basketball_meter) - { - if (self.ballcarried && !self.metertime) - self.metertime = time; - else - weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); - } - else - { - W_Nexball_Attack(-1); - weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); - } - if (self.BUTTON_ATCK2) - if (weapon_prepareattack(1, autocvar_g_balance_nexball_secondary_refire)) - { - W_Nexball_Attack2(); - weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_nexball_secondary_animtime, w_ready); - } - - if (!self.BUTTON_ATCK && self.metertime && self.ballcarried) - { - W_Nexball_Attack(time - self.metertime); - // DropBall or stealing will set metertime back to 0 - weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); - } - } - else if (req == WR_PRECACHE) - { - precache_model ("models/weapons/g_porto.md3"); - precache_model ("models/weapons/v_porto.md3"); - precache_model ("models/weapons/h_porto.iqm"); - precache_model ("models/elaser.mdl"); - precache_sound ("nexball/shoot1.wav"); - precache_sound ("nexball/shoot2.wav"); - precache_sound ("misc/typehit.wav"); - } - else if (req == WR_SETUP) - weapon_setup(WEP_PORTO); - else if (req == WR_SUICIDEMESSAGE) - { - w_deathtypestring = "is a weirdo"; - } - else if (req == WR_KILLMESSAGE) - { - w_deathtypestring = "got killed by #'s black magic"; - } - // No need to check WR_CHECKAMMO* or WR_AIM, it should always return TRUE - return TRUE; -} diff --git a/qcsrc/server/attic/runematch.qc b/qcsrc/server/attic/runematch.qc deleted file mode 100644 index 1b6cc5dbb..000000000 --- a/qcsrc/server/attic/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(!IS_PLAYER(self.owner) || 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(!IS_PLAYER(other) || 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(IS_PLAYER(rune.owner)) - { - 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/attic/vehicles/bumblebee.qc b/qcsrc/server/attic/vehicles/bumblebee.qc deleted file mode 100644 index 067b17436..000000000 --- a/qcsrc/server/attic/vehicles/bumblebee.qc +++ /dev/null @@ -1,371 +0,0 @@ -#ifdef SVQC -// Auto cvars -float autocvar_g_vehicle_bumblebee_speed_forward; -float autocvar_g_vehicle_bumblebee_speed_strafe; -float autocvar_g_vehicle_bumblebee_speed_up; -float autocvar_g_vehicle_bumblebee_speed_down; -float autocvar_g_vehicle_bumblebee_turnspeed; -float autocvar_g_vehicle_bumblebee_pitchspeed; -float autocvar_g_vehicle_bumblebee_pitchlimit; -float autocvar_g_vehicle_bumblebee_friction; - -float autocvar_g_vehicle_bumblebee_energy; -float autocvar_g_vehicle_bumblebee_energy_regen; -float autocvar_g_vehicle_bumblebee_energy_regen_pause; - -float autocvar_g_vehicle_bumblebee_health; -float autocvar_g_vehicle_bumblebee_health_regen; -float autocvar_g_vehicle_bumblebee_health_regen_pause; - -float autocvar_g_vehicle_bumblebee_shield; -float autocvar_g_vehicle_bumblebee_shield_regen; -float autocvar_g_vehicle_bumblebee_shield_regen_pause; - -float autocvar_g_vehicle_bumblebee_cannon_cost; -float autocvar_g_vehicle_bumblebee_cannon_damage; -float autocvar_g_vehicle_bumblebee_cannon_radius; -float autocvar_g_vehicle_bumblebee_cannon_refire; -float autocvar_g_vehicle_bumblebee_cannon_speed; -float autocvar_g_vehicle_bumblebee_cannon_spread; -float autocvar_g_vehicle_bumblebee_cannon_force; - -float autocvar_g_vehicle_bumblebee_cannon_turnspeed; -float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down; -float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up; -float autocvar_g_vehicle_bumblebee_cannon_turnlimit_in; -float autocvar_g_vehicle_bumblebee_cannon_turnlimit_out; - -float autocvar_g_vehicle_bumblebee_respawntime; - -float autocvar_g_vehicle_bumblebee_blowup_radius; -float autocvar_g_vehicle_bumblebee_blowup_coredamage; -float autocvar_g_vehicle_bumblebee_blowup_edgedamage; -float autocvar_g_vehicle_bumblebee_blowup_forceintensity; - -#define BUMB_MIN '-120 -120 -40' -#define BUMB_MAX '120 120 40' - -.entity gunner1; -//.entity gunner2; -.vector lastaim; -float bumb_gunner_frame() -{ - entity vehic, gun, gunner; - float ftmp, ftmp2; - vector vtmp; - - vehic = self.vehicle; - gun = self.vehicle.gun1; - gunner = self; - - self = vehic; - vehic.solid = SOLID_NOT; - crosshair_trace(gunner); - - //vtmp = gettaginfo(vehic, gettagindexvehic, "tag_hardpoint01")); - vtmp = gettaginfo(gun, gettagindex(gun, "muzzle")); - vtmp = vectoangles(normalize(trace_endpos - vtmp)); // Find the direction & angle - vtmp = shortangle_vxy(vtmp - (vehic.angles + gun.angles), vehic.angles + gun.angles); // Find aim offset - - // Bind to aimspeed - ftmp2 = autocvar_g_vehicle_bumblebee_cannon_turnspeed * frametime; ftmp = -ftmp2; - vtmp_x = bound(ftmp, vtmp_x, ftmp2); - vtmp_y = bound(ftmp, vtmp_y, ftmp2); - // Bind to limts - gun.angles_x = bound(-autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down, vtmp_x + gun.angles_x, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up); - gun.angles_y = bound(-autocvar_g_vehicle_bumblebee_cannon_turnlimit_in, vtmp_y + gun.angles_y, autocvar_g_vehicle_bumblebee_cannon_turnlimit_out); - - if(gunner.BUTTON_ATCK && gun.cnt <= time) - { - vtmp = gettaginfo(gun, gettagindex(gun, "muzzle")); - v_forward = normalize(v_forward); - vtmp += v_forward * 50; - - fireBullet (vtmp, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_damage, - autocvar_g_vehicle_spiderbot_minigun_spread, DEATH_SBMINIGUN, 0); - - gun.cnt = time + 0.1; - } - - setorigin(gunner, vehic.origin); - gunner.velocity = vehic.velocity; - - vehic.solid = SOLID_BBOX; - gunner.BUTTON_ATCK = gunner.BUTTON_ATCK2 = gunner.BUTTON_CROUCH = 0; - self = gunner; - return 1; -} - -void bumb_gunner_enter() -{ - if(self.gunner1 != world) - return; - - self.gunner1 = other; - self.gunner1.vehicle = self; - - msg_entity = other; - WriteByte (MSG_ONE, SVC_SETVIEWPORT); - WriteEntity(MSG_ONE, self.gun1); - WriteByte (MSG_ONE, SVC_SETVIEWANGLES); - if(self.tur_head) - { - WriteAngle(MSG_ONE, self.gun1.angles_x + self.angles_x); // tilt - WriteAngle(MSG_ONE, self.gun1.angles_y + self.angles_y); // yaw - WriteAngle(MSG_ONE, 0); // roll - } - other.PlayerPhysplug = bumb_gunner_frame; -} - -float bumb_pilot_frame() -{ - entity pilot, gunner, vehic; - vector newvel; - - pilot = self; - vehic = self.vehicle; - self = vehic; - - if(pilot.BUTTON_USE && vehic.deadflag == DEAD_NO) - { - self = vehic; - vehicles_exit(VHEF_NORMAL); - self = pilot; - return 0; - } - - if(vehic.deadflag != DEAD_NO) - { - self = pilot; - pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = 0; - return 1; - } - - crosshair_trace(pilot); - - vector vang; - float ftmp; - - vang = vehic.angles; - newvel = vectoangles(normalize(trace_endpos - self.origin + '0 0 32')); - vang_x *= -1; - newvel_x *= -1; - if(newvel_x > 180) newvel_x -= 360; - if(newvel_x < -180) newvel_x += 360; - if(newvel_y > 180) newvel_y -= 360; - if(newvel_y < -180) newvel_y += 360; - - ftmp = shortangle_f(pilot.v_angle_y - vang_y, vang_y); - if(ftmp > 180) ftmp -= 360; if(ftmp < -180) ftmp += 360; - vehic.avelocity_y = bound(-autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity_y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed); - - // Pitch - ftmp = 0; - if(pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit) ftmp = 5; - else if(pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit) ftmp = -20; - - newvel_x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x , autocvar_g_vehicle_bumblebee_pitchlimit); - ftmp = vang_x - bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit); - vehic.avelocity_x = bound(-autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity_x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed); - - vehic.angles_x = anglemods(vehic.angles_x); - vehic.angles_y = anglemods(vehic.angles_y); - vehic.angles_z = anglemods(vehic.angles_z); - - makevectors('0 1 0' * vehic.angles_y); - newvel = vehic.velocity * -autocvar_g_vehicle_bumblebee_friction; - - if(pilot.movement_x != 0) - { - if(pilot.movement_x > 0) - newvel += v_forward * autocvar_g_vehicle_bumblebee_speed_forward; - else if(pilot.movement_x < 0) - newvel -= v_forward * autocvar_g_vehicle_bumblebee_speed_forward; - } - - if(pilot.movement_y != 0) - { - if(pilot.movement_y < 0) - newvel -= v_right * autocvar_g_vehicle_bumblebee_speed_strafe; - else if(pilot.movement_y > 0) - newvel += v_right * autocvar_g_vehicle_bumblebee_speed_strafe; - ftmp = newvel * v_right; - ftmp *= frametime * 0.1; - vehic.angles_z = bound(-15, vehic.angles_z + ftmp, 15); - } - else - { - vehic.angles_z *= 0.95; - if(vehic.angles_z >= -1 && vehic.angles_z <= -1) - vehic.angles_z = 0; - } - - if(pilot.BUTTON_CROUCH) - newvel -= v_up * autocvar_g_vehicle_bumblebee_speed_down; - else if (pilot.BUTTON_JUMP) - newvel += v_up * autocvar_g_vehicle_bumblebee_speed_up; - - vehic.velocity += newvel * frametime; - pilot.velocity = pilot.movement = vehic.velocity; - setorigin(pilot,vehic.origin + '0 0 32'); - - - if(vehic.vehicle_flags & VHF_SHIELDREGEN) - vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_bumblebee_shield, autocvar_g_vehicle_bumblebee_shield_regen_pause, autocvar_g_vehicle_bumblebee_shield_regen, frametime); - - if(vehic.vehicle_flags & VHF_HEALTHREGEN) - vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_health_regen_pause, autocvar_g_vehicle_bumblebee_health_regen, frametime); - - if(vehic.vehicle_flags & VHF_ENERGYREGEN) - vehicles_regen(cnt, vehicle_energy, autocvar_g_vehicle_bumblebee_energy, autocvar_g_vehicle_bumblebee_energy_regen_pause, autocvar_g_vehicle_bumblebee_energy_regen, frametime); - - VEHICLE_UPDATE_PLAYER(health, bumblebee); - VEHICLE_UPDATE_PLAYER(energy, bumblebee); - if(vehic.vehicle_flags & VHF_HASSHIELD) - VEHICLE_UPDATE_PLAYER(shield, bumblebee); - - pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = pilot.BUTTON_CROUCH = 0; - self = pilot; - - return 1; -} - -void bumb_think() -{ - self.velocity = self.velocity * 0.99; - self.nextthink = time + 0.1; -} - -void bumb_enter() -{ - self.touch = bumb_gunner_enter; -} - -void bumb_exit(float eject) -{ - self.owner = world; - self.touch = vehicles_touch; -} - -void bumb_spawn() -{ - self.vehicle_health = autocvar_g_vehicle_bumblebee_health; - self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield; - self.movetype = MOVETYPE_TOSS; - self.solid = SOLID_BBOX; - //self.vehicle_energy = 1; - self.movetype = MOVETYPE_FLY; - setorigin(self, self.origin + '0 0 25'); -} - -void bumb_die() -{ - self.health = 0; - self.event_damage = func_null; - self.solid = SOLID_CORPSE; - self.takedamage = DAMAGE_NO; - self.deadflag = DEAD_DYING; - self.movetype = MOVETYPE_BOUNCE; - - pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1); -} - -void bumb_dinit() -{ - if not (vehicle_initialize( - "Bumblebee", - "models/vehicles/bumblebee_body.dpm", - "", - "models/vehicles/spiderbot_cockpit.dpm", - "", "", "tag_viewport", - HUD_BUMBLEBEE, - BUMB_MIN, BUMB_MAX, - FALSE, - bumb_spawn, autocvar_g_vehicle_bumblebee_respawntime, - bumb_pilot_frame, - bumb_enter, bumb_exit, - bumb_die, bumb_think, - FALSE)) - { - remove(self); - return; - } - self.gun1 = spawn(); - setmodel(self.gun1, "models/vehicles/bumblebee_ray.dpm"); - setattachment(self.gun1, self, "tag_hardpoint03"); - - self.gun1 = spawn(); - self.gun2 = spawn(); - - self.gun1.owner = self; - self.gun2.owner = self; - - setmodel(self.gun1, "models/vehicles/bumblebee_plasma_right.dpm"); - setmodel(self.gun2, "models/vehicles/bumblebee_plasma_left.dpm"); - - setattachment(self.gun1, self, "tag_hardpoint01"); - setattachment(self.gun2, self, "tag_hardpoint02"); - - vector ofs; - ofs = gettaginfo(self, gettagindex(self, "tag_hardpoint01")); - ofs -= self.origin; - setattachment(self.gun1, self, ""); - setorigin(self.gun1, ofs); - - ofs = gettaginfo(self, gettagindex(self, "tag_hardpoint02")); - ofs -= self.origin; - setattachment(self.gun2, self, ""); - setorigin(self.gun2, ofs); - - -} - -void spawnfunc_vehicle_bumblebee() -{ - - precache_model ("models/vehicles/bumblebee_body.dpm"); - precache_model ("models/vehicles/bumblebee_plasma_left.dpm"); - precache_model ("models/vehicles/bumblebee_plasma_right.dpm"); - precache_model ("models/vehicles/bumblebee_ray.dpm"); - - //vehicles_configcheck("vehicle_bumblebee.cfg", autocvar_g_vehicle_bumblebee_health); - - if(autocvar_g_vehicle_bumblebee_energy) - if(autocvar_g_vehicle_bumblebee_energy_regen) - self.vehicle_flags |= VHF_ENERGYREGEN; - - if(autocvar_g_vehicle_bumblebee_shield) - self.vehicle_flags |= VHF_HASSHIELD; - - if(autocvar_g_vehicle_bumblebee_shield_regen) - self.vehicle_flags |= VHF_SHIELDREGEN; - - if(autocvar_g_vehicle_bumblebee_health_regen) - self.vehicle_flags |= VHF_HEALTHREGEN; - - self.think = bumb_dinit; - self.nextthink = time + 1; -} -#endif // SVQC - -#ifdef CSQC -void bumblebee_draw() -{ - -} - -void bumblebee_draw2d() -{ - -} - -void bumblebee_read_extra() -{ - -} - -void vehicle_bumblebee_assemble() -{ - -} -#endif //CSQC diff --git a/qcsrc/server/attic/vehicles/collision.qc b/qcsrc/server/attic/vehicles/collision.qc deleted file mode 100644 index 11488a0d5..000000000 --- a/qcsrc/server/attic/vehicles/collision.qc +++ /dev/null @@ -1,55 +0,0 @@ -vector collision_force; -vector collision_angle; - -vector bb1[9]; -vector bb2[9]; - -float collision_run() -{ - vector vtmp, vmin, vmax, vrot, vforce, vtmp2, vtmp3; - float i, fvel, bcol; - - - // Extract the 8 bbox corners from mins/maxs for self - vmax = self.maxs; - vmin = self.mins; - bb1[0] = vmax; - vtmp = vmax; vtmp_x = vmin_x; bb1[1] = vtmp; - vtmp = vmax; vtmp_y = vmin_y; bb1[2] = vtmp; - vtmp = vmin; vtmp_z = vmax_z; bb1[3] = vtmp; - bb1[4] = vmin; - vtmp = vmin; vtmp_x = vmax_x; bb1[5] = vtmp; - vtmp = vmin; vtmp_y = vmax_y; bb1[6] = vtmp; - vtmp = vmax; vtmp_z = vmin_z; bb1[7] = vtmp; - - makevectors(self.angles + '-2 0 0' * self.angles_x); - bcol = 0; - - // Pass1: Transform by rotation, ajust points by impact/s - for(i = 8; i >= 0; --i) - { - vtmp = bb1[i]; - vtmp = self.origin + vtmp_x * v_forward - vtmp_y * v_right + vtmp_z * v_up; - traceline(self.origin, vtmp, MOVE_WORLDONLY, self); - te_lightning1(world,self.origin,vtmp); - if(trace_fraction != 1.0) - { - vforce += (trace_endpos - vtmp); - vtmp3 = self.origin + self.velocity * frametime; - vtmp2 = vectoangles(normalize(vtmp - vtmp3)); - vrot += (vectoangles(normalize(trace_endpos - vtmp3)) - vtmp2); - bcol += 1; - } - } - - if(bcol) - { - - vtmp = self.origin + self.velocity * frametime; - self.angles += vrot * frametime; - self.velocity += vforce * frametime; - - } - -} - diff --git a/qcsrc/server/attic/vehicles/network.qc b/qcsrc/server/attic/vehicles/network.qc deleted file mode 100644 index 688aa7ca2..000000000 --- a/qcsrc/server/attic/vehicles/network.qc +++ /dev/null @@ -1,237 +0,0 @@ -#ifdef VEHICLES_CSQC -// SendFlags -float VSF_SETUP = 1; /// Send vehicle type etc -float VSF_ORIGIN = 2; /// Send location -float VSF_MOVEMENT = 4; /// Send movement update (and angles) -float VSF_AVEL = 8; /// Send Angular velocity -float VSF_STATS = 16; /// Send ammo, health etc -float VSF_EXTRA = 32; /// Send additional data (turret rotations etc). Handeld per vehicle type. -float VSF_ANIMINFO = 64; /// Animation info -float VSF_FULL_UPDATE = 16777215; /// Send everything - -float VSX_FAR = 1; -float VSX_OWNER = 2; -float VSX_GUN1 = 4; -float VSX_GUN2 = 8; - -#ifdef SVQC -#define VSX_FARDISTANCE 2000 -float send_vehile(entity to, float sf) -{ - float dist, xf; - - var void WriteFunc(float, float); - - dist = vlen(self.origin - to.origin); - if(to == self.owner) - xf |= VSX_OWNER; - else if(dist > VSX_FARDISTANCE) - xf |= VSX_FAR; - - // Always send a movement and origin to owner - if(to == self.owner) - sf |= VSF_ORIGIN | VSF_MOVEMENT; - - WriteByte(MSG_ENTITY, ENT_CLIENT_VEHICLE); - - // We need to know client-side what was sent - WriteByte(MSG_ENTITY, sf); - WriteByte(MSG_ENTITY, xf); - - if(sf & VSF_SETUP) - { - WriteByte(MSG_ENTITY, self.hud); //vehicle type = hud - WriteByte(MSG_ENTITY, self.team); - WriteShort(MSG_ENTITY, self.colormap); - WriteShort(MSG_ENTITY, self.vehicle_flags); - } - - if(sf & VSF_ORIGIN) - { - WriteFunc = ((xf & VSX_FAR) ? WriteShort : WriteCoord); - WriteFunc(MSG_ENTITY, self.origin_x); - WriteFunc(MSG_ENTITY, self.origin_y); - WriteFunc(MSG_ENTITY, self.origin_z); - } - - if(sf & VSF_MOVEMENT) - { - WriteFunc = ((xf & VSX_FAR) ? WriteShort : WriteCoord); - WriteFunc(MSG_ENTITY, self.velocity_x); - WriteFunc(MSG_ENTITY, self.velocity_y); - WriteFunc(MSG_ENTITY, self.velocity_z); - - WriteFunc = ((xf & VSX_FAR) ? WriteShort : WriteAngle); - WriteFunc(MSG_ENTITY, self.angles_x); - WriteFunc(MSG_ENTITY, self.angles_y); - WriteFunc(MSG_ENTITY, self.angles_z); - } - - if(sf & VSF_AVEL) - { - WriteFunc = ((xf & VSX_FAR) ? WriteShort : WriteCoord); - WriteFunc(MSG_ENTITY, self.avelocity_x); - WriteFunc(MSG_ENTITY, self.avelocity_y); - WriteFunc(MSG_ENTITY, self.avelocity_z); - } - - if(sf & VSF_STATS) - { - WriteByte(MSG_ENTITY, self.vehicle_health); - if(xf & VSX_OWNER) - { - WriteByte(MSG_ENTITY, self.vehicle_shield); - WriteByte(MSG_ENTITY, self.vehicle_energy); - - WriteByte(MSG_ENTITY, self.vehicle_ammo1); - WriteByte(MSG_ENTITY, self.vehicle_reload1); - - WriteByte(MSG_ENTITY, self.vehicle_ammo2); - WriteByte(MSG_ENTITY, self.vehicle_reload2); - - } - } - - if(sf & VSF_EXTRA) - self.vehile_send_exta(to, sf); - - return TRUE; -} - -void net_link_vehile() -{ - self.SendFlags = 0xFFFFFF; - Net_LinkEntity(self, FALSE, 0, send_vehile); -} -#endif // SVQC - -#ifdef CSQC -void vehicle_spiderbot_assemble() -{ - -} - -void vehicle_raptor_assemble() -{ - -} - -void vehicle_bumblebee_assemble() -{ - -} - -.float lastupdate; -void read_vehicle(float bIsNew) -{ - float sf, xf; - var float ReadFunc(); - - sf = ReadByte(); - xf = ReadByte(); - - if(xf & VSX_OWNER) - vehicle = self; - - if(sf & VSF_SETUP) - { - self.vehicle_hud = ReadByte(); - self.team = ReadByte(); - self.colormap = ReadShort(); - self.vehicle_flags = ReadShort(); - - switch(self.vehicle_hud) - { - case HUD_WAKIZASHI: - vehicle_racer_assemble(); - break; - case HUD_SPIDERBOT: - vehicle_spiderbot_assemble(); - break; - case HUD_RAPTOR: - vehicle_raptor_assemble(); - break; - case HUD_BUMBLEBEE: - vehicle_bumblebee_assemble(); - break; - default: - break; - } - } - - if(self.vehicle_hud == HUD_WAKIZASHI && xf & VSX_OWNER) - { - - vehicle_hudmodel.owner = self; - } - - //if(xf & VSX_FAR) - // dprint("Client vehicle faaar set\n"); - - if(sf & VSF_ORIGIN) - { - ReadFunc = ((xf & VSX_FAR) ? ReadShort : ReadCoord); - self.origin_x = ReadFunc(); - self.origin_y = ReadFunc(); - self.origin_z = ReadFunc(); - - setorigin(self, self.origin); - //self.lastupdate = time; - } - - if(sf & VSF_MOVEMENT) - { - ReadFunc = ((xf & VSX_FAR) ? ReadShort : ReadCoord); - self.velocity_x = ReadFunc(); - self.velocity_y = ReadFunc(); - self.velocity_z = ReadFunc(); - - ReadFunc = ((sf & VSX_FAR) ? ReadShort : ReadAngle); - self.angles_x = ReadFunc(); - self.angles_y = ReadFunc(); - self.angles_z = ReadFunc(); - - //self.lastupdate = time; - // self.move_velocity = self.velocity; - // self.move_angles = self.angles; - } - - if(sf & VSF_AVEL) - { - ReadFunc = ((xf & VSX_FAR) ? ReadShort : ReadCoord); - self.avelocity_x = ReadFunc(); - self.avelocity_y = ReadFunc(); - self.avelocity_z = ReadFunc(); - - // self.move_avelocity = self.avelocity; - } - - if(sf & VSF_STATS) - { - self.vehicle_health = ReadByte(); - if(xf & VSX_OWNER) - { - self.vehicle_shield = ReadByte(); - self.vehicle_energy = ReadByte(); - self.vehicle_ammo1 = ReadByte(); - self.vehicle_reload1 = ReadByte(); - self.vehicle_ammo2 = ReadByte(); - self.vehicle_reload2 = ReadByte(); - } - } - - if(sf & VSF_EXTRA) - self.vehile_read_exta(sf); - -} - -#endif // CSQC -#else -#ifdef CSQC -.float lastupdate; -void read_vehicle(float bIsNew) -{ - -} -#endif -#endif // VEHICLES_CSQC diff --git a/qcsrc/server/attic/verbstack.qc b/qcsrc/server/attic/verbstack.qc deleted file mode 100644 index b0601afe6..000000000 --- a/qcsrc/server/attic/verbstack.qc +++ /dev/null @@ -1,274 +0,0 @@ -/// Some default stacks. -.entity verbs_idle; -.entity verbs_attack; -.entity verbs_move; -//.entity vchain; - -/// This global gets set to the verb in question each time the stack manager calls verb_call -entity verb; -//.entity current_verb; -//.float verb_done; - -/// Execure this verb -#define VCM_DO 0 -/// Return the value of this verb. Return VS_CALL_REMOVE to delete it. -#define VCM_EVAL 1 -/// This verb is beeing removed NOW (not sent when verb_call returns VS_CALL_REMOVE) -#define VCM_REMOVE 2 - -/// Verb callback -.float(float message) verb_call; - -/// Points to this verb's stack. -.entity verbstack; - -/// Static value of this verb -.float verb_static_value; - -/// verb_call returns this when a verb in not doable -#define VS_CALL_NO 0 -/// verb_call(VCM_DO) returns this when a verb is executing -#define VS_CALL_YES_DOING -1 -/// verb_call(VCM_DO) returns this when a verb did execure and is done -#define VS_CALL_YES_DONE -2 -/// verb_call(VCM_DO) returns this when a verb should be deleted by the stack manager -#define VS_CALL_REMOVE -3 - -/* -void verbstack_updatechain(entity stack) -{ - entity vrb, v; - if not (stack) - return; - - dprint("verbstack_updatechain\n"); - - vrb = findchainentity(verbstack, stack); - if not (vrb) - { - stack.vchain = world; - return; - } - - stack.vchain = vrb; - v = vrb; - - while(vrb) - { - vrb = vrb.chain; - - - } -} - -void verbstack_remove(entity vverb) -{ - entity vstack; - dprint("verbstack_remove\n"); - - vstack = verb.verbstack; - remove(vverb); - vverb.verbstack = world; - verbstack_updatechain(vstack); - - //vverb.think = SUB_Remove; - //vverb.nextthink = time; -} - -void verbstack_thinkremove() -{ - dprint("verbstack_thinkremove\n"); - verbstack_remove(self); -} -*/ - -/** - Push a new verb onto the specified stack. Set vrb_life to make it time-limited. -**/ -entity verbstack_push(entity stack, float(float eval) vrb_call, float val_static, float vrb_life,entity verb_owner) -{ - entity vrb; - - if not(stack) - return world; - - if not(vrb_call) - return world; - - vrb = spawn(); - vrb.owner = verb_owner; - vrb.verbstack = stack; - vrb.verb_call = vrb_call; - vrb.verb_static_value = val_static; - - vrb.classname = "verb"; - stack.classname = "verbstack"; - - if(vrb_life) - { - //vrb.think = verbstack_thinkremove; - vrb.think = SUB_Remove; - vrb.nextthink = time + vrb_life; - } - - //verbstack_updatechain(stack); - - return vrb; -} - -/** - Find the best verb in this stack and execurte it. - ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL or VCM_DO -**/ -float verbstack_pop(entity stack) -{ - entity vrb, bestverb, oldself; - float value, bestvalue; - - oldself = self; - - vrb = findchainentity(verbstack,stack); - //vrb = stack.vchain; - //dprint("owner:", stack.owner.classname, " vsn:", stack.classname,"\n"); - while(vrb) - { - //dprint("vn:", vrb.classname,"\n"); - verb = vrb; - vrb = vrb.chain; - self = verb.owner; - value = verb.verb_call(VCM_EVAL); - - if(value < 0) - { - if(value == VS_CALL_REMOVE) - remove(verb); - } - else - { - if(value > bestvalue) - { - bestverb = verb; - bestvalue = value; - } - } - } - - if(bestverb) - { - verb = bestverb; - self = verb.owner; - value = verb.verb_call(VCM_DO); - - if(value == VS_CALL_REMOVE) - remove(bestverb); - } - - self = oldself; - - return value; -} - -float verbstack_popfifo(entity stack) -{ - entity oldself; - float ret; - - oldself = self; - verb = findentity(stack,verbstack,stack); - if not (verb) - ret = 0; - else - { - self = verb.owner; - ret = verb.verb_call(VCM_DO); - - if(ret == VS_CALL_REMOVE) - remove(verb); - } - - self = oldself; - return ret; -} - -/** - Find the best verb in this stack and return it. - ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL. -**/ -entity verbstack_pull(entity stack) -{ - entity vrb; - entity bestverb, oldself; - float value, bestvalue; - - oldself = self; - - vrb = findchainentity(verbstack,stack); - while(vrb) - { - self = vrb.owner; - - verb = vrb; - vrb = vrb.chain; - value = verb.verb_call(VCM_EVAL); - - if(value < 0) - { - if(value == VS_CALL_REMOVE) - remove(verb); - } - else - { - if(value > bestvalue) - { - bestverb = verb; - bestvalue = value; - } - } - } - - self = oldself; - - return bestverb; -} - -entity verbstack_pullfifo(entity stack) -{ - return findentity(stack,verbstack,stack); -} - -/** - Delete every verb on this stack, signaling them with VCM_REMOVE first. -**/ -void verbstack_flush(entity stack) -{ - entity vrb, oldself; - - oldself = self; - - vrb = findchainentity(verbstack,stack); - while(vrb) - { - self = vrb.owner; - - verb = vrb; - vrb = vrb.chain; - verb.verb_call(VCM_REMOVE); - remove(verb); - } - - self = oldself; - - //stack.vchain = world; -} - -void verbstack_doverb(entity vrb) -{ - float value; - - verb = vrb; - self = verb.owner; - value = verb.verb_call(VCM_DO); - - if(value == VS_CALL_REMOVE) - remove(vrb); -}