I can't get a new submenu to work properly in the 3rd page. How to fix that?
Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta_util>
#define REQUIRED_ADMIN_LEVEL ADMIN_CFG
#define PLUGINNAME "Map Spawns Editor"
#define VERSION "1.0.16"
#define AUTHOR "iG_os"
// CS default MDL and SPR
#define T_MDL "models/player/leet/leet.mdl"
#define CT_MDL "models/player/gign/gign.mdl"
#define LINE_SPR "sprites/laserbeam.spr"
#define CHECKTIMER 0.8
#define CHECKTASKID 666
#define RESETENTITYTASKID 777
#define SAFEp2p 85 // point to point safe distance
#define SAFEp2w 40 // point to wall safe distance
#define EDIT_CLASSNAME "Map_Spawns_Editor"
#define SPAWN_PRESENT_OFFSET 10
#define SPAWN_ABOVE_OFFSET 115
// store filename
new g_SpawnFile[256], g_DieFile[256], g_EntFile[256], g_Stripper2File[256]
// Menu Handel ID
new g_MainMenuID = -1
new bool:g_DeathCheck_end = false
new bool:g_LoadSuccessed = false
new bool:g_LoadInit = false
new bool:g_CheckDistance = true
new bool:g_AbovePlayer = false
new g_OffSet = SPAWN_PRESENT_OFFSET
new g_Editing
new g_SpawnT, g_EditT
new g_SpawnCT, g_EditCT
new Laser_Spr
new g_BeamColors[4][3]={{255, 0, 0}, {0, 255, 0}, {200, 200, 0}, {0, 0, 255}}
new g_FwdKeyValue;
public plugin_init()
{
register_plugin(PLUGINNAME, VERSION, AUTHOR)
// register_dictionary("map_spawns_editor.txt")
unregister_forward(FM_KeyValue, g_FwdKeyValue);
// disabled pfn_keyvalue using
g_LoadInit = true
// Spawns_Count()
// new string[16]
// format(string, 15, "T(%d) CT(%d)", g_SpawnT, g_SpawnCT)
// register_cvar("map_spawns", string, FCVAR_SERVER) // spawns info for HLSW display
register_event("TextMsg", "event_restartgame", "a", "2&#Game_C", "2&#Game_w")
register_event("DeathMsg", "event_death", "a")
register_event("HLTV", "event_newround", "a", "1=0", "2=0")
register_clcmd("amx_spawneditor", "editor_onoff", REQUIRED_ADMIN_LEVEL, "- 1/0 switch editor function on/off")
register_clcmd("amx_spawneditor_menu", "editor_menu", REQUIRED_ADMIN_LEVEL, "- open editor menu")
}
public Forward_KeyValue( const EntIndex, const KvdHandle )
{
if ( pev_valid( EntIndex ) && g_LoadSuccessed && !g_LoadInit )
{
new szClassName[ 32 ];
get_kvd( KvdHandle, KV_ClassName, szClassName, charsmax( szClassName ) );
if( equal( szClassName, "info_player_deathmatch" ) || equal( szClassName, "info_player_start" ) )
{
if ( pev( EntIndex, pev_iuser1 ) != 1 )
{
engfunc( EngFunc_RemoveEntity, EntIndex );
return FMRES_SUPERCEDE;
}
}
}
return FMRES_IGNORED;
}
public editor_onoff(id, level, cid)
{
if (!cmd_access(id, level, cid, 1)) return PLUGIN_HANDLED
if (g_Editing && g_Editing!=id)
{
client_print(id, print_chat, "* Someone is already using the Spawn Editor. The Spawn Editor only supports one user at a time.")
return PLUGIN_HANDLED
}
new arg[2]
read_argv(1, arg, 2)
if (equal(arg, "1", 1) && !g_Editing)
{
g_Editing = id
Clear_AllEdit(0)
Load_SpawnFlie(0)
Spawns_To_Edit()
client_print(0, print_chat, ">> Map Spawns Editor - ON")
}
else if (equal(arg, "0", 1))
{
g_Editing = 0
Clear_AllEdit(0)
if (task_exists(id+CHECKTASKID)) remove_task(id+CHECKTASKID)
client_print(0, print_chat, ">> Map Spawns Editor - OFF")
}
return PLUGIN_HANDLED
}
public editor_menu(id, level, cid)
{
if (!cmd_access(id, level, cid, 1))
return PLUGIN_HANDLED
if (!g_Editing)
{
client_print(id, print_chat, "* The Spawn Editor is disabled. Type amx_spawn_editor 1 in console to enable it.")
return PLUGIN_HANDLED
}
if (g_Editing!=id)
{
client_print(id, print_chat, "* Someone is already using the Spawn Editor. The Spawn Editor only supports one user at a time.")
return PLUGIN_HANDLED
}
new tempString[101]
format(tempString, 100, "Map Spawns Editor")
g_MainMenuID = menu_create(tempString, "m_MainHandler")
new callbackMenu = menu_makecallback("c_Main")
// page 1
menu_additem(g_MainMenuID, "[Spawns Info]", "1", 1, callbackMenu)
menu_addblank(g_MainMenuID, 0)
menu_additem(g_MainMenuID, "[Add spawn locate: present/above player]", "2", 0, callbackMenu)
format(tempString, 100, "Add a %s spawn point", "T")
menu_additem(g_MainMenuID, tempString, "3", 0, callbackMenu)
format(tempString, 100, "Add a %s spawn point", "CT")
menu_additem(g_MainMenuID, tempString, "4", 0, callbackMenu)
menu_addblank(g_MainMenuID, 0)
format(tempString, 100, "\yTurn a spawn left by aim")
menu_additem(g_MainMenuID, tempString, "5", 0, callbackMenu)
format(tempString, 100, "\yTurn a spawn right by aim")
menu_additem(g_MainMenuID, tempString, "6", 0, callbackMenu)
menu_addblank(g_MainMenuID, 0)
format(tempString, 100, "Save all spawn points")
menu_additem(g_MainMenuID, tempString, "7", 0, callbackMenu)
menu_addblank(g_MainMenuID, 0)
// page 1 end
// page 2
menu_additem(g_MainMenuID, "[Spawns Info]", "11", 1, callbackMenu)
menu_addblank(g_MainMenuID, 0)
menu_additem(g_MainMenuID, "[Safe range check on/off]", "12", 0, callbackMenu)
format(tempString, 100, "Clear a spawn by aim")
menu_additem(g_MainMenuID, tempString, "13", 0, callbackMenu)
menu_addblank(g_MainMenuID, 0)
format(tempString, 100, "Clear all T spawns")
menu_additem(g_MainMenuID, tempString, "14", 0, callbackMenu)
format(tempString, 100, "Clear all CT spawns")
menu_additem(g_MainMenuID, tempString, "15", 0, callbackMenu)
menu_addblank(g_MainMenuID, 0)
format(tempString, 100, "Delete current map's spawn file")
menu_additem(g_MainMenuID, tempString, "16", 0, callbackMenu)
format(tempString, 100, "Export spawns for ENT format")
menu_additem(g_MainMenuID, tempString, "17", 0, callbackMenu)
menu_addblank(g_MainMenuID, 0)
// page 2 end
// page 3
menu_additem(g_MainMenuID, "[Spawns Info]", "21", 1, callbackMenu)
menu_addblank(g_MainMenuID, 0)
format(tempString, 100, "Export spawns for STRIPPER2 format")
menu_additem(g_MainMenuID, tempString, "22", 0, callbackMenu)
menu_addblank(g_MainMenuID, 0)
// page 3 end
format(tempString, 100, "Exit")
menu_setprop(g_MainMenuID, MPROP_EXITNAME, tempString)
format(tempString, 100, "Next")
menu_setprop(g_MainMenuID, MPROP_NEXTNAME, tempString)
format(tempString, 100, "Back")
menu_setprop(g_MainMenuID, MPROP_BACKNAME, tempString)
menu_setprop(g_MainMenuID, MPROP_EXIT, MEXIT_ALL)
menu_display (id, g_MainMenuID, 0)
client_cmd(id, "spk buttons/button9")
set_task(CHECKTIMER, "check_Task", id+CHECKTASKID, _, _, "b")
return PLUGIN_HANDLED
}
public c_Main(id, menu, item)
{
if (item < 0) return PLUGIN_CONTINUE
new cmd[6], fItem[256], iName[64]
new access, callback
menu_item_getinfo(menu, item, access, cmd, 5, iName, 63, callback)
new num = str_to_num(cmd)
if (num==1 || num==11)
{
if (g_EditT!=g_SpawnT || g_EditCT!=g_SpawnCT)
format(fItem, 255, "Spawn Origins (T=%d + CT=%d) ^n0.\y Edit Spawns \r(T=%d + CT=%d) ^n>> Notice: Save and reload the map once for changes to take effect", g_SpawnT, g_SpawnCT, g_EditT, g_EditCT)
else
format(fItem, 255, "Spawn Origins (T=%d + CT=%d) ^n0.\y Edit Spawns (T=%d + CT=%d)", g_SpawnT, g_SpawnCT, g_EditT, g_EditCT)
menu_item_setname(menu, item, fItem)
return ITEM_DISABLED
}
switch (num)
{
case 2:
{
if (g_AbovePlayer)
format(fItem, 255, "\yAdd spawn location ->\r Above of current location")
else
format(fItem, 255, "\yAdd spawn location ->\r Current location")
menu_item_setname(menu, item, fItem)
}
case 12:
{
if (g_CheckDistance)
format(fItem, 255, "\ySafe range check ->\r ON")
else
format(fItem, 255, "\ySafe range check ->\r OFF")
menu_item_setname(menu, item, fItem)
}
}
return ITEM_ENABLED
}
public m_MainHandler(id, menu, item)
{
if (item==MENU_EXIT || !g_Editing)
{
if (task_exists(id+CHECKTASKID)) remove_task(id+CHECKTASKID)
menu_destroy(g_MainMenuID)
return PLUGIN_HANDLED
}
new cmd[6], iName[64]
new access, callback
menu_item_getinfo(menu, item, access, cmd, 5, iName, 63, callback)
new iChoice = str_to_num(cmd)
switch(iChoice)
{
// Location Set
case 2:
{
if (g_AbovePlayer)
{
g_OffSet = SPAWN_PRESENT_OFFSET
g_AbovePlayer = false
}
else
{
g_OffSet = SPAWN_ABOVE_OFFSET
g_AbovePlayer = true
}
client_cmd(id, "spk buttons/button3")
}
// Add T Spawn
case 3:
{
if (g_CheckDistance && !SafeRangeCheck(id, g_OffSet))
{
client_cmd(id, "spk buttons/button2")
client_print(0, print_chat, ">> Notice: Unsafe location.")
}
else if (CreateEditEntity(1, id, g_OffSet)==1)
{
g_EditT++
client_cmd(id, "spk buttons/button9")
client_print(0, print_chat, ">> Add a %s spawn point", "T")
}
}
// Add CT Spawn
case 4:
{
if (g_CheckDistance && !SafeRangeCheck(id, g_OffSet))
{
client_cmd(id, "spk buttons/button2")
client_print(0, print_chat, ">> Notice: Unsafe location.")
}
else if (CreateEditEntity(2, id, g_OffSet)==2)
{
g_EditCT++
client_cmd(id, "spk buttons/button9")
client_print(0, print_chat, ">> Add a %s spawn point", "CT")
}
}
// Spawn Turn Left
case 5:
{
new entity = Get_Edit_Point_By_Aim(id)
if (entity && pev_valid(entity))
{
Entity_Turn_angle(entity, 10)
client_cmd(id, "spk buttons/blip1")
}
else
{
client_cmd(id, "spk buttons/button2")
client_print(0, print_chat, ">> Error: Couldn't locate spawn point.")
}
}
// Spawn Turn Right
case 6:
{
new entity = Get_Edit_Point_By_Aim(id)
if (entity && pev_valid(entity))
{
Entity_Turn_angle(entity, -10)
client_cmd(id, "spk buttons/blip1")
}
else
{
client_cmd(id, "spk buttons/button2")
client_print(0, print_chat, ">> Error: Couldn't locate spawn point.")
}
}
// Save All Spawn To File
case 7:
{
if (Save_SpawnsFile())
{
Load_SpawnFlie(0)
client_cmd(id, "spk buttons/blip2")
client_print(0, print_chat, ">> Saved all spawn points to file. (T=%d, CT=%d)", g_EditT, g_EditCT)
}
else
client_print(0, print_chat, ">> Error: Couldn't save spawns to file.")
}
// Safe Range Check
case 12:
{
g_CheckDistance = g_CheckDistance ? false:true
client_cmd(id, "spk buttons/button3")
}
// Clear a Spawn
case 13:
{
new entity = Get_Edit_Point_By_Aim(id)
if (entity && pev_valid(entity))
{
new team = pev(entity, pev_iuser2)
fm_remove_entity(entity)
client_cmd(id, "spk buttons/button3")
if (team==1)
{
g_EditT--
client_print(0, print_chat, ">> Successfully cleared a %s spawn point.", "T")
}
else
{
g_EditCT--
client_print(0, print_chat, ">> Successfully cleared a %s spawn point.", "CT")
}
}
else
{
client_cmd(id, "spk buttons/button2")
client_print(0, print_chat, ">> Error: Couldn't locate spawn point.")
}
}
// Clear All T Spawn
case 14:
{
Clear_AllEdit(1)
client_cmd(id, "spk buttons/blip2")
client_print(0, print_chat, ">> Clear all T spawns")
}
// Clear All CT Spawn
case 15:
{
Clear_AllEdit(2)
client_cmd(id, "spk buttons/blip2")
client_print(0, print_chat, ">> Clear all CT spawns")
}
// Del Spawns Flie
case 16:
{
if (file_exists(g_SpawnFile))
{
delete_file(g_SpawnFile)
client_cmd(id, "spk buttons/blip2")
client_print(0, print_chat, ">> Deleted current map's spawn file.")
}
}
// Expotr Spawn To ENT Format
case 17:
{
if (Export_RipentFormatFile())
{
client_cmd(id, "spk buttons/blip2")
client_print(0, print_chat, ">> Export all spawns to [%s] (T=%d, CT=%d)", g_EntFile, g_EditT, g_EditCT)
}
}
// Expotr Spawn To STRIPPER2 Format
case 22:
{
if (Export_Stripper2FormatFile())
{
client_cmd(id, "spk buttons/blip2")
client_print(0, print_chat, ">> Export all spawns to [%s] (T=%d, CT=%d)", g_Stripper2File, g_EditT, g_EditCT)
}
}
}
// go back to second page is using
if (iChoice>=11 && iChoice<=22)
menu_display (id, g_MainMenuID, 1)
else
menu_display (id, g_MainMenuID, 0)
return PLUGIN_CONTINUE
}
public plugin_precache()
{
new configdir[128]
get_configsdir(configdir, 127)
new spawndir[256]
format(spawndir, 255, "%s/spawns", configdir)
if (!dir_exists(spawndir))
{
// Create a dir, if it's not exist
if (mkdir(spawndir)==0)
{
log_amx("Create [%s] dir successfully finished.", spawndir)
}
else
{
log_error(AMX_ERR_NOTFOUND, "Couldn't create [%s] dir, plugin stoped.", spawndir)
pause("ad")
return PLUGIN_CONTINUE
}
}
precache_model(T_MDL)
precache_model(CT_MDL)
Laser_Spr = precache_model(LINE_SPR)
new MapName[32]
get_mapname(MapName, 31)
//store spawns point data in this file
format(g_SpawnFile, 255, "%s/%s_spawns.cfg", spawndir, MapName)
//when restart game some bad spawn point will make user die, store data in this file, it's useful.
format(g_DieFile, 255, "%s/%s_spawns_die.cfg", spawndir, MapName)
//export spawns data to this file for ripent.exe format, it's useful for import to bsp for ripent.exe
format(g_EntFile, 255, "%s/%s_ent.txt", spawndir, MapName)
//export spawns data to this file for Stripper2 format
format(g_Stripper2File, 255, "%s/%s_str.cfg", spawndir, MapName)
//load spawn file and create player spawn points
if (Load_SpawnFlie(1))
g_LoadSuccessed = true
else
g_LoadSuccessed = false
g_FwdKeyValue = register_forward(FM_KeyValue, "Forward_KeyValue");
return PLUGIN_CONTINUE
}
//load spawns from file, Return 0 when didn't load anything.
stock Load_SpawnFlie(type) //createEntity = 1 create an entity when load a point
{
if (file_exists(g_SpawnFile))
{
new ent_T, ent_CT
new Data[128], len, line = 0
new team[8], p_origin[3][8], p_angles[3][8]
new Float:origin[3], Float:angles[3]
while((line = read_file(g_SpawnFile, line, Data, 127, len)) != 0)
{
if (strlen(Data)<2) continue
parse(Data, team, 7, p_origin[0], 7, p_origin[1], 7, p_origin[2], 7, p_angles[0], 7, p_angles[1], 7, p_angles[2], 7)
origin[0] = str_to_float(p_origin[0]); origin[1] = str_to_float(p_origin[1]); origin[2] = str_to_float(p_origin[2]);
angles[0] = str_to_float(p_angles[0]); angles[1] = str_to_float(p_angles[1]); angles[2] = str_to_float(p_angles[2]);
if (equali(team, "T"))
{
if (type==1)
ent_T = fm_create_entity("info_player_deathmatch")
else
ent_T = fm_find_ent_by_class(ent_T, "info_player_deathmatch")
if (ent_T>0)
{
set_pev(ent_T, pev_iuser1, 1) // mark that create by map spawns editor
fm_entity_set_origin(ent_T, origin)
set_pev(ent_T, pev_angles, angles)
}
}
else if (equali(team, "CT"))
{
if (type==1)
ent_CT = fm_create_entity("info_player_start")
else
ent_CT = fm_find_ent_by_class(ent_CT, "info_player_start")
if (ent_CT>0)
{
set_pev(ent_CT, pev_iuser1, 1) // mark that create by map spawns editor
fm_entity_set_origin(ent_CT, origin)
set_pev(ent_CT, pev_angles, angles)
}
}
}
return 1
}
return 0
}
public event_restartgame()
{
if (g_Editing && file_exists(g_DieFile))
delete_file(g_DieFile)
g_DeathCheck_end = false
if (g_Editing)
{
Clear_AllEdit(0)
Load_SpawnFlie(0)
Spawns_To_Edit()
}
return PLUGIN_CONTINUE
}
// Remove & save bad spawn point where force user die.
public event_death()
{
if (!g_DeathCheck_end)
{
new string[12]
read_data(4, string, 11)
if (equal(string, "worldspawn"))
{
new id = read_data(2)
if (g_Editing)
{
new entList[1], team
find_sphere_class(id, EDIT_CLASSNAME, 30.0, entList, 1)
if (entList[0])
{
team = pev(entList[0], pev_iuser2) // team mark
if (team==1)
{
client_print(0, print_chat, ">> Auto-removed a bad %s spawn point.", "T")
g_EditT--
}
else
{
client_print(0, print_chat, ">> Auto-removed a bad %s spawn point.", "CT")
g_EditCT--
}
fm_remove_entity(entList[0])
return PLUGIN_CONTINUE
}
}
else
{
new team = get_user_team(id)
if (team==1) Point_WriteToFlie(g_DieFile, 1, id, 1)
else if (team==2) Point_WriteToFlie(g_DieFile, 2, id, 1)
}
}
}
return PLUGIN_CONTINUE
}
public event_newround()
{
set_task(3.0, "deathCheck_end")
}
public deathCheck_end()
{
g_DeathCheck_end = true
}
// create a edit point
stock CreateEditEntity(team, iEnt, offset)
{
new Float:fOrigin[3], Float:fAngles[3]
pev(iEnt, pev_origin, fOrigin)
pev(iEnt, pev_angles, fAngles)
fOrigin[2] += float(offset) //offset Z
new entity = fm_create_entity("info_target")
if (entity)
{
set_pev(entity, pev_classname, EDIT_CLASSNAME)
fm_entity_set_model(entity, (team==1) ? T_MDL:CT_MDL)
fm_entity_set_origin(entity, fOrigin)
set_pev(entity, pev_angles, fAngles)
set_pev(entity, pev_sequence, 4)
set_pev(entity, pev_iuser2, team) // team mark
return team
}
return 0
}
// clear up all edit points
stock Clear_AllEdit(team)
{
new entity
switch (team)
{
case 0:
{
while ((entity = fm_find_ent_by_class(entity, EDIT_CLASSNAME)))
fm_remove_entity(entity)
g_EditT = 0
g_EditCT = 0
}
case 1:
{
while ((entity = fm_find_ent_by_class(entity, EDIT_CLASSNAME)))
if (pev(entity, pev_iuser2)==1)
fm_remove_entity(entity)
g_EditT = 0
}
case 2:
{
while ((entity = fm_find_ent_by_class(entity, EDIT_CLASSNAME)))
if (pev(entity, pev_iuser2)==2)
fm_remove_entity(entity)
g_EditCT = 0
}
}
}
// convert origin spawns to edit points
stock Spawns_To_Edit()
{
new entity
g_EditT = 0
while ((entity = fm_find_ent_by_class(entity, "info_player_deathmatch")))
{
CreateEditEntity(1, entity, 0)
g_EditT++
}
entity = 0
g_EditCT = 0
while ((entity = fm_find_ent_by_class(entity, "info_player_start")))
{
CreateEditEntity(2, entity, 0)
g_EditCT++
}
}
stock Spawns_Count()
{
new entity
g_SpawnT = 0
while ((entity = fm_find_ent_by_class(entity, "info_player_deathmatch")))
g_SpawnT++
entity = 0
g_SpawnCT = 0
while ((entity = fm_find_ent_by_class(entity, "info_player_start")))
g_SpawnCT++
}
public check_Task(taskid)
{
SafeRangeCheck(taskid-CHECKTASKID, SPAWN_PRESENT_OFFSET)
Get_Edit_Point_By_Aim(taskid-CHECKTASKID)
}
// reset entity sequence
public reset_entity_stats(param)
{
new entity = param - RESETENTITYTASKID
if (pev_valid(entity))
{
set_pev(entity, pev_animtime, 0.0)
set_pev(entity, pev_framerate, 0.0)
set_pev(entity, pev_sequence, 4)
}
}
// set entity vangle[1]+turn
stock Entity_Turn_angle(entity, turn)
{
if (pev_valid(entity))
{
new Float:fAngles[3]
pev(entity, pev_angles, fAngles)
fAngles[1] += turn
if (fAngles[1]>=360) fAngles[1] -= 360
if (fAngles[1]<0) fAngles[1] += 360
set_pev(entity, pev_angles, fAngles)
}
}
// check edit point or wall distance to id
stock SafeRangeCheck(id, offset)
{
new safepostion = 1
new Float:fOrigin[3], Float:fAngles[3], Float:inFrontPoint[3], Float:HitPoint[3]
pev(id, pev_origin, fOrigin)
fOrigin[2] += offset // hight offset, same as Edit Point offset
pev(id, pev_angles, fAngles)
for (new i=0;i<360;i+=10)
{
fAngles[1] = float(i)
// get the id infront point for trace_line
Vector_By_Angle(fOrigin, fAngles, SAFEp2w * 2.0, 1, inFrontPoint)
// check id nearby wall
fm_trace_line(-1, fOrigin, inFrontPoint, HitPoint)
new distance = floatround(vector_distance(fOrigin, HitPoint))
// unsafe distance to wall
if (distance<SAFEp2w)
{
Make_TE_BEAMPOINTS(id, 0, fOrigin, HitPoint, 2, 255)
safepostion = 0
}
else if (distance < SAFEp2w * 1.5)
Make_TE_BEAMPOINTS(id, 2, fOrigin, HitPoint, 2, 255)
}
// check id nearby Edit Points
new entList[10], Float:vDistance
new Float:entity_origin[3]
find_sphere_class(0, EDIT_CLASSNAME, SAFEp2p * 1.5, entList, 9, fOrigin)
for(new i=0;i<10;i++)
{
if (entList[i])
{
pev(entList[i], pev_origin, entity_origin)
vDistance = vector_distance(fOrigin, entity_origin)
// unsafe location to Edit Points
if (vDistance < SAFEp2p)
{
Make_TE_BEAMPOINTS(id, 0, fOrigin, entity_origin, 5, 255)
set_pev(entList[i], pev_sequence, 64)
safepostion = 0
if (task_exists(entList[i]+RESETENTITYTASKID))
remove_task(entList[i]+RESETENTITYTASKID)
set_task(CHECKTIMER+0.1, "reset_entity_stats", entList[i]+RESETENTITYTASKID)
}
else
Make_TE_BEAMPOINTS(id, 1, fOrigin, entity_origin, 5, 255)
}
}
return safepostion
}
stock Get_Edit_Point_By_Aim(id)
{
new entList[1], team
new Float:fOrigin[3], Float:vAngles[3], Float:vecReturn[3]
pev(id, pev_origin, fOrigin)
fOrigin[2] += 10 // offset Z of id
pev(id, pev_v_angle, vAngles)
for(new Float:i=0.0;i<=1000.0;i+=20.0)
{
Vector_By_Angle(fOrigin, vAngles, i, 1, vecReturn)
//Make_TE_BEAMPOINTS(id, 3, fOrigin, vecReturn, 5, 255)
//client_print(0, print_chat, "fOrigin={%d, %d, %d}, vecReturn={%d, %d, %d}", floatround(fOrigin[0]), floatround(fOrigin[1]), floatround(fOrigin[2]), floatround(vecReturn[0]), floatround(vecReturn[1]), floatround(vecReturn[2]))
find_sphere_class(0, EDIT_CLASSNAME, 20.0, entList, 1, vecReturn)
if (entList[0])
{
// let entity have anim.
set_pev(entList[0], pev_animtime, 1.0)
set_pev(entList[0], pev_framerate, 1.0)
team = pev(entList[0], pev_iuser2)
client_print(id, print_center, "%s spawn #%d", (team==1) ? "T":"CT", entList[0])
if (task_exists(entList[0]+RESETENTITYTASKID))
remove_task(entList[0]+RESETENTITYTASKID)
set_task(CHECKTIMER+0.1, "reset_entity_stats", entList[0]+RESETENTITYTASKID)
break
}
}
return entList[0] // return entity if be found
}
/* FRU define in vector.inc
#define ANGLEVECTOR_FORWARD 1
#define ANGLEVECTOR_RIGHT 2
#define ANGLEVECTOR_UP 3
*/
stock Vector_By_Angle(Float:fOrigin[3], Float:vAngles[3], Float:multiplier, FRU, Float:vecReturn[3])
{
angle_vector(vAngles, FRU, vecReturn)
vecReturn[0] = vecReturn[0] * multiplier + fOrigin[0]
vecReturn[1] = vecReturn[1] * multiplier + fOrigin[1]
vecReturn[2] = vecReturn[2] * multiplier + fOrigin[2]
}
// draw laserBeam
stock Make_TE_BEAMPOINTS(id, color, Float:Vec1[3], Float:Vec2[3], width, brightness)
{
message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, {0, 0, 0}, id)
write_byte(TE_BEAMPOINTS) // TE_BEAMPOINTS = 0
write_coord(floatround(Vec1[0])) // start position
write_coord(floatround(Vec1[1]))
write_coord(floatround(Vec1[2]))
write_coord(floatround(Vec2[0])) // end position
write_coord(floatround(Vec2[1]))
write_coord(floatround(Vec2[2]))
write_short(Laser_Spr) // sprite index
write_byte(1) // starting frame
write_byte(0) // frame rate in 0.1's
write_byte(4) // life in 0.1's
write_byte(width) // line width in 0.1's
write_byte(0) // noise amplitude in 0.01's
write_byte(g_BeamColors[color][0])
write_byte(g_BeamColors[color][1])
write_byte(g_BeamColors[color][2])
write_byte(brightness) // brightness)
write_byte(0) // scroll speed in 0.1's
message_end()
}
stock Save_SpawnsFile()
{
if (file_exists(g_SpawnFile))
delete_file(g_SpawnFile)
new mapname[32], line[128]
get_mapname(mapname, 31)
format(line, 127, "/* %s T=%d, CT=%d */ Map Spawns Editor Format File", mapname, g_EditT, g_EditCT)
write_file(g_SpawnFile, line, -1)
new entity, team
while ((entity = fm_find_ent_by_class(entity, EDIT_CLASSNAME)))
{
team = pev(entity, pev_iuser2)
Point_WriteToFlie(g_SpawnFile, team, entity, 1)
}
return 1
}
stock Export_RipentFormatFile()
{
if (file_exists(g_EntFile))
delete_file(g_EntFile)
new entity, team
while ((entity =fm_find_ent_by_class(entity, EDIT_CLASSNAME)))
{
team = pev(entity, pev_iuser2)
Point_WriteToFlie(g_EntFile, team, entity, 2)
}
return 1
}
stock Export_Stripper2FormatFile()
{
if (file_exists(g_Stripper2File))
delete_file(g_Stripper2File)
new entity, team
while ((entity =fm_find_ent_by_class(entity, EDIT_CLASSNAME)))
{
team = pev(entity, pev_iuser2)
Point_WriteToFlie(g_Stripper2File, team, entity, 3)
}
return 1
}
// store one entity data to file
stock Point_WriteToFlie(Flie[], team, entity, saveformat)
{
new line[128], sTeam[32]
new nOrigin[3], nAngles[3]
new Float:fOrigin[3], Float:fAngles[3]
pev(entity, pev_origin, fOrigin)
pev(entity, pev_angles, fAngles)
FVecIVec(fOrigin, nOrigin)
FVecIVec(fAngles, nAngles)
if (nAngles[1]>=360) nAngles[1] -= 360
if (nAngles[1]<0) nAngles[1] += 360
switch(saveformat)
{
// write for plugin using format
case 1:
{
if (team==1)
sTeam = "T"
else
sTeam = "CT"
format(line, 127, "%s %d %d %d %d %d %d", sTeam, nOrigin[0], nOrigin[1], nOrigin[2], 0, nAngles[1], 0)
write_file(Flie, line, -1)
}
// write for ripent.exe format
case 2:
{
if (team==1)
sTeam = "info_player_deathmatch"
else
sTeam = "info_player_start"
format(line, 127, "{^n ^"classname^" ^"%s^"", sTeam)
write_file(Flie, line, -1)
format(line, 127, " ^"origin^" ^"%d %d %d^"", nOrigin[0], nOrigin[1], nOrigin[2])
write_file(Flie, line, -1)
format(line, 127, " ^"angle^" ^"0 %d 0^"^n}^n", nAngles[1])
write_file(Flie, line, -1)
}
// write for stripper2 format
case 3:
{
if (team==1)
sTeam = "info_player_deathmatch"
else
sTeam = "info_player_start"
format(line, 127, "{^n classname/%s", sTeam)
write_file(Flie, line, -1)
format(line, 127, " angle/%d", nAngles[1])
write_file(Flie, line, -1)
format(line, 127, " origin/%d %d %d^n}^n", nOrigin[0], nOrigin[1], nOrigin[2])
write_file(Flie, line, -1)
}
}
}
find_sphere_class ( aroundent, _lookforclassname[], Float:radius, entlist[], maxents, Float:origin[3] = {0.0, 0.0, 0.0} )
{
static entsFound, pSearchEnt, Float:EntOrigin[ 3 ], Classname[ 32 ];
entsFound = pSearchEnt = 0;
if ( aroundent > 0 ) { pev( aroundent, pev_origin, EntOrigin ); }
else
{
EntOrigin = origin;
}
while ( entsFound < maxents )
{
pSearchEnt = fm_find_ent_in_sphere( pSearchEnt, EntOrigin, radius )
if ( !pSearchEnt ) { break; }
else
{
pev( pSearchEnt, pev_classname, Classname, charsmax( Classname ) );
if( equal( Classname, _lookforclassname ) )
{
entlist[ entsFound++ ] = pSearchEnt;
}
}
}
return entsFound;
}
//////////////////////////////////////////////////////////
/* export spawns data to txt file for ripent.exe format */
/*
{ //(T)
"classname" "info_player_deathmatch"
"origin" "-384 1056 108"
"angle" "0 180 0"
}
{ //(CT)
"classname" "info_player_start"
"origin" "-128 -832 104"
"angle" "0 270 0"
}
*/
//////////////////////////////////////////////////////////