1 #include "gamemode_singleplayer.qh"
3 const int SP_TEAM_PLAYER = NUM_TEAM_1;
4 const int SP_TEAM_ENEMY = NUM_TEAM_2;
12 bool autocvar_g_sp_allow_bot_pickup;
16 /*QUAKED spawnfunc_tdm_team (0 .5 .8) (-16 -16 -24) (16 16 32)
17 Team declaration for TDM gameplay, this allows you to decide what team names and control point models are used in your map.
18 Note: If you use spawnfunc_tdm_team entities you must define at least 2! However, unlike domination, you don't need to make a blank one too.
20 "netname" Name of the team (for example Red, Blue, Green, Yellow, Life, Death, Offense, Defense, etc)...
21 "cnt" Scoreboard color of the team (for example 4 is red and 13 is blue)... */
24 if(!g_singleplayer || !this.cnt) { delete(this); return; }
26 this.classname = "sp_team";
27 this.team = this.cnt + 1;
30 // code from here on is just to support maps that don't have team entities
31 void sp_spawn_team_entity(string teamname, int teamcolor)
33 entity this = new_pure(sp_team);
34 this.netname = teamname;
35 this.cnt = teamcolor - 1;
36 this.team = teamcolor;
37 this.spawnfunc_checked = true;
41 spawnfunc(info_player_singleplayer)
43 if (!g_singleplayer) { delete(this); return; }
45 this.team = SP_TEAM_PLAYER;
46 this.sp_spawn_team = SP_TEAM_PLAYER;
47 spawnfunc_info_player_deathmatch(this);
50 void sp_spawn_bot(entity spawn_point)
53 entity bot = spawnclient();
56 bot.sp_spawn_spot = spawn_point;
61 LOG_WARN("Could not spawn bot");
65 void sp_enemy_spawn_think(entity this)
68 setthink(this, func_null);
72 void sp_enemy_spawn_use(entity this, entity actor, entity trigger)
77 spawnfunc(info_player_singleplayer_enemy)
79 if (!g_singleplayer) { delete(this); return; }
81 this.team = SP_TEAM_ENEMY;
82 this.sp_spawn_team = SP_TEAM_ENEMY;
83 spawnfunc_info_player_deathmatch(this);
84 this.use = sp_enemy_spawn_use;
85 if ( this.targetname == "" )
86 setthink(this, sp_enemy_spawn_think);
89 void sp_delayed_init(entity this)
91 // if no teams are found, spawn defaults
92 if(find(NULL, classname, "sp_team") == NULL)
94 sp_spawn_team_entity("Player", SP_TEAM_PLAYER);
95 sp_spawn_team_entity("Enemy", SP_TEAM_ENEMY);
101 void sp_remove_bot(entity bot)
104 bot.sp_spawn_spot = NULL;
108 MUTATOR_HOOKFUNCTION(sp, CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
110 M_ARGV(1, string) = "sp_team";
111 entity ent = M_ARGV(2, entity);
112 if ( IS_BOT_CLIENT(ent) )
114 ent.team_forced = NUM_TEAM_2;
116 else if( IS_REAL_CLIENT(ent) )
118 ent.team_forced = NUM_TEAM_1;
127 MUTATOR_HOOKFUNCTION(sp, Scores_CountFragsRemaining)
132 MUTATOR_HOOKFUNCTION(sp, PlayerSpawn)
134 entity player = M_ARGV(0, entity);
135 entity spawn_spot = M_ARGV(1, entity);
136 if ( IS_BOT_CLIENT(player) )
138 player.can_drop_weapon = spawn_spot.can_drop_weapon;
139 player.items |= IT_UNLIMITED_WEAPON_AMMO;
140 if ( spawn_spot.health )
141 player.health = spawn_spot.health;
142 player.armorvalue = spawn_spot.armorvalue;
143 player.weapons = WepSet_FromWeapon(Weapons_fromstr(spawn_spot.weapon_name));
144 if ( spawn_spot.netname )
145 player.netname = spawn_spot.netname;
149 player.can_drop_weapon = true;
153 MUTATOR_HOOKFUNCTION(sp, ForbidDropCurrentWeapon)
155 entity player = M_ARGV(0, entity);
156 return !player.can_drop_weapon;
159 MUTATOR_HOOKFUNCTION(sp, CheckRules_World)
161 M_ARGV(0, float) = WINNING_NO;
162 // TODO: conditions for WINNING_YES
166 MUTATOR_HOOKFUNCTION(sp, Spawn_Score)
168 entity player = M_ARGV(0, entity);
169 entity spawn_spot = M_ARGV(1, entity);
170 vector spawn_score = M_ARGV(2, vector);
171 if ( IS_BOT_CLIENT(player) )
173 if ( spawn_spot.sp_spawn_team != SP_TEAM_ENEMY ||
174 (player.sp_spawn_spot && player.sp_spawn_spot != spawn_spot) )
177 else if ( spawn_spot.sp_spawn_team != SP_TEAM_PLAYER )
182 M_ARGV(2, vector) = spawn_score;
185 MUTATOR_HOOKFUNCTION(sp, HideTeamNagger)
190 MUTATOR_HOOKFUNCTION(sp, Bot_FixCount)
192 M_ARGV(2, int) = sp_bot_number;
196 MUTATOR_HOOKFUNCTION(sp, PlayerDies)
198 entity target = M_ARGV(2, entity);
199 if ( IS_BOT_CLIENT(target) )
201 if ( target.sp_spawn_spot && !target.sp_spawn_spot.can_respawn )
203 sp_remove_bot(target);
208 MUTATOR_HOOKFUNCTION(sp, Bot_SelectRemove)
210 FOREACH_CLIENT(it.isbot,
212 if ( !it.sp_spawn_spot )
214 M_ARGV(0, entity) = it;
220 MUTATOR_HOOKFUNCTION(sp, PlayerPreThink)
222 entity player = M_ARGV(0, entity);
223 if ( IS_BOT_CLIENT(player) && !player.sp_spawn_spot )
227 MUTATOR_HOOKFUNCTION(sp, ItemTouch)
229 entity toucher = M_ARGV(1, entity);
230 if ( IS_BOT_CLIENT(toucher) && !autocvar_g_sp_allow_bot_pickup )
231 return MUT_ITEMTOUCH_RETURN;
232 return MUT_ITEMTOUCH_CONTINUE;
235 MUTATOR_HOOKFUNCTION(sp, Item_Spawn)
237 entity item = M_ARGV(0, entity);
238 if ( !autocvar_g_sp_allow_bot_pickup )
240 item.bot_pickup = false;