Поэтому, не написал, не каких своих попыток что то исправить, прошу не ругаться
- Код: Выделить всё
/*
v0.1 - [15.05.2012] - First Release
For - All Modes :)
http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community
*/
#include <amxmodx>
#include <fakemeta_util>
#include <engine>
#include <hamsandwich>
/* <<< Plugin Config >>> */
#define _Max_Portals 32 // Max Portals That Can Create & Use (32 - Max)
#define ADMIN_FLAGS ADMIN_RCON // Admin Flags For - Menu Using, Can Be - (ADMIN_IMMUNITY | ADMIN_BAN) ...
#define SPRITE_SIZE 1.0 // Portal Sprite Size
#define SPRITE_ANIMATION_SPEED 25.0
#define PORTAL_POINT_TRANSPARENCY 128.0
#define PORTAL_SPRITE "sprites/e-tele1.spr"
//#define PORTAL_TRICK // Enable Trick, When Player Can Duck & Move In Portal Point Location - Without Portation
#define KILL_ONLY_PLAYERS // Only Players Will Be Killed On Portation Point, Else - All Entities
#define SEARCHING_RADIUS 32.0 // Serching Radius In Portation Point
#define ORIGIN_DIFFERENCE 5.0 // Origin[2]++ When Portation Point Add
#define CLCMD_COMMAND "QuakeIII_Portals_Menu" // Create Menu
/* <<< End >>> */
/* <<< Do Not Modify! >>> */
#define Default_Rotate_Angle 22.5
#define None 0
#define NULL 0x0
#define Portal_Counter g_plugin_data[__Portal_Counter]
#define Max_Players g_plugin_data[__Max_Players]
#define Current_Portal(%1) g_plugin_data[%1 + 32]
#define MODEL_PIKE "models/q3/q3_Portal_Pike.mdl"
#define MODEL_BASE "models/q3/q3_Portal_Base.mdl"
#if _Max_Portals > 0x20
#define MAX_PORTALS 0x20
#else
#define MAX_PORTALS _:_Max_Portals
#endif
#define bit_bot_NOT(%1) (1 << (%1 - 1) & ~g_plugin_data[_Client_Bot])
#define bit_bot_add(%1) g_plugin_data[_Client_Bot] |= 1 << (%1 - 1)
#define bit_bot_sub(%1) g_plugin_data[_Client_Bot] &= ~(1 << (%1 - 1))
#define bit_bot(%1) g_plugin_data[_Client_Bot] & 1 << (%1 - 1)
enum _:__III_Data
{
_III_Portal_Colors,
_III_Portal_Origin,
_III_Point_Origin
}
enum _:_Colors
{
Float:_Color_Red,
Float:_Color_Green,
Float:_Color_Blue
}
enum _:_Create_Entity
{
_Create_Info_Target,
_Create_Env_Sprite
}
enum _:__I_Data
{
Float:_I_Portal_Angles,
Float:_I_Point_Angles
}
enum _:_Portal_Action(<<= 1)
{
_Portal_Move = 1,
_Portal_Spin
}
enum _:_Events
{
_Event_Portal,
_Event_Point
}
enum _:_Plugin_Data
{
__Max_Players,
__Clients_Keys[32],
__Clients_Data[32],
__Portal_Counter,
_Time_Remain,
_Client_Bot
}
enum _:_Trace_Params
{
_Trace_Land,
_Trace_World
}
enum _:_Portal_Parts
{
_Portal_Base,
_Portal_Pike_I,
_Portal_Pike_II,
_Portal_Start,
_Portal_Index,
_Portal_Point_Type,
_Portal_Using
}
new const Float:const_Angles[] =
{
0.0,
22.5,
45.0,
67.5,
90.0,
112.5,
135.0,
157.5,
180.0,
202.5,
225.0,
247.5,
270.0,
292.5,
315.0,
337.5
}
new const g_direction[][3] =
{
{0x20, NULL, 0x4b},
{0x20, 0x10, 0x4b},
{0x20, 0x20, 0x4b},
{0x10, 0x20, 0x4b},
{NULL, 0x20, 0x4b},
{-0x10, 0x20, 0x4b},
{-0x20, 0x20, 0x4b},
{-0x20, 0x10, 0x4b},
{-0x20, NULL, 0x4b},
{-0x20, -0x10, 0x4b},
{-0x20, -0x20, 0x4b},
{-0x10, -0x20, 0x4b},
{NULL, -0x20, 0x4b},
{0x10, -0x20, 0x4b},
{0x20, -0x20, 0x4b},
{0x20, -0x10, 0x4b}
}
#define PLUGIN "hl_QuakeIII_Portals"
#define VERSION "0.1"
#define AUTHOR "Turanga_Leela"
new
g_portal_data[MAX_PORTALS][_Portal_Parts],
g_plugin_data[_Plugin_Data],
Float:g_portal_data_III[MAX_PORTALS][__III_Data][3],
Float:g_portal_data_I[MAX_PORTALS][__I_Data],
g_config_path[64]
public plugin_precache()
{
precache_model(PORTAL_SPRITE)
precache_model(MODEL_BASE)
precache_model(MODEL_PIKE)
precache_sound("q3/telein.wav")
precache_sound("q3/teleout.wav")
}
public client_disconnect(id)
{
bit_bot_sub(id)
if(Current_Portal(id) > -1)
{
g_portal_data[Current_Portal(id)][_Portal_Using] = None
Current_Portal(id) = -1
}
}
public client_putinserver(id)
{
Current_Portal(id) = -1
if(is_user_bot(id))
{
bit_bot_add(id)
}
}
public On_Client_Death()
{
new id = read_data(2)
if(Current_Portal(id) > -1)
{
client_cmd(id, CLCMD_COMMAND)
}
}
public Change_OutPoint(id)
{
if(get_user_flags(id) & (ADMIN_FLAGS))
{
new
string[3],
value = None
read_argv(1, string, charsmax(string))
if(!(None < (value = str_to_num(string)) <= MAX_PORTALS))
{
client_print(id, print_chat, "<q3> Portals -> #Wrong Portal Index! [1 - %d]", MAX_PORTALS)
return
}
else if(value == Current_Portal(id) + 1)
{
client_print(id, print_chat, "<q3> Portals -> #This Is The Same Portal - Ignored!")
return
}
client_print(id, print_chat, "<q3> Portals -> #Done! [%d] - Is OutPoint For This Portal - [%d]", (g_portal_data[Current_Portal(id)][_Portal_Point_Type] = value), Current_Portal(id) + 1)
}
}
public plugin_cfg()
{
new string[64]
get_mapname(string, charsmax(string))
formatex(g_config_path, charsmax(g_config_path), "%s%s%s", "maps/", string, "_q3_portals.ini")
if(!Check_Config())
{
set_fail_state("FATAL ERROR: Can't Read Config")
return
}
Max_Players = get_maxplayers()
register_plugin(PLUGIN, VERSION, AUTHOR)
register_touch("q3_portal_start", "*", "On_Portal_Touch")
register_event("DeathMsg", "On_Client_Death", "a")
register_clcmd("<q3>_Portals_#OutPoint", "Change_OutPoint")
register_clcmd("<q3>_Portals_#colors", "Change_Colors")
register_clcmd(CLCMD_COMMAND, "Call_Menu")
new
line = None,
left[32],
line_len = None,
portal = -1,
counter = None,
Float:f_origin[3]
while(read_file(g_config_path, line++, string, charsmax(string), line_len))
{
switch(string[None])
{
case '%':
{
if(Portal_Counter == MAX_PORTALS)
{
server_print("^n****^n<q3> Portals: Max Portals Count Was Reached & Some Portals Will Be Ignored!^n****^n")
return
}
g_portal_data[(portal = (str_to_num(string[1]) - 1))][_Portal_Index] = portal + 1
continue
}
case 'A':
{
strtok(string, left, charsmax(left), string, charsmax(string), '=')
g_portal_data_I[portal][_I_Portal_Angles] = str_to_float(string[1])
}
case '.':
{
strtok(string, left, charsmax(left), string, charsmax(string), ' ')
g_portal_data_I[portal][_I_Point_Angles] = str_to_float(string)
}
case ':':
{
Get_Value_From_Config(left, string, portal, _III_Point_Origin)
}
case 'C':
{
Get_Value_From_Config(left, string, portal, _III_Portal_Colors)
}
case 'O':
{
Get_Value_From_Config(left, string, portal, _III_Portal_Origin)
}
case 'P':
{
strtok(string, left, charsmax(left), string, charsmax(string), '=')
g_portal_data[portal][_Portal_Point_Type] = str_to_num(string[1])
}
default:
{
continue
}
}
if(++counter ^ 0x6)
{
continue
}
counter = None
Portal_Initialize(portal)
f_origin[0] = g_portal_data_III[portal][_III_Portal_Origin][0]
f_origin[1] = g_portal_data_III[portal][_III_Portal_Origin][1]
f_origin[2] = g_portal_data_III[portal][_III_Portal_Origin][2]
Move_Portal(portal, (_Portal_Move | _Portal_Spin), floatround(g_portal_data_I[portal][_I_Portal_Angles] / Default_Rotate_Angle), f_origin)
}
}
public Change_Colors(id)
{
if(get_user_flags(id) & (ADMIN_FLAGS))
{
new
Colors[12],
Float:f_colors[3],
Left[4],
Right[8]
read_argv(1, Colors, charsmax(Colors))
strbreak(Colors, Left, charsmax(Left), Right, charsmax(Right))
f_colors[0] = float(str_to_num(Left))
strbreak(Right, Left, charsmax(Left), Right, charsmax(Right))
if(!((0.0 <= f_colors[0] <= 255.0) && (0.0 <= (f_colors[1] = float(str_to_num(Left))) <= 255.0) && (0.0 <= (f_colors[2] = float(str_to_num(Right))) <= 255.0)))
{
client_print(id, print_chat, "<q3> Portals -> #Wrong Colors [0-255]")
return
}
g_portal_data_III[Current_Portal(id)][_III_Portal_Colors][0] = f_colors[0]
g_portal_data_III[Current_Portal(id)][_III_Portal_Colors][1] = f_colors[1]
g_portal_data_III[Current_Portal(id)][_III_Portal_Colors][2] = f_colors[2]
set_pev(g_portal_data[Current_Portal(id)][_Portal_Start], pev_rendercolor, f_colors)
}
}
Get_Value_From_Config(Left[32], Right[64], index, Mode)
{
strtok(Right, Left, charsmax(Left), Right, charsmax(Right), '/')
strtok(Right, Left, charsmax(Left), Right, charsmax(Right), '/')
g_portal_data_III[index][Mode][0] = str_to_float(Left)
strtok(Right, Left, charsmax(Left), Right, charsmax(Right), '/')
g_portal_data_III[index][Mode][1] = str_to_float(Left)
g_portal_data_III[index][Mode][2] = str_to_float(Right)
}
Check_Trace(id, Mode, Portal_Index = -1)
{
new
i_origin[3],
Float:f_origin[3],
Float:f_end[3],
trace
get_user_origin(id, i_origin, 3)
f_origin[0] = float(i_origin[0])
f_origin[1] = float(i_origin[1])
f_origin[2] = float(i_origin[2]) + 0.5
switch(Mode)
{
case _Trace_Land:
{
xs_vec_sub(f_origin, Float:{0.0, 0.0, 2.5}, f_end)
engfunc(EngFunc_TraceLine, f_origin, f_end, DONT_IGNORE_MONSTERS | IGNORE_MISSILE, None, trace)
if(get_tr2(trace, TR_pHit) > None)
{
client_print(id, print_chat, "<q3> Portals -> #Bad Trace!")
return None
}
get_tr2(trace, TR_vecPlaneNormal, f_end)
if(f_end[2] != 1.0)
{
client_print(id, print_chat, "<q3> Portals -> #Ground Not Horizontal!")
return None
}
if(Portal_Index != -1)
{
Move_Portal(Portal_Index, _Portal_Move, None, f_origin)
return -1
}
new base = None
for(new b = None; b < MAX_PORTALS; b++)
{
if(!g_portal_data[b][_Portal_Base])
{
base = b
break
}
}
if(Portal_Initialize(base))
{
Move_Portal(base, (_Portal_Move | _Portal_Spin), None, f_origin)
return -1
}
}
case _Trace_World:
{
new
point = -1,
classname[32]
while((point = engfunc(EngFunc_FindEntityInSphere, point, f_origin, 32.0)))
{
if(point > Max_Players && pev_valid(point) && point == pev(point, pev_owner))
{
pev(point, pev_classname, classname, charsmax(classname))
if(equali(classname, "q3_portal_base", 0xE))
{
for(new i = None; i < MAX_PORTALS; i++)
{
if(g_portal_data[i][_Portal_Base] ^ point)
{
continue
}
if(g_portal_data[i][_Portal_Using])
{
get_user_name(g_portal_data[i][_Portal_Using], classname, charsmax(classname))
client_print(id, print_chat, "<q3> [Portals] -> #This Portal Using By - %s", classname)
return -2
}
client_print(id, print_chat, "<q3> [Portals] -> #You Catched Portal = `%d`", (Current_Portal(id) = (g_portal_data[i][_Portal_Index] - 1)) + 1)
g_portal_data[Current_Portal(id)][_Portal_Using] = id
return -1
}
}
}
}
}
}
return None
}
Event_Portation(id, OutPoint, Mode)
{
new
Float:origin[3],
Float:f_angles[3],
ent = -1
switch(Mode)
{
case _Event_Portal:
{
emit_sound(OutPoint, CHAN_AUTO, "q3/teleout.wav", VOL_NORM, ATTN_NORM, None, PITCH_NORM)
new origin_change = floatround(g_portal_data_I[OutPoint][_I_Portal_Angles] / Default_Rotate_Angle)
f_angles[1] = g_portal_data_I[OutPoint][_I_Portal_Angles]
origin[0] = g_portal_data_III[OutPoint][_III_Portal_Origin][0] + g_direction[origin_change][0]
origin[1] = g_portal_data_III[OutPoint][_III_Portal_Origin][1] + g_direction[origin_change][1]
origin[2] = g_portal_data_III[OutPoint][_III_Portal_Origin][2] + g_direction[origin_change][2]
}
case _Event_Point:
{
origin[0] = g_portal_data_III[OutPoint][_III_Point_Origin][0]
origin[1] = g_portal_data_III[OutPoint][_III_Point_Origin][1]
origin[2] = g_portal_data_III[OutPoint][_III_Point_Origin][2]
f_angles[1] = g_portal_data_I[OutPoint][_I_Point_Angles]
new ent = None
if((ent = Summon_Entity()))
{
set_pev(ent, pev_origin, origin)
emit_sound(ent, CHAN_AUTO, "q3/teleout.wav", VOL_NORM, ATTN_NORM, None, PITCH_NORM)
engfunc(EngFunc_RemoveEntity, ent)
}
}
}
while((ent = engfunc(EngFunc_FindEntityInSphere, ent, origin, Float:SEARCHING_RADIUS)))
{
#if defined KILL_ONLY_PLAYERS
if((None < (ent ^ id) <= Max_Players) && !pev(ent, pev_deadflag) && pev(ent, pev_health) > 0.0)
#else
if(pev_valid(ent ^ id) && pev(ent, pev_takedamage) && !pev(ent, pev_deadflag) && pev(ent, pev_health) > 0.0)
#endif
{
ExecuteHamB(Ham_Killed, ent, id, 0x2)
}
}
set_pev(id, pev_origin, origin)
set_pev(id, pev_velocity, Float:{0.0, 0.0, 0.0})
set_pev(id, pev_fixangle, 0x1)
set_pev(id, pev_angles, f_angles)
set_pev(id, pev_v_angle, Float:{0.0, 0.0, 0.0})
return 1
}
bool:Get_Point(id, InPoint, _Else_ = None)
{
switch(_Else_ ? _Else_ : g_portal_data[InPoint][_Portal_Point_Type])
{
case None:
{
return Get_Point(id, InPoint, random_num(0x2, 0x3) * -0x1)
}
case -0x1:
{
return bool:Event_Portation(id, InPoint, _Event_Point)
}
case -0x2:
{
new
_data[MAX_PORTALS],
counter = None
for(new i = None; i < Portal_Counter; i++)
{
if(g_portal_data[i][_Portal_Base] ^ g_portal_data[InPoint][_Portal_Base])
{
_data[counter++] = i
}
}
if(!counter)
{
return false
}
return bool:Event_Portation(id, _data[random(counter)], _Event_Portal)
}
case -0x3:
{
new
_data[MAX_PORTALS],
counter = None,
i
for(i = None; i < Portal_Counter; i++)
{
if(g_portal_data[i][_Portal_Point_Type] == -0x1)
{
_data[counter++] = i
}
}
if(!counter)
{
return Get_Point(id, InPoint, -0x2)
}
return bool:Event_Portation(id, _data[random(counter)], _Event_Point)
}
default:
{
if(!(None < g_portal_data[InPoint][_Portal_Point_Type] <= MAX_PORTALS))
{
return false
}
if(!g_portal_data[g_portal_data[InPoint][_Portal_Point_Type] - 1][_Portal_Base])
{
//server_print("^n****^n<q3> Portals: WARNING! Portal [%d] -> Hasn't Out-Portal^n****^n", g_portal_data[InPoint][_Portal_Index])
return Get_Point(id, InPoint, random_num(0x2, 0x3) * -0x1)
}
return bool:Event_Portation(id, g_portal_data[InPoint][_Portal_Point_Type] - 1, _Event_Portal)
}
}
return false
}
public On_Portal_Touch(ent, toucher)
{
static id_touch[32]
if((None < toucher <= Max_Players))
{
if(++id_touch[toucher - 1] & 0x2 || !pev_valid(ent) || pev(toucher, pev_deadflag) || pev(toucher, pev_health) <= 0.0)
{
id_touch[toucher - 1] = None
return
}
new Portal = pev(ent, pev_iuser3)
if(Get_Point(toucher, Portal))
{
if(bit_bot_NOT(toucher))
{
client_cmd(toucher, "spk sound/q3/telein.wav")
}
emit_sound(g_portal_data[Portal][_Portal_Base], CHAN_AUTO, "q3/teleout.wav", VOL_NORM, ATTN_NORM, None, PITCH_NORM)
}
}
}
Summon_Entity(Mode = _Create_Info_Target)
{
static class_cache[_Create_Entity]
static const g_classes[][] =
{
"info_target",
"env_sprite"
}
new ent
if((class_cache[Mode] || (class_cache[Mode] = engfunc(EngFunc_AllocString, g_classes[Mode]))) && (pev_valid((ent = engfunc(EngFunc_CreateNamedEntity, class_cache[Mode])))))
{
if(Mode & _Create_Env_Sprite)
{
engfunc(EngFunc_SetModel, ent, PORTAL_SPRITE)
set_pev(ent, pev_scale, Float:SPRITE_SIZE)
set_pev(ent, pev_framerate, Float:SPRITE_ANIMATION_SPEED)
set_pev(ent, pev_spawnflags, SF_SPRITE_STARTON)
}
dllfunc(DLLFunc_Spawn, ent)
return ent
}
return None
}
bool:Portal_Initialize(index)
{
new
counter = None,
ent = None
for(new i = _Portal_Base; i < _Portal_Start; i++)
{
if((ent = Summon_Entity()))
{
counter++
set_pev((g_portal_data[index][i] = ent), pev_owner, g_portal_data[index][_Portal_Base])
set_pev(ent, pev_iuser3, index)
set_pev(ent, pev_classname, "q3_portal_base")
set_pev(ent, pev_movetype, MOVETYPE_NOCLIP)
set_pev(ent, pev_solid, SOLID_BBOX)
set_pev(ent, pev_takedamage, DAMAGE_NO)
}
}
if((ent = Summon_Entity(_Create_Env_Sprite)))
{
counter++
set_pev((g_portal_data[index][_Portal_Start] = ent), pev_owner, g_portal_data[index][_Portal_Base])
set_pev(ent, pev_iuser3, index)
set_pev(ent, pev_classname, "q3_portal_start")
set_pev(ent, pev_movetype, MOVETYPE_NOCLIP)
set_pev(ent, pev_takedamage, DAMAGE_NO)
set_pev(ent, pev_solid, SOLID_TRIGGER)
set_pev(ent, pev_renderamt, Float:PORTAL_POINT_TRANSPARENCY)
// Rendering
set_pev(ent, pev_renderfx, kRenderFxNone)
set_pev(ent, pev_rendermode, kRenderTransAdd)
// End
new Float:Colors[3]
Colors[0] = g_portal_data_III[index][_III_Portal_Colors][_Color_Red]
Colors[1] = g_portal_data_III[index][_III_Portal_Colors][_Color_Green]
Colors[2] = g_portal_data_III[index][_III_Portal_Colors][_Color_Blue]
set_pev(ent, pev_rendercolor, Colors)
}
if(!(counter ^ 0x4))
{
if(!g_portal_data[index][_Portal_Index])
{
g_portal_data[index][_Portal_Index] = index + 1
}
engfunc(EngFunc_SetModel, g_portal_data[index][_Portal_Base], MODEL_BASE)
engfunc(EngFunc_SetModel, g_portal_data[index][_Portal_Pike_I], MODEL_PIKE)
engfunc(EngFunc_SetModel, g_portal_data[index][_Portal_Pike_II], MODEL_PIKE)
#if defined PORTAL_TRICK
engfunc(EngFunc_SetSize, g_portal_data[index][_Portal_Start], Float:{-2.5, -2.5, -2.5}, Float:{2.5, 2.5, 2.5})
#else
engfunc(EngFunc_SetSize, g_portal_data[index][_Portal_Start], Float:{-2.5, -2.5, -64.0}, Float:{2.5, 2.5, 2.5})
#endif
engfunc(EngFunc_SetSize, g_portal_data[index][_Portal_Base], Float:{-32.0, -32.0, 0.0}, Float:{32.0, 32.0, 12.0})
return bool:(++Portal_Counter)
}
Remove_Portal(index)
return false
}
bool:Check_Config()
{
if(!file_exists(g_config_path))
{
if(!write_file(g_config_path, ""))
{
return false
}
}
return true
}
Change_Config()
{
if(!(delete_file(g_config_path) && Check_Config()))
{
set_fail_state("FATAL ERROR: Can't Change Config File")
return
}
enum {Config_Data = 0x6}
enum
{
_Change_Portal_Colors,
_Change_Portal_Origin,
_Change_Point_Origin,
_Change_Portal_Angles,
_Change_Point_Angles,
_Change_Point_Type
}
new
config_line = None,
config_string[64],
string[12]
for(new i = None; i < MAX_PORTALS; i++)
{
if(g_portal_data[i][_Portal_Base])
{
if(i)
{
config_line++
}
formatex(string, charsmax(string), "%c%d%s", "%", g_portal_data[i][_Portal_Index], "^n{^n")
write_file(g_config_path, string, config_line)
config_line++
for(new j = None; j < Config_Data; j++)
{
switch(j)
{
case _Change_Portal_Colors:
{
formatex(config_string, charsmax(config_string), "%s%f%c%f%c%f%s", "Colors = /", g_portal_data_III[i][j][_Color_Red], "/", g_portal_data_III[i][j][_Color_Green], "/", g_portal_data_III[i][j][_Color_Blue], "^n")
}
case _Change_Portal_Origin:
{
formatex(config_string, charsmax(config_string), "%s%f%c%f%c%f%s", "Origin = /", g_portal_data_III[i][j][0], "/", g_portal_data_III[i][j][1], "/", g_portal_data_III[i][j][2], "^n")
}
case _Change_Point_Origin:
{
formatex(config_string, charsmax(config_string), "%s%f%c%f%c%f%s", ": /", g_portal_data_III[i][j][0], "/", g_portal_data_III[i][j][1], "/", g_portal_data_III[i][j][2], "^n")
}
case _Change_Portal_Angles:
{
formatex(config_string, charsmax(config_string), "%s%f%s", "Angles = ", g_portal_data_I[i][_I_Portal_Angles], "^n")
}
case _Change_Point_Angles:
{
formatex(config_string, charsmax(config_string), "%s%f%s", ". ", g_portal_data_I[i][_I_Point_Angles], "^n")
}
case _Change_Point_Type:
{
formatex(config_string, charsmax(config_string), "%s%d%s", "Point = ", g_portal_data[i][_Portal_Point_Type], "^n")
}
}
write_file(g_config_path, config_string, ++config_line)
}
write_file(g_config_path, "}", ++config_line)
}
}
}
public Config_Enable()
{
if(g_plugin_data[_Time_Remain])
{
g_plugin_data[_Time_Remain]--
}
}
public Menu_Config(id, Menu, Item)
{
if(Item == MENU_EXIT)
{
if(Current_Portal(id) > -0x1)
{
g_portal_data[Current_Portal(id)][_Portal_Using] = None
Current_Portal(id) = -0x1
}
menu_destroy(Menu)
return PLUGIN_HANDLED
}
new
s_Data[6],
s_Name[16],
i_Access = None,
i_Callback = None,
i = None
menu_item_getinfo(Menu, Item, i_Access, s_Data, charsmax(s_Data), s_Name, charsmax(s_Name), i_Callback)
new i_Key = str_to_num(s_Data)
switch(g_plugin_data[id])
{
case 1:
{
if(Current_Portal(id) > -1)
{
g_portal_data[Current_Portal(id)][_Portal_Using] = None
Current_Portal(id) = -1
}
switch(i_Key)
{
case 1:
{
if(Portal_Counter == MAX_PORTALS)
{
client_print(id, print_chat, "<q3> Portals -> #Error! - Max Count")
Main_Menu(id, 1)
return PLUGIN_HANDLED
}
Check_Trace(id, _Trace_Land)
i = 1
}
case 2:
{
switch(Check_Trace(id, _Trace_World))
{
case None:
{
client_print(id, print_chat, "<q3> [Portals] -> #Can't Find Portal")
i = 1
}
case -0x1:
{
i = 2
}
case -0x2:
{
i = 1
}
}
}
case 3:
{
if(g_plugin_data[_Time_Remain])
{
client_print(id, print_chat, "<q3> Portals: -> #Config Will Be Available After - [%d] Seconds", g_plugin_data[_Time_Remain])
Main_Menu(id, 1)
return PLUGIN_HANDLED
}
i = 3
}
}
}
case 2:
{
switch(i_Key)
{
case 1:
{
static id_rotate[32]
if(get_user_oldbutton(id) & IN_USE)
{
if(++id_rotate[id - 1] > 0xF)
{
id_rotate[id - 1] = None
}
}
else
{
if(--id_rotate[id - 1] < None)
{
id_rotate[id - 1] = 0xF
}
}
Move_Portal(Current_Portal(id), _Portal_Spin, id_rotate[id - 1])
i = 2
}
case 2:
{
Check_Trace(id, _Trace_Land, Current_Portal(id))
i = 2
}
case 3:
{
client_cmd(id, "messagemode <q3>_Portals_#colors")
i = 2
}
case 4:
{
i = 4
}
case 5:
{
Remove_Portal(Current_Portal(id))
client_print(id, print_chat, "<q3> Portals -> #Done! [%d] - Removed", Current_Portal(id) + 1)
i = 1
}
case 6:
{
i = 1
}
}
}
case 3:
{
i = 1
switch(i_Key)
{
case 1:
{
Change_Config()
client_print(id, print_chat, "<q3> Portals -> #Done! - All Changes Saved")
}
case 2:
{
if(!(delete_file(g_config_path) && Check_Config()))
{
client_print(id, print_chat, "<q3> Portals -> #Failed! - Can't Delete Config File")
Main_Menu(id, 1)
return PLUGIN_HANDLED
}
client_print(id, print_chat, "<q3> Portals -> #Done! - Config Updated")
}
}
if(i_Key ^ 0x3)
{
g_plugin_data[_Time_Remain] = 0x5
set_task(1.0, "Config_Enable", _, _, _, "a", 0x5)
}
}
case 4:
{
i = 2
switch(i_Key)
{
case 1:
{
client_cmd(id, "messagemode <q3>_Portals_#OutPoint")
}
case 2:
{
new Float:f_angles[3]
pev(id, pev_angles, f_angles)
g_portal_data_I[Current_Portal(id)][_I_Point_Angles] = f_angles[1]
g_portal_data[Current_Portal(id)][_Portal_Point_Type] = -0x1
pev(id, pev_origin, f_angles)
g_portal_data_III[Current_Portal(id)][_III_Point_Origin][0] = f_angles[0]
g_portal_data_III[Current_Portal(id)][_III_Point_Origin][1] = f_angles[1]
g_portal_data_III[Current_Portal(id)][_III_Point_Origin][2] = f_angles[2] + Float:ORIGIN_DIFFERENCE
client_print(id, print_chat, "<q3> Portals -> #Done! - New Point Ready")
}
case 3:
{
g_portal_data[Current_Portal(id)][_Portal_Point_Type] = -0x2
}
case 4:
{
g_portal_data[Current_Portal(id)][_Portal_Point_Type] = -0x3
}
case 5:
{
g_portal_data[Current_Portal(id)][_Portal_Point_Type] = None
}
}
}
}
Main_Menu(id, i)
return PLUGIN_HANDLED
}
Main_Menu(id, mode)
{
#define Menu(%1) Menu_Contents[%1 - 1]
new Menu_Contents[][] =
{
"\r#Main Menu",
"\r#Data",
"\r#Config",
"\r[Out-Point] -> #Type"
}
if(mode == 0x2)
{
formatex(Menu(mode), 0xF, "%s%d%c", "\r#Data - [", Current_Portal(id) + 1, "]")
}
new menu = menu_create(Menu(mode), "Menu_Config")
g_plugin_data[id] = mode
switch(mode)
{
case 1:
{
new string[32]
formatex(string, charsmax(string), "%s%d%s%d%c", "\w[Portal] -> #Add [", Portal_Counter, " / ", MAX_PORTALS, "]")
menu_additem(menu, string, "1")
menu_additem(menu, "\w[Portal] -> #Data", "2")
menu_addblank(menu, None)
menu_additem(menu, "\w[Config] -> #Change", "3")
}
case 2:
{
menu_additem(menu, "\w[Portal] -> #Rotate", "1")
menu_additem(menu, "\w[Portal] -> #Position", "2")
menu_additem(menu, "\w[In-Point -> #Colors", "3")
menu_addblank(menu, None)
menu_additem(menu, "\w[Out-Point] -> #Type", "4")
menu_addblank(menu, None)
menu_additem(menu, "\w[Portal] -> #Remove", "5")
menu_addblank(menu, None)
menu_additem(menu, "\w[Back]", "6")
}
case 3:
{
menu_additem(menu, "\w[Config] -> #Data Update (Save)", "1")
menu_additem(menu, "\w[Config] -> #Data Clear", "2")
menu_addblank(menu, None)
menu_additem(menu, "\w[Back]", "3")
}
case 4:
{
new _Menu_Content[][0x29] =
{
"\w#Specific Portal ",
"\w#Current Position - As An OutPoint ",
"\w#Random - Portal ",
"\w#Random - Point ",
"\w#Random - [Portal | Point] "
}
new i = None
switch(g_portal_data[Current_Portal(id)][_Portal_Point_Type])
{
case None:
{
i = 0x4
}
case -0x1, -0x2, -0x3:
{
i = g_portal_data[Current_Portal(id)][_Portal_Point_Type] * -0x1
}
}
formatex(_Menu_Content[i], 0x28, i ? "%s%c%c%c" : "%s%c%d%c", _Menu_Content[i], '(', i ? '+' : g_portal_data[Current_Portal(id)][_Portal_Point_Type], ')')
menu_additem(menu, _Menu_Content[None], "1")
menu_additem(menu, _Menu_Content[1], "2")
menu_addblank(menu, None)
menu_additem(menu, _Menu_Content[2], "3")
menu_additem(menu, _Menu_Content[3], "4")
menu_addblank(menu, None)
menu_additem(menu, _Menu_Content[4], "5")
menu_addblank(menu, None)
menu_additem(menu, "\w[Back]", "6")
}
}
menu_setprop(menu, MPROP_EXIT, MEXIT_ALL)
menu_display(id, menu, None)
return PLUGIN_CONTINUE
}
public Call_Menu(id)
{
if(get_user_flags(id) & (ADMIN_FLAGS))
{
Main_Menu(id, 1)
}
}
Move_Portal(index, Mode = _Portal_Spin, Angle = None, Float:origin[] = {0.0, 0.0, 0.0})
{
Portal_Valid(index)
if(Mode & _Portal_Move)
{
set_pev(g_portal_data[index][_Portal_Base], pev_origin, origin)
set_pev(g_portal_data[index][_Portal_Pike_I], pev_origin, origin)
set_pev(g_portal_data[index][_Portal_Pike_II], pev_origin, origin)
g_portal_data_III[index][_III_Portal_Origin][0] = origin[0]
g_portal_data_III[index][_III_Portal_Origin][1] = origin[1]
g_portal_data_III[index][_III_Portal_Origin][2] = origin[2]
origin[2] += 75.0
set_pev(g_portal_data[index][_Portal_Start], pev_origin, origin)
}
if(Mode & _Portal_Spin)
{
new Float:angles[3]
angles[0] = 0.0
angles[1] = const_Angles[Angle]
angles[2] = 0.0
set_pev(g_portal_data[index][_Portal_Base], pev_angles, angles)
set_pev(g_portal_data[index][_Portal_Pike_I], pev_angles, angles)
angles[1] += 180.0
set_pev(g_portal_data[index][_Portal_Pike_II], pev_angles, angles)
new
Float:first_mins[3],
Float:first_maxs[3],
Float:second_mins[3],
Float:second_maxs[3]
second_maxs[2] = first_maxs[2] = 128.0
second_mins[2] = first_mins[2] = 0.0
#define X_mins_I first_mins[0]
#define X_maxs_I first_maxs[0]
#define Y_mins_I first_mins[1]
#define Y_maxs_I first_maxs[1]
#define X_mins_II second_mins[0]
#define X_maxs_II second_maxs[0]
#define Y_mins_II second_mins[1]
#define Y_maxs_II second_maxs[1]
switch(const_Angles[Angle])
{
case 0.0, 180.0:
{
X_mins_II = X_mins_I = -12.0
X_maxs_II = X_maxs_I = 12.0
Y_mins_I = -69.0
Y_maxs_I = -32.0
Y_mins_II = 32.0
Y_maxs_II = 69.0
}
case 90.0, 270.0:
{
X_mins_I = -69.0
X_maxs_I = -32.0
Y_mins_II = Y_mins_I = -12.0
Y_maxs_II = Y_maxs_I = 12.0
X_mins_II = 32.0
X_maxs_II = 69.0
}
case 135.0, 315.0:
{
Y_mins_I = X_mins_I = 25.5
Y_maxs_I = X_maxs_I = 60.0
Y_mins_II = X_mins_II = -60.0
Y_maxs_II = X_maxs_II = -25.5
}
case 45.0, 225.0:
{
X_mins_II = Y_mins_I = -60.0
X_maxs_II = Y_maxs_I = -25.5
Y_mins_II = X_mins_I = 25.5
Y_maxs_II = X_maxs_I = 60.0
}
case 157.5, 337.5:
{
X_mins_I = 10.0
X_maxs_I = 38.0
Y_mins_I = 32.0
Y_maxs_I = 64.0
X_mins_II = -38.0
X_maxs_II = -10.0
Y_mins_II = -64.0
Y_maxs_II = -32.0
}
case 112.5, 292.5:
{
X_mins_I = 32.0
X_maxs_I = 64.0
Y_mins_I = 10.0
Y_maxs_I = 38.0
X_mins_II = -64.0
X_maxs_II = -32.0
Y_mins_II = -38.0
Y_maxs_II = -10.0
}
case 22.5, 202.5:
{
X_mins_I = -38.0
X_maxs_I = -10.0
Y_mins_I = 32.0
Y_maxs_I = 64.0
Y_mins_II = -64.0
Y_maxs_II = -32.0
X_mins_II = 10.0
X_maxs_II = 38.0
}
case 67.5, 247.5:
{
X_mins_I = -64.0
X_maxs_I = -32.0
Y_mins_I = 10.0
Y_maxs_I = 38.0
X_mins_II = 32.0
X_maxs_II = 64.0
Y_mins_II = -38.0
Y_maxs_II = -10.0
}
default:
{
set_fail_state("FATAL ERROR: Wrong Spin Angle -> Plugin OFF")
return
}
}
g_portal_data_I[index][_I_Portal_Angles] = const_Angles[Angle]
engfunc(EngFunc_SetSize, g_portal_data[index][_Portal_Pike_I], first_mins, first_maxs)
engfunc(EngFunc_SetSize, g_portal_data[index][_Portal_Pike_II], second_mins, second_maxs)
}
}
Portal_Valid(index)
{
new valid = None
for(new i = _Portal_Base; i <= _Portal_Start; i++)
{
if(!pev_valid(g_portal_data[index][i]) || pev(g_portal_data[index][i], pev_owner) ^ g_portal_data[index][_Portal_Base])
{
break
}
valid++
}
if(valid ^ 0x4)
{
set_fail_state("FATAL ERROR: Portal Not Valid -> Plugin OFF")
}
}
Remove_Portal(index)
{
Portal_Valid(index)
engfunc(EngFunc_RemoveEntity, g_portal_data[index][_Portal_Base])
engfunc(EngFunc_RemoveEntity, g_portal_data[index][_Portal_Pike_I])
engfunc(EngFunc_RemoveEntity, g_portal_data[index][_Portal_Pike_II])
engfunc(EngFunc_RemoveEntity, g_portal_data[index][_Portal_Start])
g_portal_data[index][_Portal_Using] = None
g_portal_data[index][_Portal_Base] = None
g_portal_data[index][_Portal_Pike_I] = None
g_portal_data[index][_Portal_Pike_II] = None
g_portal_data[index][_Portal_Start] = None
g_portal_data[index][_Portal_Index] = None
g_portal_data[index][_Portal_Point_Type] = None
if(Portal_Counter)
{
Portal_Counter--
}
}