/* Plugin generated by AMXX-Studio */
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
//#define ZOBMIE_PLAGUE
#if defined ZOBMIE_PLAGUE
#include <zombieplague>
#define GET_MONEY(%1) zp_get_user_ammo_packs(%1)
#define SET_MONEY(%1,%2) zp_set_user_ammo_packs(%1, %2)
#else
#include <cstrike>
#define GET_MONEY(%1) cs_get_user_money(%1)
#define SET_MONEY(%1,%2) cs_set_user_money(%1, %2)
#endif
#define PLUGIN "Build Teleport"
#define VERSION "0.1.1"
#define AUTHOR "PomanoB"
#define INPUT_MODEL "models/tp_by_xranitel.mdl"
#define BREAK_MODEL "models/metalplategibs.mdl"
#define HEALTH_OFFSET 1000
#define TP_TEAM pev_iuser3
#define TP_STATE pev_iuser1
#define TP_PLAYER pev_iuser2
#define TP_OWNER pev_euser1
#define TP_TYPE pev_iuser4
#define TP_TIME pev_fuser1
#define TP_LAST_TOUCH pev_fuser2
#define TP_LAST_HEALTH pev_fuser3
new const g_damage_sound[2][] =
{
"buttons/spark5.wav",
"buttons/spark6.wav"
}
new g_teleports[33][2]
new g_info_target_string
new const g_tp_class_name[] = "my_teleport_class_name"
enum BUILD_STATE
{
STATE_BUILDING,
STATE_NORMAL,
STATE_CHARGING,
STATE_TELEPORTING,
STATE_NO_EXIT,
STATE_EXIT
}
new g_maxplayers
new g_cvar_tp_cost, g_cvar_tp_health
new g_cvar_team_attack, g_cvar_repair_hp_cost
new g_cvar_heal_distance, g_cvar_teleport_enemy
new g_cvar_tp_time, g_cvar_build_speed
new g_cvar_charging_time, g_cvar_one_round
new g_cvar_tp_anonce, g_cvar_admin_flag
new g_break_model
new g_buildMenu
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_clcmd("say /tb", "cmdShowMenu")
register_forward(FM_Think, "fwdThink")
register_forward(FM_TraceLine, "fwdTraceLine", 1)
register_forward(FM_Touch, "fwdTouch")
RegisterHam(Ham_TakeDamage, "info_target", "fwdTakeDamage", 1)
register_event("TextMsg", "deleteAllTeleports", "a", "2&#Game_C", "2&#Game_w")
register_event("TextMsg", "deleteAllTeleports", "a", "2&#Game_will_restart_in")
register_event("TeamInfo", "eventTeamInfo", "a")
register_logevent("roundEnd", 2, "1=Round_End")
new callback = menu_makecallback("buildMenuCallback")
g_buildMenu = menu_create("Build Menu", "buildMenuHandler")
menu_additem(g_buildMenu, "Build Input", "0", _, callback)
menu_additem(g_buildMenu, "Build Output", "1", _, callback)
menu_additem(g_buildMenu, "Repair Input", "2", _, callback)
menu_additem(g_buildMenu, "Repair Output", "3", _, callback)
register_dictionary("tp_dollar.txt")
g_info_target_string = engfunc(EngFunc_AllocString,"info_target")
g_maxplayers = get_maxplayers()
g_cvar_tp_cost = register_cvar("tp_cost", "1000")
g_cvar_tp_health = register_cvar("tp_health", "2000.0")
g_cvar_team_attack = register_cvar("tp_team_attack", "1")
g_cvar_repair_hp_cost = register_cvar("tp_repair_hp_cost", "5")
g_cvar_heal_distance = register_cvar("tp_heal_distance", "100.0")
g_cvar_teleport_enemy = register_cvar("tp_teleport_enemy", "0")
g_cvar_tp_time = register_cvar("tp_teleport_time", "2.0")
g_cvar_build_speed = register_cvar("tp_teleport_build_speed", "5.1")
g_cvar_charging_time = register_cvar("tp_teleport_charging_time", "5.0")
g_cvar_one_round = register_cvar("tp_teleport_one_round", "0")
g_cvar_tp_anonce = register_cvar("tp_anonce", "15.0")
g_cvar_admin_flag = register_cvar("tp_admin_flag", "")
}
public plugin_precache()
{
precache_model(INPUT_MODEL)
g_break_model= precache_model(BREAK_MODEL)
new i
for (i = 0; i < sizeof g_damage_sound; i++)
precache_sound(g_damage_sound[i])
}
public cmdShowMenu(id)
{
new adminFlags[32]
get_pcvar_string(g_cvar_admin_flag, adminFlags, charsmax(adminFlags))
new iAdminFlag = read_flags(adminFlags)
if (!iAdminFlag || (get_user_flags(id)&iAdminFlag))
menu_display(id, g_buildMenu)
else
client_print(id, print_chat, "%L", id, "TP_NO_ACCESS")
}
public buildMenuCallback(id, menu, item)
{
new _access, command[3], cmd, callback
menu_item_getinfo(menu, item, _access, command, 2, _, _, callback)
cmd = str_to_num(command)
new itemName[64]
if (cmd <= 1)
{
new ent = g_teleports[id][cmd]
if (ent)
{
format(itemName, charsmax(itemName),
"%L", id, "TP_DESTROY", id, (cmd ? "TP_EXIT" : "TP_INPUT"), pev(ent, pev_health) - HEALTH_OFFSET)
}
else
{
format(itemName, charsmax(itemName),
"%L", id, "TP_BUILD", id, (cmd ? "TP_EXIT" : "TP_INPUT"),
get_pcvar_num(g_cvar_tp_cost))
}
}
else
{
cmd -=2
new ent = g_teleports[id][cmd], health = 0
if (ent)
health = HEALTH_OFFSET + get_pcvar_num(g_cvar_tp_health) - pev(ent, pev_health)
if (health)
{
format(itemName, charsmax(itemName),
"%L", id, "TP_REPAIR", id, (cmd ? "TP_EXIT" : "TP_INPUT"),
health * get_pcvar_num(g_cvar_repair_hp_cost))
}
else
{
format(itemName, charsmax(itemName),
"%L", id, "TP_NO_REPAIR", id, (cmd ? "TP_EXIT" : "TP_INPUT"))
}
}
menu_item_setname(menu, item, itemName)
}
public buildMenuHandler(id, menu, item)
{
if(item == MENU_EXIT)
return PLUGIN_HANDLED
new _access, command[3], cmd, callback
menu_item_getinfo(menu, item, _access, command, 2, _, _, callback)
cmd = str_to_num(command)
if (cmd < 2)
{
new building = g_teleports[id][cmd]
if (building)
destroyObject(id, cmd)
else
buildObjetc(id, cmd)
}
else
{
cmd -= 2
new building = g_teleports[id][cmd]
if (building)
{
new Float:tpOrigin[3], Float:youOrigin[3]
pev(building, pev_origin, tpOrigin)
pev(id, pev_origin, youOrigin)
if (get_distance_f(tpOrigin, youOrigin) <= get_pcvar_float(g_cvar_heal_distance))
{
new health = HEALTH_OFFSET + get_pcvar_num(g_cvar_tp_health)
if (checkCost(id, (health - pev(building, pev_health)) * get_pcvar_num(g_cvar_repair_hp_cost)))
{
set_pev(building, pev_health, float(health))
}
}
else
client_print(id, print_chat, "%L", id, "TP_LONG")
}
}
return PLUGIN_HANDLED
}
public destroyObject(id, object)
{
new tp = g_teleports[id][object]
if (tp)
{
new Float:origin[3]
pev(tp ,pev_origin, origin)
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, origin, 0)
write_byte(TE_BREAKMODEL) // TE id
engfunc(EngFunc_WriteCoord, origin[0])
engfunc(EngFunc_WriteCoord, origin[1])
engfunc(EngFunc_WriteCoord, origin[2])
write_coord(16) // size x
write_coord(16) // size y
write_coord(16) // size z
write_coord(random_num(-20, 20)) // velocity x
write_coord(random_num(-20, 20)) // velocity y
write_coord(10) // velocity z
write_byte(10) // random velocity
write_short(g_break_model) // model
write_byte(10) // count
write_byte(25) // life
write_byte(2) // flags
message_end()
g_teleports[id][object] = 0
engfunc(EngFunc_RemoveEntity, tp)
if (object)
{
new input = g_teleports[id][0]
if (pev_valid(input))
set_pev(input, TP_STATE, STATE_NO_EXIT)
}
}
}
public buildObjetc(id, object)
{
if (!checkCost(id, get_pcvar_num(g_cvar_tp_cost)))
return
new ent = engfunc(EngFunc_CreateNamedEntity, g_info_target_string)
set_pev(ent,pev_classname, g_tp_class_name)
engfunc(EngFunc_SetModel, ent, INPUT_MODEL)
new Float:mins[3] = {-16.0,-16.0, -8.0}
new Float:maxs[3] = {16.0,16.0,8.0}
set_pev(ent, pev_mins, mins)
set_pev(ent, pev_maxs, maxs)
engfunc(EngFunc_SetSize, ent, mins, maxs)
set_pev(ent, pev_animtime, 0.0)
set_pev(ent, pev_framerate, 0.0)
set_pev(ent, pev_sequence, 0)
set_pev(ent, pev_gaitsequence, 0)
set_pev(ent, pev_solid, SOLID_BBOX)
set_pev(ent, pev_movetype, MOVETYPE_FLY)
set_pev(ent, pev_rendermode, kRenderTransAdd)
set_pev(ent, pev_rendercolor, Float:{0.0, 255.0, 0.0})
set_pev(ent ,pev_renderamt,0.0)
new Float:health = HEALTH_OFFSET + get_pcvar_float(g_cvar_tp_health)
set_pev(ent, pev_health, health)
set_pev(ent, pev_takedamage, 1.0)
set_pev(ent,pev_flags, FL_MONSTER|FL_MONSTERCLIP)
new Float:origin[3], Float:angle[3]
pev(id ,pev_angles, angle)
// angle[2] = 0.0
// set_pev(ent, pev_angles, angle)
// pev(id ,pev_v_angle, angle)
// set_pev(ent, pev_v_angle, angle)
engfunc(EngFunc_MakeVectors, angle)
global_get(glb_v_forward, angle)
angle[2] = 0.0
xs_vec_mul_scalar(angle, 50.0, angle)
pev(id, pev_origin, origin)
xs_vec_add(angle, origin ,origin)
set_pev(ent, pev_origin, origin)
engfunc(EngFunc_DropToFloor, ent)
set_pev(ent, TP_OWNER, id)
set_pev(ent, TP_TEAM, get_user_team(id))
set_pev(ent, TP_STATE, STATE_BUILDING)
set_pev(ent, pev_nextthink,get_gametime() + 0.1)
set_pev(ent, TP_TYPE, object)
g_teleports[id][object] = ent
}
public fwdThink(ent)
{
static classname[32]
pev(ent ,pev_classname, classname, 31)
if (equal(classname, g_tp_class_name))
{
switch(pev(ent, TP_STATE))
{
case STATE_BUILDING:
{
static Float:current
pev(ent, pev_renderamt, current)
if (current < 255.0)
{
current += get_pcvar_float(g_cvar_build_speed)
if (current > 255.0)
current = 255.0
set_pev(ent, pev_renderamt, current)
}
else
{
if (pev(ent, TP_TYPE))
{
set_pev(ent, TP_STATE, STATE_EXIT)
static input
input = g_teleports[pev(ent, TP_OWNER)][0]
if (pev_valid(input) && BUILD_STATE:pev(input, TP_STATE) == STATE_NO_EXIT)
set_pev(input, TP_STATE, STATE_NORMAL)
}
else
{
static exitTp
exitTp = g_teleports[pev(ent, TP_OWNER)][1]
if (pev_valid(exitTp) && BUILD_STATE:pev(exitTp, TP_STATE) == STATE_EXIT)
set_pev(ent, TP_STATE, STATE_NORMAL)
else
set_pev(ent, TP_STATE, STATE_NO_EXIT)
}
set_pev(ent, pev_rendermode, kRenderNormal)
set_pev(ent, pev_renderfx, kRenderFxGlowShell)
set_pev(ent, pev_renderamt, 30.0)
if (pev(ent, TP_TEAM) == 1)
set_pev(ent, pev_rendercolor, Float:{255.0, 0.0, 0.0})
else
set_pev(ent, pev_rendercolor, Float:{0.0, 0.0, 255.0})
}
}
case STATE_TELEPORTING:
{
static Float:lastTouchTime
pev(ent, TP_LAST_TOUCH, lastTouchTime)
if (get_gametime() - lastTouchTime > 0.1)
{
set_pev(ent, TP_STATE, STATE_NORMAL)
}
}
case STATE_CHARGING:
{
static Float:readyTime
pev(ent, TP_TIME, readyTime)
if (get_gametime() >= readyTime)
{
set_pev(ent, TP_STATE, STATE_NORMAL)
}
}
}
set_pev(ent, pev_nextthink,get_gametime() + 0.1)
}
}
public fwdTraceLine(Float:v1[3], Float:v2[3], fNoMonsters, entToSkip, tr)
{
static pHit
pHit = get_tr2(tr, TR_pHit)
if (pev_valid(pHit))
{
static classname[32]
pev(pHit ,pev_classname, classname, 31)
if (equal(classname, g_tp_class_name))
{
static message[256]
static const states[BUILD_STATE][] =
{
"TP_STATUS_BUILDING",
"TP_STATUS_READY",
"TP_STATUS_CHARGING",
"TP_STATUS_TELEPORTING",
"TP_STATUS_NO_EXIT",
"TP_STATUS_EXIT"
}
format(message, charsmax(message),
"%L", entToSkip, "TP_STATUS", entToSkip,
(pev(pHit, TP_TYPE) ? "TP_EXIT" : "TP_INPUT"),
entToSkip, states[BUILD_STATE:pev(pHit, TP_STATE)],
(pev(pHit, pev_health) - HEALTH_OFFSET))
client_print(entToSkip, print_center, message)
}
}
}
public fwdTouch(id, ent)
{
if (1 <= id <= g_maxplayers && pev_valid(ent))
{
static classname[32]
pev(ent ,pev_classname, classname, 31)
if (equal(classname, g_tp_class_name) && ent == pev(id, pev_groundentity))
{
static BUILD_STATE:tpState
tpState = BUILD_STATE:pev(ent, TP_STATE)
if (tpState == STATE_NORMAL && (get_pcvar_num(g_cvar_teleport_enemy) || get_user_team(id) == pev(ent, TP_TEAM)))
{
set_pev(ent, TP_STATE, STATE_TELEPORTING)
set_pev(ent, TP_PLAYER, id)
set_pev(ent, TP_TIME, get_gametime() + get_pcvar_float(g_cvar_tp_time))
}
else
if (tpState == STATE_TELEPORTING && pev(ent, TP_PLAYER) == id)
{
static Float:tpTime
pev(ent, TP_TIME, tpTime)
if (tpTime <= get_gametime())
{
static Float:origin[3], tp
tp = g_teleports[pev(ent, TP_OWNER)][1]
pev(tp, pev_origin, origin)
origin[2]+=50.0
static tr
tr = 0
engfunc(EngFunc_TraceHull, origin, origin, 0, pev(id, pev_flags) & FL_DUCKING ? HULL_HEAD : HULL_HUMAN, 0, tr)
if (!get_tr2(tr, TR_StartSolid) && !get_tr2(tr, TR_AllSolid) && get_tr2(tr, TR_InOpen))
{
createEffect(id)
set_pev(id, pev_origin, origin)
/*
set_pev(id, pev_fixangle, 1)
pev(tp, pev_angles, origin)
set_pev(id ,pev_angles, origin)
pev(tp, pev_v_angle, origin)
set_pev(id ,pev_v_angle, origin)
set_pev(id, pev_fixangle, 1)
*/
set_pev(ent, TP_STATE, STATE_CHARGING)
set_pev(ent, TP_TIME, get_gametime() + get_pcvar_float(g_cvar_charging_time))
}
else
{
client_print(id, print_center, "%L", id, "TP_NO_SPACE")
set_pev(ent, TP_STATE, STATE_NORMAL)
}
free_tr2(tr)
}
else
set_pev(ent, TP_LAST_TOUCH, get_gametime())
}
}
}
}
public fwdTakeDamage(ent, idinflictor, idattacker, Float:damage, damagebits)
{
static classname[32]
pev(ent, pev_classname, classname, 31)
if (equal(classname, g_tp_class_name))
{
static owner
owner = pev(ent, TP_OWNER)
if (!get_pcvar_num(g_cvar_team_attack) && get_user_team(idattacker) == pev(ent, TP_TEAM))
return HAM_SUPERCEDE
static health
health = pev(ent, pev_health)
if (health - HEALTH_OFFSET - damage < 0.0)
{
static type
type = pev(ent, TP_TYPE)
set_hudmessage(255, 0, 0, 0.04, -1.0, 0, 6.0, 3.0)
show_hudmessage(owner, "%L", owner, "TP_DESTROYED", owner,
(type ? "TP_EXIT" : "TP_INPUT"))
destroyObject(owner, type)
}
else
{
set_hudmessage(255, 0, 0, 0.04, -1.0, 0, 6.0, 1.0)
show_hudmessage(owner, "%L", owner, "TP_ATTACKED", owner,
(pev(ent, TP_TYPE) ? "TP_EXIT" : "TP_INPUT"))
static Float:origin[3]
pev(ent, pev_origin, origin)
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, origin, 0)
write_byte(TE_SPARKS)
engfunc(EngFunc_WriteCoord, origin[0])
engfunc(EngFunc_WriteCoord, origin[1])
engfunc(EngFunc_WriteCoord, origin[2])
message_end()
emit_sound(ent, CHAN_VOICE,
g_damage_sound[random_num(0, sizeof g_damage_sound - 1)],
random_float(0.7, 1.0),
ATTN_NORM, 0, PITCH_NORM)
}
}
return HAM_IGNORED
}
public client_disconnect(id)
{
destroyObject(id, 0)
destroyObject(id, 1)
remove_task(id)
}
public createEffect(id)
{
static msgScreenFade
if (!msgScreenFade)
msgScreenFade = get_user_msgid("ScreenFade")
message_begin(MSG_ONE, msgScreenFade, _, id)
write_short(1000)
write_short(1000)
write_short(0x0)
write_byte(200)
write_byte(200)
write_byte(200)
write_byte(255)
message_end()
}
public deleteAllTeleports()
{
new i
for (i = 1; i <= g_maxplayers; i++)
{
destroyObject(i, 0)
destroyObject(i, 1)
}
}
public eventTeamInfo()
{
new id = read_data(1)
new team[10], iTeam
read_data(2, team, 9)
static teams[33]
if (team[0] == 'C')
iTeam = 2
else
if (team[0] == 'T')
iTeam = 1
else
iTeam = 3
if (iTeam != teams[id])
{
destroyObject(id, 0)
destroyObject(id, 1)
}
teams[id] = iTeam
}
public roundEnd()
{
if (get_pcvar_num(g_cvar_one_round))
deleteAllTeleports()
}
public client_putinserver(id)
{
new Float:anonce = get_pcvar_float(g_cvar_tp_anonce)
if (anonce)
set_task(anonce, "showMessage", id)
}
public showMessage(id)
{
client_print(id, print_chat, "%L", id, "TP_WELCOME")
}
public bool:checkCost(id, cost)
{
new money = GET_MONEY(id)
if (money >= cost)
{
money -= cost
SET_MONEY(id, money)
return true
}
client_print(id, print_center, "%L", id, "TP_NOT_MONEY")
return false
}
/* Portal gun is cooming soon */