/* =============================================
* - NAME:
* + Player Spawn Utility
*
* - DESCRIPTION:
* + This plugin lets you easily add more player spawn points to any map at the position you are standing.
* + In the menu it will let you know how many spawns are recommended for your server size (# of slots).
* + After adding spawns you can save them and they will auto load on map start.
* + Use the sv_spawneditor cvar to see where other spawns are so you know where to add new ones.
*
* + NOTE: I made this because Hawks spawn creater was making spawns in bad places (outside of the map).
*
* - USAGE:
* + In your addons/amxmodx/configs directory make a new folder called "spawns".
* + Now go in your server and turn the "sv_spawneditor" to "1".
* + Restart the map. Now you will see where the current spawn points are.
* + Type "amx_spawnmenu" in the console to load the spawn editor menu.
* + Press "1" to add a Terrorist spawn, and "2" for a CT spawn. Press "3" to save spawns you made.
* + Now turn the "sv_spawneditor" cvar back to "0", restart the map.
*
* - CREDITS:
* + Hawk552's Spawn Creater for ideas.
*
* ---------------
* Admin Commands:
* ---------------
* - Type in console 'amx_spawnmenu' to show the spawn editor menu.
*
* -------------
* Server cvars:
* -------------
* - sv_spawneditor <0/1>
* + Setting to 0 will turn the spawn editor off.
* + Setting to 1 will turn the spawn editor on (while on you can see all the spawn points).
*
* ----------
* Changelog:
* ----------
* Version 1.0 (02-03-2008)
* -- First version made and works.
*/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#define PLUGIN "Spawn Utility"
#define VERSION "1.0"
#define AUTHOR "hlstriker"
// Load variables
new g_filename[256];
new bool:g_customsCreated;
// Save variables
new sTeams[64];
new Float:sOrigins[64][3];
new Float:sAngles[64][3];
new sEntId;
// Regular variables
new sv_spawneditor;
new g_spawnMenu;
new bool:g_hasSpawned[33];
new g_maxPlayerSlots;
new g_tSpawns;
new g_ctSpawns;
new Float:angle;
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR);
g_maxPlayerSlots = get_maxplayers();
register_clcmd("amx_spawnmenu", "spawnMenu", ADMIN_RCON, "- the spawn utility menu");
register_event("ResetHUD", "hook_ResetHUD", "be");
}
public plugin_precache()
{
new confFolder[32];
get_mapname(g_filename, 255);
get_configsdir(confFolder, 31);
format(g_filename, 255, "%s/spawns/%s.ini", confFolder, g_filename);
sv_spawneditor = register_cvar("sv_spawneditor", "0");
register_forward(FM_Spawn, "fwd_Spawn", 1);
}
public client_authorized(id)
g_hasSpawned[id] = false;
public hook_ResetHUD(id)
{
if(is_user_admin(id) && !g_hasSpawned[id])
{
g_hasSpawned[id] = true;
if(g_maxPlayerSlots >= g_tSpawns * 2 || g_maxPlayerSlots >= g_tSpawns * 2)
{
static recT, recCT;
recT = g_maxPlayerSlots / 2 - g_tSpawns + 3;
recCT = g_maxPlayerSlots / 2 - g_ctSpawns + 3;
client_print(id, print_chat, "WARNING: This map does not have enough spawns [%i T] [%i CT].", g_tSpawns, g_ctSpawns);
client_print(id, print_chat, "WARNING: Notify the server owner to add a recommended of [%i T] and [%i CT] spawns.", recT, recCT);
}
}
}
public spawnMenu(id, level, cid)
{
if(cmd_access(id, level, cid, 1))
create_menu(id);
return FMRES_HANDLED;
}
public create_menu(id)
{
static text[128], recT, recCT;
recT = g_maxPlayerSlots / 2 + 3;
recCT = g_maxPlayerSlots / 2 + 3;
format(text, 127, "Total Spawns:^n[%i T-Spawns] [%i CT-Spawns]^n^nRecommended Spawns:^n[%i T-Spawns] [%i CT-Spawns]", g_tSpawns, g_ctSpawns, recT, recCT);
g_spawnMenu = menu_create(text, "spawnMenu_handle");
menu_additem(g_spawnMenu, "Create T Spawn");
menu_additem(g_spawnMenu, "Create CT Spawn");
menu_additem(g_spawnMenu, "Save Created Spawns");
menu_setprop(g_spawnMenu, MPROP_PERPAGE, 3);
menu_display(id, g_spawnMenu, 0);
}
public spawnMenu_handle(id, menu, key)
{
// If they press the exit key, return
if(key == MENU_EXIT)
return FMRES_HANDLED;
switch(key)
{
case 0:
{
// Key 1 - Create T Spawn
sTeams[sEntId] = 1;
pev(id, pev_origin, sOrigins[sEntId]);
pev(id, pev_angles, sAngles[sEntId]);
sAngles[sEntId][0] = angle;
sOrigins[sEntId][2] += 9.0;
new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_player_deathmatch"));
engfunc(EngFunc_SetOrigin, ent, sOrigins[sEntId]);
if(get_pcvar_num(sv_spawneditor) == 1)
engfunc(EngFunc_SetModel, ent, "models/player/terror/terror.mdl");
set_pev(ent, pev_fixangle, 1);
set_pev(ent, pev_angles, sAngles[sEntId]);
set_pev(ent, pev_iuser1, 1);
dllfunc(DLLFunc_Spawn, ent);
sEntId +=1;
g_tSpawns += 1;
client_print(id, print_chat, "[Spawn Utility] You have created a T spawn [%i].", g_tSpawns);
}
case 1:
{
// Key 2 - Create CT Spawn
sTeams[sEntId] = 2;
pev(id, pev_origin, sOrigins[sEntId]);
pev(id, pev_angles, sAngles[sEntId]);
sAngles[sEntId][0] = angle;
sOrigins[sEntId][2] += 9.0;
new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_player_start"));
engfunc(EngFunc_SetOrigin, ent, sOrigins[sEntId]);
if(get_pcvar_num(sv_spawneditor) == 1)
engfunc(EngFunc_SetModel, ent, "models/player/vip/vip.mdl");
set_pev(ent, pev_fixangle, 1);
set_pev(ent, pev_angles, sAngles[sEntId]);
set_pev(ent, pev_iuser1, 1);
dllfunc(DLLFunc_Spawn, ent);
sEntId +=1;
g_ctSpawns += 1;
client_print(id, print_chat, "[Spawn Utility] You have created a CT spawn [%i].", g_ctSpawns);
}
case 2:
{
// Key 3 - Save Spawns
new text[3072], ln;
ln = 0;
for(new i=0; i<=sEntId; i++)
{
if(sTeams[i] > 0)
ln += format(text[ln], 3071-ln, "%i^n%f^n%f^n%f^n%f^n%f^n%f^n", sTeams[i], sOrigins[i][0], sOrigins[i][1], sOrigins[i][2], sAngles[i][0], sAngles[i][1], sAngles[i][2]);
else break;
}
new filepointer;
filepointer = fopen(g_filename, "w+");
if(filepointer)
{
fprintf(filepointer, text);
fclose(filepointer);
client_print(id, print_chat, "[Spawn Utility] You have saved the spawns, they will auto load from now on.");
}
return FMRES_HANDLED;
}
}
create_menu(id);
return FMRES_HANDLED;
}
public fwd_Spawn(entId)
{
if(!pev_valid(entId))
return FMRES_IGNORED;
static className[64];
pev(entId, pev_classname, className, 63);
if(equali(className, "info_player_start"))
{
static Float:angles[3];
pev(entId, pev_angles, angles);
angle = angles[0];
if(get_pcvar_num(sv_spawneditor) == 1)
{
static Float:origin[3], Float:angles[3];
pev(entId, pev_origin, origin);
pev(entId, pev_angles, angles);
new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
engfunc(EngFunc_SetOrigin, ent, origin);
engfunc(EngFunc_SetModel, ent, "models/player/vip/vip.mdl");
engfunc(EngFunc_SetSize, ent, Float:{-16.0,-16.0,-36.0}, Float:{16.0,16.0,36.0});
set_pev(ent, pev_angles, angles);
dllfunc(DLLFunc_Spawn, ent);
}
g_ctSpawns += 1;
}
else if(equali(className, "info_player_deathmatch"))
{
if(get_pcvar_num(sv_spawneditor) == 1)
{
static Float:origin[3], Float:angles[3];
pev(entId, pev_origin, origin);
pev(entId, pev_angles, angles);
new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
engfunc(EngFunc_SetOrigin, ent, origin);
engfunc(EngFunc_SetModel, ent, "models/player/terror/terror.mdl");
engfunc(EngFunc_SetSize, ent, Float:{-16.0,-16.0,-36.0}, Float:{16.0,16.0,36.0});
set_pev(ent, pev_angles, angles);
dllfunc(DLLFunc_Spawn, ent);
}
g_tSpawns += 1;
}
if(!g_customsCreated)
{
g_customsCreated = true;
new cTeams[64], Float:cOrigins[64][3], Float:cAngles[64][3], entNum, i;
// Get all the custom spawns and save to arrays
new file;
file = fopen(g_filename, "r");
if(file)
{
// File exists
new data[3072], type;
while(!feof(file))
{
fgets(file, data, 3071);
switch(type)
{
case 0:
{
// Load the team
cTeams[entNum] = str_to_num(data);
type = 1;
}
case 1:
{
// Load Origin[0]
cOrigins[entNum][0] = str_to_float(data);
type = 2;
}
case 2:
{
// Load Origin[1]
cOrigins[entNum][1] = str_to_float(data);
type = 3;
}
case 3:
{
// Load Origin[2]
cOrigins[entNum][2] = str_to_float(data);
type = 4;
}
case 4:
{
// Load Angles[0]
cAngles[entNum][0] = str_to_float(data);
type = 5;
}
case 5:
{
// Load Angles[1]
cAngles[entNum][1] = str_to_float(data);
type = 6;
}
case 6:
{
// Load Angles[2]
cAngles[entNum][2] = str_to_float(data);
type = 0;
entNum += 1;
}
}
i++;
}
fclose(file);
}
// Now load all the custom spawns from the arrays
new cEnt;
for(i=0; i<=entNum; i++)
{
if(cTeams[i] > 0)
{
if(cTeams[i] == 1)
{
cEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_player_deathmatch"));
g_tSpawns += 1;
}
else if(cTeams[i] == 2)
{
cEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_player_start"));
g_ctSpawns += 1;
}
engfunc(EngFunc_SetOrigin, cEnt, cOrigins[i]);
if(get_pcvar_num(sv_spawneditor) == 1)
{
if(cTeams[i] == 1)
engfunc(EngFunc_SetModel, cEnt, "models/player/terror/terror.mdl");
else if(cTeams[i] == 2)
engfunc(EngFunc_SetModel, cEnt, "models/player/vip/vip.mdl");
}
set_pev(cEnt, pev_fixangle, 1);
set_pev(cEnt, pev_angles, cAngles[i]);
set_pev(cEnt, pev_iuser1, 1);
dllfunc(DLLFunc_Spawn, cEnt);
}
else break;
}
}
return FMRES_HANDLED;
}