Иконка ресурса

Walkguard 1.0.0

Нет прав для скачивания
Сообщения
1,291
Реакции
2,288
Помог
57 раз(а)
Сообщения
839
Реакции
519
Помог
12 раз(а)
еще б модели какие-либо можно было туда втыкать, как преграды
типа стенки, ящики
 
Сообщения
160
Реакции
170
Помог
1 раз(а)
BalbuR,
#include amxmodx
#include xs
#include fakemeta
#include hamsandwich

#define MinDist 100.0
#define MaxDist 500.0
#define ChangMoveDist 10.0

new GibsModel
new DustSprite
new mapname[32]
new mapfile[64]
new EntMove[33]
new EntThrow[33]
new bool:IsMove[33]
new Float:fMoveDistance[33]
new bool:IsChageDistBack[33]
new Float:fBoxCenterZ = 21.61
new bool:IsChageDistForward[33]
new Float:fBoxMaxs[3] = {21.72, 21.72, 43.21}
new Float:fBoxMins[3] = {-21.72, -21.72, 0.01}

new breakable_sound[3][] = {
"debris/bustcrate1.wav",
"debris/bustcrate2.wav",
"debris/bustcrate3.wav"
}

new damage_sound[3][] = {
"debris/wood1.wav",
"debris/wood2.wav",
"debris/wood3.wav"
}

new other_sound[3][] = {
"items/box_move_on.wav",
"items/box_move_off.wav",
"items/box_warning.wav"
}

public plugin_init() {
get_mapname(mapname, 31)
register_cvar("box_health", "300")
register_concmd("box_use", "box_use")
register_concmd("box_throw", "box_throw")
register_concmd("box_create", "box_create")
RegisterHam(Ham_Spawn, "player", "fw_spawn")
format(mapfile, 63, "maps/%s_boxes.cfg",mapname)
RegisterHam(Ham_Touch, "info_target", "fw_touch")
RegisterHam(Ham_Think, "info_target", "fw_think")
RegisterHam(Ham_Killed, "info_target", "fw_killed")
register_concmd("box_delete_all", "box_delete_all")
register_concmd("box_create_exec", "box_create_exec")
register_concmd("box_save_mapfile", "box_save_mapfile")
register_concmd("box_load_mapfile", "box_load_mapfile")
register_concmd("box_reload_mapfile", "box_reload_mapfile")
register_concmd("box_delete_mapfile", "box_delete_mapfile")
register_concmd("box_delete_current", "box_delete_current")
RegisterHam(Ham_TakeDamage, "info_target", "fw_takedamage")
register_concmd("box_delete_all_saved", "box_delete_all_saved")
register_concmd("+box_movedist_back", "box_movedist_back_plus")
register_concmd("-box_movedist_back", "box_movedist_back_minus")
register_concmd("+box_movedist_forward", "box_movedist_forward_plus")
register_concmd("-box_movedist_forward", "box_movedist_forward_minus")
if(get_user_msgid("HLTV") > 0)
register_event("HLTV", "event_hltv", "a", "1=0", "2=0")
if(file_exists(mapfile))
server_cmd("exec %s",mapfile)
register_plugin("Box Creator", "1.0", "PahanCS")
}

public plugin_precache() {
precache_model("models/box.mdl")
GibsModel = precache_model("models/box_gibs.mdl")
DustSprite = precache_model("sprites/box_dust.spr")
for(new i=0; i<3; i++) {
precache_sound(breakable_sound)
precache_sound(damage_sound)
precache_sound(other_sound)
}
}

public fw_spawn(id) {
if(is_user_alive(id)) {
static ent
ent = get_moving_box(id)
if(pev_valid(ent))
fm_set_rendering(ent, kRenderFxNone, 0, 0, 0, kRenderNormal, 0)
set_moving_box(id, 0)
IsMove[id] = false
ent = get_throwing_box(id)
if(pev_valid(ent))
set_thrower_box(ent, 0)
set_throwing_box(id, 0)
}
return HAM_IGNORED
}

public fw_touch(ent, idother) {
if(!is_entity_box_breakable(ent) || idother < 0 || pev(idother, pev_solid) < SOLID_BBOX)
return HAM_IGNORED
static attacker
attacker = get_thrower_box(ent)
if(!is_user_connected(attacker) || attacker == idother)
return HAM_IGNORED
static Float:fVelocity[3], Float:fLength
pev(ent, pev_velocity, fVelocity)
fLength = vector_length(fVelocity)
if(fLength < 300.0) {
set_thrower_box(ent, 0)
set_throwing_box(attacker, 0)
return HAM_IGNORED
}
fLength /= 10.0
if(is_user_connected(idother)) {
if(get_user_team(attacker) != get_user_team(idother))
ExecuteHamB(Ham_TakeDamage, idother, attacker, attacker, fLength / 2, DMG_GENERIC)
else
ExecuteHamB(Ham_TakeDamage, idother, attacker, attacker, fLength, DMG_GENERIC)
}
else if(is_damaging_entity(idother))
ExecuteHamB(Ham_TakeDamage, idother, attacker, attacker, fLength, DMG_GENERIC)
set_thrower_box(ent, 0)
set_throwing_box(attacker, 0)
ExecuteHamB(Ham_TakeDamage, ent, attacker, attacker, fLength, DMG_GENERIC)
return HAM_IGNORED
}

public fw_think(ent) {
if(!is_entity_box_breakable(ent))
return HAM_IGNORED
static idmover
idmover = get_mover_box(ent)
if(!is_user_alive(idmover)) {
if(idmover) {
set_mover_box(ent, 0)
fm_set_rendering(ent, kRenderFxNone, 0, 0, 0, kRenderNormal, 0)
if(is_normal_index(idmover)) {
set_moving_box(idmover, 0)
IsMove[idmover] = false
}
}
if(pev(ent, pev_flags) & FL_ONGROUND && fm_distance_to_floor(ent) > 0.0) {
static Float:fEntVelocity[3]
fEntVelocity[0] = 0.0; fEntVelocity[1] = 0.0
fEntVelocity[2] = -8191.0
set_pev(ent, pev_velocity, fEntVelocity)
}
set_pev(ent, pev_nextthink, get_gametime() + 0.1)
return HAM_IGNORED
}
if(!IsMove[idmover]) {
set_moving_box(idmover, 0)
set_mover_box(ent, 0)
fm_set_rendering(ent, kRenderFxNone, 0, 0, 0, kRenderNormal, 0)
set_pev(ent, pev_nextthink, get_gametime() + 0.1)
return HAM_IGNORED
}
if(IsChageDistForward[idmover]) {
fMoveDistance[idmover] += ChangMoveDist
if(fMoveDistance[idmover] > MaxDist) {
fMoveDistance[idmover] = MaxDist
}
}
else if(IsChageDistBack[idmover]) {
fMoveDistance[idmover] -= ChangMoveDist
if(fMoveDistance[idmover] < MinDist) {
fMoveDistance[idmover] = MinDist
}
}
static Float:fOrigin[3], Float:fAimOrigin[3], Float:fEntOrigin[3],
Float:fDirection[3], Float:fMoveto[3], Float:fVelocity[3], Float:fLength
pev(idmover, pev_origin, fOrigin)
fm_get_aimorigin_dist(idmover, MaxDist, fAimOrigin)
pev(ent, pev_origin, fEntOrigin)
fAimOrigin[2] -= fBoxCenterZ
xs_vec_sub(fAimOrigin, fOrigin, fDirection)
fLength = get_distance_f(fAimOrigin, fOrigin)
if(fLength < 1.0)
fLength = 1.0
fMoveto[0] = fOrigin[0] + fDirection[0] * fMoveDistance[idmover] / fLength
fMoveto[1] = fOrigin[1] + fDirection[1] * fMoveDistance[idmover] / fLength
fMoveto[2] = fOrigin[2] + fDirection[2] * fMoveDistance[idmover] / fLength
fVelocity[0] = (fMoveto[0] - fEntOrigin[0]) * 8
fVelocity[1] = (fMoveto[1] - fEntOrigin[1]) * 8
fVelocity[2] = (fMoveto[2] - fEntOrigin[2]) * 8
set_pev(ent, pev_velocity, fVelocity)
set_pev(ent, pev_nextthink, get_gametime() + 0.1)
return HAM_IGNORED
}

public fw_killed(ent, idattacker, shouldgib) {
if(!is_entity_box_breakable(ent))
return HAM_IGNORED
static id, Float:fEntOrigin[3]
id = get_mover_box(ent)
if(is_normal_index(id)) {
set_moving_box(id, 0)
IsMove[id] = false
}
id = get_thrower_box(ent)
if(is_normal_index(id))
set_throwing_box(id, 0)
pev(ent, pev_origin, fEntOrigin)
engfunc(EngFunc_EmitSound, ent, CHAN_AUTO, breakable_sound[random_num(0, 2)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
create_dust(fEntOrigin)
create_breakmodel(fEntOrigin)
return HAM_IGNORED
}

public fw_takedamage(ent, idinflictor, idattacker, Float:damage, damagebits) {
if(!is_entity_box_breakable(ent))
return HAM_IGNORED
static Float:fEntOrigin[3]
pev(ent, pev_origin, fEntOrigin)
if(is_inflictor_grenade(idinflictor) && damage <= 0.0) {
static Float:fInfOrigin[3]
pev(idinflictor, pev_origin, fInfOrigin)
damage = 300.0 - (get_distance_f(fEntOrigin, fInfOrigin) - 130.0)
SetHamParamFloat(4, damage > 0.0 ? damage:0.0)
engfunc(EngFunc_EmitSound, ent, CHAN_AUTO, damage_sound[random_num(0, 2)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
create_dust(fEntOrigin)
box_push_from_grenade(ent, idinflictor, damage)
return HAM_HANDLED
}
else if(is_user_connected(idattacker))
box_push_from_attacker(ent, idattacker, damage)
engfunc(EngFunc_EmitSound, ent, CHAN_AUTO, damage_sound[random_num(0, 2)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
create_dust(fEntOrigin)
return HAM_IGNORED
}

public event_hltv() {
if(!file_exists(mapfile))
return PLUGIN_CONTINUE
static fb
fb = engfunc(EngFunc_FindEntityByString, -1, "classname", "box_breakable")
while(fb > 0) {
if(pev_valid(fb) && is_saved_box(fb)) {
static id
id = get_mover_box(fb)
if(is_normal_index(id)) {
set_moving_box(id, 0)
IsMove[id] = false
}
id = get_thrower_box(fb)
if(is_normal_index(id))
set_throwing_box(id, 0)
engfunc(EngFunc_RemoveEntity, fb)
}
fb = engfunc(EngFunc_FindEntityByString, fb, "classname", "box_breakable")
}
server_cmd("exec %s",mapfile)
return PLUGIN_CONTINUE
}

public box_use(id) {
if(!IsMove[id]) {
static ent
ent = fm_get_aiment_dist(id, MaxDist)
if(is_entity_box_breakable(ent) && get_mover_box(ent) < 1) {
if(fMoveDistance[id] > MaxDist)
fMoveDistance[id] = MaxDist
if(fMoveDistance[id] < MinDist)
fMoveDistance[id] = MinDist
IsMove[id] = true
fm_set_rendering(ent, kRenderFxNone, 10, 10, 255, kRenderTransColor, 100)
set_thrower_box(ent, 0)
set_moving_box(id, ent)
set_mover_box(ent, id)
client_cmd(id, "spk %s",other_sound[0])
}
else
client_cmd(id, "spk %s",other_sound[2])
}
else {
static ent
ent = get_moving_box(id)
if(pev_valid(ent) && get_mover_box(ent) == id) {
set_moving_box(id, 0)
set_mover_box(ent, 0)
fm_set_rendering(ent, kRenderFxNone, 0, 0, 0, kRenderNormal, 0)
IsMove[id] = false
client_cmd(id, "spk %s",other_sound[1])
}
else
client_cmd(id, "spk %s",other_sound[2])
}
return PLUGIN_CONTINUE
}

public box_throw(id) {
if(!is_user_alive(id) || !IsMove[id]) {
client_cmd(id, "spk %s",other_sound[2])
return PLUGIN_CONTINUE
}
static ent
ent = get_moving_box(id)
if(pev_valid(ent) && get_mover_box(ent) == id) {
fm_set_rendering(ent, kRenderFxNone, 0, 0, 0, kRenderNormal, 0)
set_moving_box(id, 0)
set_mover_box(ent, 0)
IsMove[id] = false
static Float:fThrowVelocity[3]
get_throw_velocity(id, fThrowVelocity)
set_pev(ent, pev_velocity, fThrowVelocity)
set_throwing_box(id, ent)
set_thrower_box(ent, id)
}
else
client_cmd(id, "spk %s",other_sound[2])
return PLUGIN_CONTINUE
}

public box_movedist_back_plus(id) {
if(!is_user_alive(id) || !IsMove[id]) {
IsChageDistBack[id] = false
client_cmd(id, "spk %s",other_sound[2])
return PLUGIN_CONTINUE
}
IsChageDistBack[id] = true
return PLUGIN_CONTINUE
}

public box_movedist_back_minus(id) {
if(IsChageDistBack[id])
IsChageDistBack[id] = false
return PLUGIN_CONTINUE
}

public box_movedist_forward_plus(id) {
if(!is_user_alive(id) || !IsMove[id]) {
IsChageDistForward[id] = false
client_cmd(id, "spk %s",other_sound[2])
return PLUGIN_CONTINUE
}
IsChageDistForward[id] = true
return PLUGIN_CONTINUE
}

public box_movedist_forward_minus(id) {
if(IsChageDistForward[id])
IsChageDistForward[id] = false
return PLUGIN_CONTINUE
}

public box_create(id) {
if(!is_user_alive(id) || IsMove[id]) {
client_cmd(id, "spk %s",other_sound[2])
return PLUGIN_CONTINUE
}
static Float:fEntOrigin[3]
fm_get_aimorigin_dist(id, MinDist, fEntOrigin)
fEntOrigin[2] -= fBoxCenterZ
static ent
ent = create_box(fEntOrigin)
if(ent <= 0) {
client_cmd(id, "spk %s",other_sound[2])
return PLUGIN_CONTINUE
}
set_moving_box(id, ent)
set_mover_box(ent, id)
IsMove[id] = true
if(fMoveDistance[id] > MaxDist)
fMoveDistance[id] = MaxDist
if(fMoveDistance[id] < MinDist)
fMoveDistance[id] = MinDist
fm_set_rendering(ent, kRenderFxNone, 10, 10, 255, kRenderTransColor, 100)
set_pev(ent, pev_nextthink, get_gametime() + 0.1)
client_cmd(id, "spk %s",other_sound[0])
return PLUGIN_CONTINUE
}

public box_delete_all(id) {
static fb, bool:is_del; is_del = false
fb = engfunc(EngFunc_FindEntityByString, -1, "classname", "box_breakable")
while(fb > 0) {
if(pev_valid(fb)) {
static id
id = get_mover_box(fb)
if(is_normal_index(id)) {
set_moving_box(id, 0)
IsMove[id] = false
}
id = get_thrower_box(fb)
if(is_normal_index(id))
set_throwing_box(id, 0)
is_del = true
engfunc(EngFunc_RemoveEntity, fb)
}
fb = engfunc(EngFunc_FindEntityByString, fb, "classname", "box_breakable")
}
if(is_del) {
client_print(id, print_chat, "[box] all boxes were deleted !")
client_cmd(id, "spk %s",other_sound[0])
}
else {
client_print(id, print_chat, "[box] not a one box is not deleted !")
client_cmd(id, "spk %s",other_sound[2])
}
return PLUGIN_CONTINUE
}

public box_delete_all_saved(id) {
static fb, bool:is_del; is_del = false
fb = engfunc(EngFunc_FindEntityByString, -1, "classname", "box_breakable")
while(fb > 0) {
if(pev_valid(fb) && is_saved_box(fb)) {
static id
id = get_mover_box(fb)
if(is_normal_index(id)) {
set_moving_box(id, 0)
IsMove[id] = false
}
id = get_thrower_box(fb)
if(is_normal_index(id))
set_throwing_box(id, 0)
is_del = true
engfunc(EngFunc_RemoveEntity, fb)
}
fb = engfunc(EngFunc_FindEntityByString, fb, "classname", "box_breakable")
}
if(is_del) {
client_print(id, print_chat, "[box] all boxes saved were deleted !")
client_cmd(id, "spk %s",other_sound[0])
}
else {
client_print(id, print_chat, "[box] not a one box saved is not deleted !")
client_cmd(id, "spk %s",other_sound[2])
}
return PLUGIN_CONTINUE
}

public box_create_exec(id) {
static cmd1[32], cmd2[32], cmd3[32], cmd4[7], mark, Float:fOrigin[3], ent
read_argv(1, cmd1, 31)
read_argv(2, cmd2, 31)
read_argv(3, cmd3, 31)
read_argv(4, cmd4, 6)
fOrigin[0] = str_to_float(cmd1)
fOrigin[1] = str_to_float(cmd2)
fOrigin[2] = str_to_float(cmd3)
mark = str_to_num(cmd4)
ent = create_box(fOrigin)
if(ent != 0) {
if(mark == 4444)
mark_save_box(ent)
set_pev(ent, pev_nextthink, get_gametime() + 0.1)
}
return PLUGIN_CONTINUE
}

public box_save_mapfile(id) {
if(id != 1)
return PLUGIN_CONTINUE
if(file_exists(mapfile))
delete_file(mapfile)
write_file(mapfile, "// Do not change nor what^n")
static fb, bool:is_save; is_save = false
fb = engfunc(EngFunc_FindEntityByString, -1, "classname", "box_breakable")
while(fb > 0) {
if(pev_valid(fb)) {
is_save = true
write_mapfile(fb)
}
fb = engfunc(EngFunc_FindEntityByString, fb, "classname", "box_breakable")
}
if(is_save) {
client_print(id, print_chat, "[box] all boxes are preserved in map file !")
client_cmd(id, "spk %s",other_sound[0])
}
else {
client_print(id, print_chat, "[box] not a one box is not preserved !")
client_cmd(id, "spk %s",other_sound[2])
}
return PLUGIN_CONTINUE
}

public box_load_mapfile(id) {
if(id != 1)
return PLUGIN_CONTINUE
if(file_exists(mapfile)) {
server_cmd("exec %s",mapfile)
client_print(id, print_chat, "[box] file of the map was loaded !")
client_cmd(id, "spk %s",other_sound[0])
}
else {
client_print(id, print_chat, "[box] impossible load, file of the map does not exist !")
client_cmd(id, "spk %s",other_sound[2])
}
return PLUGIN_CONTINUE
}

public box_reload_mapfile(id) {
if(id != 1)
return PLUGIN_CONTINUE
if(!file_exists(mapfile)) {
client_print(id, print_chat, "[box] impossible reload, file of the map does not exist !")
client_cmd(id, "spk %s",other_sound[2])
return PLUGIN_CONTINUE
}
static fb
fb = engfunc(EngFunc_FindEntityByString, -1, "classname", "box_breakable")
while(fb > 0) {
if(pev_valid(fb) && is_saved_box(fb)) {
static id
id = get_mover_box(fb)
if(is_normal_index(id)) {
set_moving_box(id, 0)
IsMove[id] = false
}
id = get_thrower_box(fb)
if(is_normal_index(id))
set_throwing_box(id, 0)
engfunc(EngFunc_RemoveEntity, fb)
}
fb = engfunc(EngFunc_FindEntityByString, fb, "classname", "box_breakable")
}
server_cmd("exec %s",mapfile)
client_print(id, print_chat, "[box] file of the map was reloaded !")
client_cmd(id, "spk %s",other_sound[0])
return PLUGIN_CONTINUE
}

public box_delete_mapfile(id) {
if(id != 1)
return PLUGIN_CONTINUE
if(file_exists(mapfile)) {
delete_file(mapfile)
client_print(id, print_chat, "[box] file of the map was deleted !")
client_cmd(id, "spk %s",other_sound[0])
}
else {
client_print(id, print_chat, "[box] impossible delete, file of the map does not exist !")
client_cmd(id, "spk %s",other_sound[2])
}
return PLUGIN_CONTINUE
}

public box_delete_current(id) {
if(id != 1)
return PLUGIN_CONTINUE
static ent
ent = fm_get_aiment_dist(id, 9999.0)
if(is_entity_box_breakable(ent)) {
static id
id = get_mover_box(ent)
if(is_normal_index(id)) {
set_moving_box(id, 0)
IsMove[id] = false
}
id = get_thrower_box(ent)
if(is_normal_index(id))
set_throwing_box(id, 0)
engfunc(EngFunc_RemoveEntity, ent)
client_print(id, print_chat, "[box] current box deleted !")
client_cmd(id, "spk %s",other_sound[0])
}
else {
client_print(id, print_chat, "[box] impossible delete box !")
client_cmd(id, "spk %s",other_sound[2])
}
return PLUGIN_CONTINUE
}

stock write_mapfile(ent) {
mark_save_box(ent)
static Float:fOrigin[3], fstr[128]
pev(ent, pev_origin, fOrigin)
format(fstr, 127, "box_create_exec %f %f %f 4444",fOrigin[0],fOrigin[1],fOrigin[2])
write_file(mapfile, fstr)
return 1
}

stock create_box(Float:fEntOrigin[3]) {
static ent
ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
if(!pev_valid(ent))
return 0
set_pev(ent, pev_classname, "box_breakable")
set_pev(ent, pev_origin, fEntOrigin)
set_pev(ent, pev_solid, SOLID_SLIDEBOX)
set_pev(ent, pev_movetype, MOVETYPE_PUSHSTEP)
set_pev(ent, pev_health, get_cvar_float("box_health"))
set_pev(ent, pev_takedamage, DAMAGE_YES)
engfunc(EngFunc_SetModel, ent, "models/box.mdl")
engfunc(EngFunc_SetSize, ent, fBoxMins, fBoxMaxs)
set_pev(ent, pev_body, random_num(0, 2))
return ent
}

stock box_push_from_attacker(ent, idother, Float:multiplier) {
static Float:fVector[3], Float:fEntVelocity[3]
pev(idother, pev_v_angle, fVector)
angle_vector(fVector, ANGLEVECTOR_FORWARD, fVector)
xs_vec_mul_scalar(fVector, multiplier * 3, fVector)
pev(ent, pev_velocity, fEntVelocity)
xs_vec_add(fEntVelocity, fVector, fVector)
set_pev(ent, pev_velocity, fVector)
return 1
}

stock box_push_from_grenade(ent, idother, Float:multiplier) {
static Float:v1[3], Float:v2[3], Float:v3[3]
pev(ent, pev_origin, v1)
pev(idother, pev_origin, v2)
xs_vec_sub(v1, v2, v3)
xs_vec_normalize(v3, v3)
xs_vec_mul_scalar(v3, 8.0 * multiplier, v3)
pev(ent, pev_velocity, v1)
pev(idother, pev_velocity, v2)
xs_vec_add(v1, v2, v1)
xs_vec_add(v1, v3, v1)
set_pev(ent, pev_velocity, v1)
return 1
}

stock get_throw_velocity(index, Float:fRetVelocity[3]) {
pev(index, pev_v_angle, fRetVelocity)
angle_vector(fRetVelocity, ANGLEVECTOR_FORWARD, fRetVelocity)
xs_vec_mul_scalar(fRetVelocity, 2000.0, fRetVelocity)
return 1
}

stock bool:is_damaging_entity(ent) {
if(pev_valid(ent)) {
static Float:health, Float:takedamage
pev(ent, pev_health, health)
pev(ent, pev_takedamage, takedamage)
if(health > 0.0 && takedamage > 0.0)
return true
}
return false
}

stock bool:is_entity_box_breakable(ent) {
if(pev_valid(ent)) {
static classname[32]
pev(ent, pev_classname, classname, 31)
if(equal(classname, "box_breakable"))
return true
}
return false
}

stock bool:is_inflictor_grenade(ent) {
if(pev_valid(ent)) {
static classname[32]
pev(ent, pev_classname, classname, 31)
if(equal(classname, "grenade"))
return true
}
return false
}

stock bool:is_normal_index(index) {
if(index > 0 && index < 33)
return true
return false
}

stock create_dust(Float:fOrigin[3]) {
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_SPRITE)
engfunc(EngFunc_WriteCoord, fOrigin[0]) // x
engfunc(EngFunc_WriteCoord, fOrigin[1]) // y
engfunc(EngFunc_WriteCoord, fOrigin[2] + fBoxCenterZ) // z
write_short(DustSprite) // sprite
write_byte(10) // scale
write_byte(50) // brightness
message_end()
}

stock create_breakmodel(Float:fOrigin[3]) {
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BREAKMODEL)
engfunc(EngFunc_WriteCoord, fOrigin[0]) // x
engfunc(EngFunc_WriteCoord, fOrigin[1]) // y
engfunc(EngFunc_WriteCoord, fOrigin[2] + fBoxCenterZ) // z
write_coord(16) // size x
write_coord(16) // size y
write_coord(16) // size z
write_coord(random_num(-50,50)) // velocity x
write_coord(random_num(-50,50)) // velocity y
write_coord(25) // velocity z
write_byte(10) // random velocity
write_short(GibsModel) // model
write_byte(20) // count
write_byte(120) // life
write_byte(0x03) // flags
message_end()
return 1
}

stock get_mover_box(ent) {
return pev(ent, pev_iuser1)
}

stock set_mover_box(ent, index) {
set_pev(ent, pev_iuser1, index)
return 1
}

stock get_moving_box(index) {
return EntMove[index]
}

stock set_moving_box(index, ent) {
EntMove[index] = ent
return 1
}

stock get_thrower_box(ent) {
return pev(ent, pev_iuser2)
}

stock set_thrower_box(ent, index) {
set_pev(ent, pev_iuser2, index)
return 1
}

stock get_throwing_box(index) {
return EntThrow[index]
}

stock set_throwing_box(index, ent) {
EntThrow[index] = ent
return 1
}

stock bool:is_saved_box(ent) {
if(pev(ent, pev_iuser3) == 4444)
return true
return false
}

stock mark_save_box(ent) {
set_pev(ent, pev_iuser3, 4444)
return 1
}

stock fm_get_aiment_dist(index, Float:fDistance, entignore = 0, monstersignore = 0) {
static Float:fStart[3], Float:fViewOfs[3], trace, hit
pev(index, pev_origin, fStart)
pev(index, pev_view_ofs, fViewOfs)
xs_vec_add(fStart, fViewOfs, fStart)
static Float:fDest[3]
pev(index, pev_v_angle, fDest)
engfunc(EngFunc_MakeVectors, fDest)
global_get(glb_v_forward, fDest)
xs_vec_mul_scalar(fDest, fDistance, fDest)
xs_vec_add(fStart, fDest, fDest)
if(entignore > 0)
engfunc(EngFunc_TraceLine, fStart, fDest, monstersignore == 1 ? 1:0, entignore, trace)
else
engfunc(EngFunc_TraceLine, fStart, fDest, monstersignore == 1 ? 1:0, index, trace)
hit = get_tr2(trace, TR_pHit)
free_tr2(trace)
return hit
}

stock fm_get_aimorigin_dist(index, Float:fDistance, Float:fRetOrigin[3], entignore = 0, monstersignore = 0) {
static Float:fStart[3], Float:fViewOfs[3], trace
pev(index, pev_origin, fStart)
pev(index, pev_view_ofs, fViewOfs)
xs_vec_add(fStart, fViewOfs, fStart)
static Float:fDest[3]
pev(index, pev_v_angle, fDest)
engfunc(EngFunc_MakeVectors, fDest)
global_get(glb_v_forward, fDest)
xs_vec_mul_scalar(fDest, fDistance, fDest)
xs_vec_add(fStart, fDest, fDest)
if(pev_valid(entignore))
engfunc(EngFunc_TraceLine, fStart, fDest, monstersignore == 1 ? 1:0, entignore, trace)
else
engfunc(EngFunc_TraceLine, fStart, fDest, monstersignore == 1 ? 1:0, index, trace)
get_tr2(trace, TR_vecEndPos, fRetOrigin)
free_tr2(trace)
return 1
}

stock Float:fm_distance_to_floor(ent, entignore = 0, monstersignore = 0) {
static Float:fStart[3], Float:fDest[3], Float:fEnd[3], trace, Float:ret
pev(ent, pev_origin, fStart)
fDest[0] = fStart[0]
fDest[1] = fStart[1]
fDest[2] = -8191.0
if(pev_valid(entignore))
engfunc(EngFunc_TraceLine, fStart, fDest, monstersignore == 1 ? 1:0, entignore, trace)
else
engfunc(EngFunc_TraceLine, fStart, fDest, monstersignore == 1 ? 1:0, ent, trace)
get_tr2(trace, TR_vecEndPos, fEnd)
free_tr2(trace)
pev(ent, pev_absmin, fStart)
ret = fStart[2] - fEnd[2]
return ret > 0.0 ? ret:0.0
}

stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) {
static Float:RenderColor[3]
RenderColor[0] = float(r)
RenderColor[1] = float(g)
RenderColor[2] = float(b)
set_pev(entity, pev_renderfx, fx)
set_pev(entity, pev_rendercolor, RenderColor)
set_pev(entity, pev_rendermode, render)
set_pev(entity, pev_renderamt, float(amount))
return 1
}

 

d3m37r4

111111
Сообщения
1,449
Реакции
1,175
Помог
10 раз(а)
malniata, в рехлдс же есть редактор энтити. К нему менюху просто надо сделать.
 
Сообщения
458
Реакции
263
Помог
9 раз(а)
d3m37r4, буду благодарен за ресурсник, документацию к редактору
 
Сообщения
32
Реакции
3
Обратите внимание, если вы хотите заключить сделку с этим пользователем, он заблокирован
BlackSignature maybe add possibility change block zone to damage zone like was in old walkguard?
 
Сообщения
32
Реакции
3
Обратите внимание, если вы хотите заключить сделку с этим пользователем, он заблокирован
malniata rly? wow. Use brain and read my text again. This is proposition if u don't know :)
 
Сообщения
366
Реакции
5
Предупреждения
5
Помог
1 раз(а)
Можете ли вы написать созданные вами зоны на базовых картах?
de_dust2 , inferno, nuke32 train32
 
Сообщения
678
Реакции
56
Помог
16 раз(а)
Обратите внимание, если вы хотите заключить сделку с этим пользователем, он заблокирован
Se_IaQe, Вам предоставили продукт, готовый. Остальное дело в ваших руках - читаем инструкцию, открываем меню и работаем.
Может, автору ещё и по нужде сходить за Вас?
 
Сообщения
366
Реакции
5
Предупреждения
5
Помог
1 раз(а)
Se_IaQe, Вам предоставили продукт, готовый. Остальное дело в ваших руках - читаем инструкцию, открываем меню и работаем.
Может, автору ещё и по нужде сходить за Вас?
Это вина лени:mosking:
 
Сообщения
40
Реакции
12
Помог
1 раз(а)
Плагин отличный, дописал две версии: в одной показываются все существующие зоны, а не только активная; в другой нет меню, осталось только то что загружает конфиг и создает зоны.
C++:
new const PLUGIN_VERSION[] = "1.0.1 advance" // based on Mogel's original Walkguard plugin

// Default access flag (later can be changed in 'configs/cmdaccess.ini')
#define ACCESS_FLAG ADMIN_CFG

// Client editor menu chat commands
new const CLCMDS[][] = {
    "say /wg",
    "wgmenu"
}

// Configs folder in 'amxmodx/configs'
new const CFG_DIR[] = "walkguard"

// Actions log (comment to disable)
//new const LOG_FILENAME[] = "Walkguard.log"

/* -------------------- */

#include <amxmodx>
#include <amxmisc>
#include <reapi>
#include <fakemeta>

new const ENT_CLASSNAME[] = "walkguard_zone"
new const LINE_SPRITE[] = "sprites/dot.spr"

new const Float:DEF_MINS[3] = { -32.0, -32.0, -32.0 }
new const Float:DEF_MAXS[3] = { 32.0, 32.0, 32.0 }

const BOX_LINE_WIDTH = 5
const BOX_LINE_BRIGHTNESS = 200
new const BOX_LINE_COLOR_MAIN[3] = { 0, 255, 0 }
new const BOX_LINE_COLOR_ALL[3] = { 0, 200, 100 }
new const BOX_LINE_COLOR_RED[3] = { 255, 0, 0 }
new const BOX_LINE_COLOR_YELLOW[3] = { 255, 255, 0 }

#define ALL_KEYS 1023
#define chx charsmax
#define chx_len(%0) charsmax(%0) - iLen

new const MENU_IDENT_STRING[] = "WalkguardMenu"

enum { _KEY1_, _KEY2_, _KEY3_, _KEY4_, _KEY5_, _KEY6_, _KEY7_, _KEY8_, _KEY9_, _KEY0_ }

stock const SOUND__BLIP1[] = "sound/buttons/blip1.wav"
stock const SOUND__ERROR[] = "sound/buttons/button2.wav"

const TASKID__HIGHLIGHT = 14372

enum {
    MENU_MODE__MAIN,
    MENU_MODE__EDIT
}

new g_szMenu[MAX_MENU_LENGTH]
new g_iMenuMode[MAX_PLAYERS + 1]
new g_szCfgPath[PLATFORM_MAX_PATH]
new g_pEnt[MAX_PLAYERS + 1]
new g_iAxis[MAX_PLAYERS + 1] = { 1, ... }
new Float:g_fStepSize[MAX_PLAYERS + 1] = { 10.0, ... }
new g_iSpriteID
new g_pEditor
new g_szMapName[64]

/* -------------------- */

public plugin_init() {
    register_plugin("Walkguard", PLUGIN_VERSION, "mx?!")
    register_dictionary("walkguard.txt")

    /* --- */

    for(new i; i < sizeof(CLCMDS); i++) {
        register_clcmd(CLCMDS[i], "clcmd_OpenMainMenu", ACCESS_FLAG, .FlagManager = 1)
    }

    register_menucmd(register_menuid(MENU_IDENT_STRING), ALL_KEYS, "func_Menu_Handler")

    get_mapname(g_szMapName, chx(g_szMapName))
    func_LoadCfg()
}

/* -------------------- */

public clcmd_OpenMainMenu(pPlayer, bitAccess) {
    if(bitAccess && !(get_user_flags(pPlayer) & bitAccess)) {
        rg_send_audio(pPlayer, SOUND__ERROR)
        client_print_color(pPlayer, print_team_red, "%l", "WALKGUARD__NO_ACCESS")
        return PLUGIN_HANDLED
    }

    if(g_pEditor && g_pEditor != pPlayer) {
        rg_send_audio(pPlayer, SOUND__ERROR)
        client_print_color(pPlayer, print_team_red, "%l", "WALKGUARD__BUSY", g_pEditor)
        return PLUGIN_HANDLED
    }

    if(!g_pEditor) {
        g_pEditor = pPlayer

        set_task_ex(0.2, "task_Highlight", TASKID__HIGHLIGHT, .flags = SetTask_Repeat)

        new pEnt = MaxClients

        while((pEnt = rg_find_ent_by_class(pEnt, ENT_CLASSNAME, .useHashTable = false))) {
            set_entvar(pEnt, var_solid, SOLID_NOT)
            rg_set_entity_visibility(pEnt, .visible = 1)
        }
    }

    func_MainMenu(pPlayer)
    return PLUGIN_HANDLED
}

/* -------------------- */

func_MainMenu(pPlayer) {
    SetGlobalTransTarget(pPlayer)

    if( !IsZoneValid( g_pEnt[pPlayer] ) ) {
        g_pEnt[pPlayer] = 0
    }

    new pEnt = g_pEnt[pPlayer]

    new iLastNumber = 'r', iLastItem = 'w'

    if(!pEnt) {
        iLastNumber = iLastItem = 'd'
    }

    new iNextNumber = 'r', iNextItem = 'w'

    if(!rg_find_ent_by_class(MaxClients, ENT_CLASSNAME, .useHashTable = false)) {
        iNextNumber = iNextItem = 'd'
    }

    new iEditNumber = 'r', iEditItem = 'w'

    if(!pEnt) {
        iEditNumber = iEditItem = 'd'
    }

    new iDelNumber = 'r', iDetItem = 'w'

    if(!pEnt) {
        iDelNumber = iDetItem = 'd'
    }

    formatex( g_szMenu, chx(g_szMenu),
        "\y%l^n\
        ^n\
        \%c1. \%c%l^n\
        \%c2. \%c%l^n\
        ^n\
        \%c3. \%c%l^n\
        ^n\
        \r4. \w%l^n\
        ^n\
        \%c6. \%c%l^n\
        ^n\
        \r8. \w%l^n\
        ^n\
        \r0. \w%l",

        "WALKGUARD__MAIN_MENU_TITLE",

        iLastNumber, iLastItem, "WALKGUARD__TO_LAST",
        iNextNumber, iNextItem, "WALKGUARD__TO_NEXT",

        iEditNumber, iEditItem, "WALKGUARD__EDIT",

        "WALKGUARD__CREATE_NEW",

        iDelNumber, iDetItem, "WALKGUARD__DEL_ZONE",

        "WALKGUARD__SAVE_CFG",

        "WALKGUARD__EXIT"
    );

    static const MENU_KEYS = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_6|MENU_KEY_8|MENU_KEY_0

    func_ShowMenu(pPlayer, MENU_KEYS, MENU_MODE__MAIN)
}

/* -------------------- */

func_MainMenu_SubHandler(pPlayer, iKey) {
    switch(iKey) {
        case _KEY1_: {
            new pEnt = func_GetLastZone(pPlayer)

            if(pEnt)
                g_pEnt[pPlayer] = pEnt

            func_MainMenu(pPlayer)
        }
        case _KEY2_: {
            new pEnt = func_GetNextZone(pPlayer)

            if(pEnt)
                g_pEnt[pPlayer] = pEnt

            func_MainMenu(pPlayer)
        }
        case _KEY3_: {
            if( !IsZoneValid( g_pEnt[pPlayer] ) ) {
                g_pEnt[pPlayer] = 0
                func_MainMenu(pPlayer)
                return
            }

            func_EditMenu(pPlayer)
        }
        case _KEY4_: {
            new Float:fOrigin[3]
            get_entvar(pPlayer, var_origin, fOrigin)

            new pEnt = func_CreateZone(fOrigin, DEF_MINS, DEF_MAXS, 1)

            if(!pEnt) {
                rg_send_audio(pPlayer, SOUND__ERROR)
                client_print_color(pPlayer, print_team_red, "%l", "WALKGUARD__ERROR")
                func_MainMenu(pPlayer)
                return
            }

            g_pEnt[pPlayer] = pEnt
            func_EditMenu(pPlayer)
        }
        case _KEY6_: {
            if( !IsZoneValid( g_pEnt[pPlayer] ) ) {
                g_pEnt[pPlayer] = 0
                func_MainMenu(pPlayer)
                return
            }

            new pEnt = g_pEnt[pPlayer]

            g_pEnt[pPlayer] = func_GetLastZone(pPlayer)

            engfunc(EngFunc_RemoveEntity, pEnt) // don't replace with FL_KILLME!

            rg_send_audio(pPlayer, SOUND__BLIP1)
            client_print_color(pPlayer, print_team_red, "%l", "WALKGUARD__REMOVED")

            func_MainMenu(pPlayer)
        }
        case _KEY8_: {
            new iCount = func_SaveCfg(pPlayer)

            rg_send_audio(pPlayer, SOUND__BLIP1)
            client_print_color(pPlayer, print_team_red, "%l", iCount ? "WALKGUARD__SAVED" : "WALKGUARD__DELETED")

            func_MainMenu(pPlayer)
        }
        case _KEY0_: {
            g_pEditor = 0
            func_OverWork()
        }
    }
}

/* -------------------- */

func_EditMenu(pPlayer) {
    SetGlobalTransTarget(pPlayer)

    static const VECTOR_CHAR[3] = { any:'X', any:'Y', any:'Z' }

    new iAxis = g_iAxis[pPlayer]

    formatex( g_szMenu, chx(g_szMenu),
        "\y%l^n\
        ^n\
        \r2. \w%l \y%c\
        ^n      \r3. \w<- %l      \r4. \w-> %l\
        ^n      \y5. \w<- %l      \y6. \w-> %l^n\
        ^n\
        \r7. \w%l: \y%.0f^n\
        ^n\
        \r0. \w%l",

        "WALKGUARD__EDIT_MENU_TITLE",

        "WALKGUARD__CHANGE_AXIS", VECTOR_CHAR[iAxis],
        "WALKGUARD__TIGHTER", "WALKGUARD__WIDER",
        "WALKGUARD__TIGHTER", "WALKGUARD__WIDER",

        "WALKGUARD__CHANGE_STEP", g_fStepSize[pPlayer],

        "WALKGUARD__BACK"
    );

    const MENU_KEYS = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_0

    func_ShowMenu(pPlayer, MENU_KEYS, MENU_MODE__EDIT)
}

/* -------------------- */

func_EditMenu_SubHandler(pPlayer, iKey) {
    if( !IsZoneValid( g_pEnt[pPlayer] ) ) {
        g_pEnt[pPlayer] = 0
        func_MainMenu(pPlayer)
        return
    }

    switch(iKey) {
        case _KEY2_: {
            if(++g_iAxis[pPlayer] == 3) {
                g_iAxis[pPlayer] = 0
            }

            func_EditMenu(pPlayer)
        }
        case _KEY7_: {
            g_fStepSize[pPlayer] = (g_fStepSize[pPlayer] != 100.0) ? g_fStepSize[pPlayer] * 10.0 : 1.0;
            func_EditMenu(pPlayer)
        }
        case _KEY0_: {
            func_MainMenu(pPlayer)
        }
        default: { // _KEY3_, _KEY4_, _KEY5_, _KEY6_
            func_ChangeSize(pPlayer, iKey)
            func_EditMenu(pPlayer)
        }
    }
}

/* -------------------- */

public func_Menu_Handler(pPlayer, iKey) {
    if(!is_user_connected(pPlayer)) {
        return
    }

    switch(g_iMenuMode[pPlayer]) {
        case MENU_MODE__MAIN: func_MainMenu_SubHandler(pPlayer, iKey)
        case MENU_MODE__EDIT: func_EditMenu_SubHandler(pPlayer, iKey)
    }
}

/* -------------------- */

func_ShowMenu(pPlayer, iKeys, iMenuMode) {
    g_iMenuMode[pPlayer] = iMenuMode
    show_menu(pPlayer, iKeys, g_szMenu, -1, MENU_IDENT_STRING)
}

/* -------------------- */

bool:IsZoneValid(pEnt) {
    return FClassnameIs(pEnt, ENT_CLASSNAME)
}

/* -------------------- */

func_GetNextZone(pPlayer) {
    if( !IsZoneValid( g_pEnt[pPlayer] ) ) {
        g_pEnt[pPlayer] = 0
    }

    return rg_find_ent_by_class(g_pEnt[pPlayer], ENT_CLASSNAME, .useHashTable = false)
}

/* -------------------- */

func_GetLastZone(pPlayer) {
    if( !IsZoneValid( g_pEnt[pPlayer] ) ) {
        g_pEnt[pPlayer] = 0
        return 0
    }

    new pLastEnt, pEnt = MaxClients

    while((pEnt = rg_find_ent_by_class(pEnt, ENT_CLASSNAME, .useHashTable = false))) {
        if(pEnt == g_pEnt[pPlayer]) {
            return pLastEnt
        }

        pLastEnt = pEnt
    }

    return 0
}

/* -------------------- */

func_ChangeSize(pPlayer, iKey) {
    new pEnt = g_pEnt[pPlayer]
    new iAxis = g_iAxis[pPlayer]
    new Float:fStepSize = g_fStepSize[pPlayer]

    new Float:fOrigin[3], Float:fMins[3], Float:fMaxs[3]

    get_entvar(pEnt, var_origin, fOrigin)
    get_entvar(pEnt, var_mins, fMins)
    get_entvar(pEnt, var_maxs, fMaxs)

    if(
        (iKey == _KEY3_ || iKey == _KEY5_)
            &&
        ((floatabs(fMins[iAxis]) + fMaxs[iAxis]) < fStepSize + 1.0)
    ) {
        rg_send_audio(pPlayer, SOUND__ERROR)
        return
    }

    new Float:fSizeStep = fStepSize / 2.0

    switch(iKey) {
        case _KEY3_: {
            fMins[iAxis] += fSizeStep
            fMaxs[iAxis] -= fSizeStep
            fOrigin[iAxis] += fSizeStep
        }
        case _KEY4_: {
            fMins[iAxis] -= fSizeStep
            fMaxs[iAxis] += fSizeStep
            fOrigin[iAxis] -= fSizeStep
        }
        case _KEY5_: {
            fMins[iAxis] += fSizeStep
            fMaxs[iAxis] -= fSizeStep
            fOrigin[iAxis] -= fSizeStep
        }
        case _KEY6_: {
            fMins[iAxis] -= fSizeStep
            fMaxs[iAxis] += fSizeStep
            fOrigin[iAxis] += fSizeStep
        }
    }

    engfunc(EngFunc_SetOrigin, pEnt, fOrigin)
    engfunc(EngFunc_SetSize, pEnt, fMins, fMaxs)
}

/* -------------------- */

func_SaveCfg(pPlayer) {
    new hFile = fopen(g_szCfgPath, "w")

    if(!hFile) {
        abort(AMX_ERR_GENERAL, "Can't write to '%s'", g_szCfgPath)
    }

    new iCount, Float:fOrigin[3], Float:fMins[3], Float:fMaxs[3], pEnt = MaxClients;

    fputs(hFile, "; Walkguard zone file. Params: Origin<3> Mins<3> Maxs<3>^n")

    while((pEnt = rg_find_ent_by_class(pEnt, ENT_CLASSNAME, .useHashTable = false))) {
        get_entvar(pEnt, var_origin, fOrigin)
        get_entvar(pEnt, var_mins, fMins)
        get_entvar(pEnt, var_maxs, fMaxs)

        fprintf( hFile, "wgz_block_all %f %f %f %f %f %f %f %f %f^n",
            fOrigin[0],
            fOrigin[1],
            fOrigin[2],
            fMins[0],
            fMins[1],
            fMins[2],
            fMaxs[0],
            fMaxs[1],
            fMaxs[2]
        );

        iCount++
    }

    fclose(hFile)

    if(!iCount) {
        delete_file(g_szCfgPath)
    }

    /* --- */

    new szAuthID[MAX_AUTHID_LENGTH], szIP[MAX_IP_LENGTH]
    get_user_authid(pPlayer, szAuthID, chx(szAuthID))
    get_user_ip(pPlayer, szIP, chx(szIP), .without_port = 1)

#if defined LOG_FILENAME
    log_to_file( LOG_FILENAME, "<%n><%s><%s> %s config on '%s'",
        pPlayer, szAuthID, szIP, iCount ? "save" : "delete", g_szMapName );
#endif

    return iCount
}

/* -------------------- */

func_LoadCfg() {
    new iLen = get_configsdir(g_szCfgPath, chx(g_szCfgPath))

    iLen += formatex(g_szCfgPath[iLen], chx_len(g_szCfgPath), "/%s", CFG_DIR)

    if(!dir_exists(g_szCfgPath)) {
        mkdir(g_szCfgPath)
    }

    formatex(g_szCfgPath[iLen], chx_len(g_szCfgPath), "/%s.wgz", g_szMapName)

    new hFile = fopen(g_szCfgPath, "r")

    if(!hFile) {
        if(file_exists(g_szCfgPath)) {
            abort(AMX_ERR_GENERAL, "Can't read '%s'", g_szCfgPath)
        }

        return
    }

    new szText[256], szType[32], szOrigin[3][10], szMins[3][10], szMaxs[3][10],
        Float:fOrigin[3], Float:fMins[3], Float:fMaxs[3], pEnt;

    while(fgets(hFile, szText, chx(szText))) {
        trim(szText)

        if(!szText[0] || szText[0] == ';') {
            continue
        }

        parse( szText,
            szType, chx(szType),
            szOrigin[0], chx(szOrigin[]),
            szOrigin[1], chx(szOrigin[]),
            szOrigin[2], chx(szOrigin[]),
            szMins[0], chx(szMins[]),
            szMins[1], chx(szMins[]),
            szMins[2], chx(szMins[]),
            szMaxs[0], chx(szMins[]),
            szMaxs[1], chx(szMins[]),
            szMaxs[2], chx(szMins[])
        );

        if(!equal(szType, "wgz_block_all")) {
            continue
        }

        for(new i; i < 3; i++) {
            fOrigin[i] = str_to_float(szOrigin[i])
            fMins[i] = str_to_float(szMins[i])
            fMaxs[i] = str_to_float(szMaxs[i])
        }

        pEnt = func_CreateZone(fOrigin, fMins, fMaxs, 0)

        if(!pEnt) {
            fclose(hFile)
            abort(AMX_ERR_GENERAL, "Can't create entity in func_LoadCfg() !")
        }
    }

    fclose(hFile)
}

/* -------------------- */

func_CreateZone(const Float:fOrigin[3], const Float:fMins[3], const Float:fMaxs[3], iVisible) {
    new pEnt = rg_create_entity("info_target", .useHashTable = false)

    if(!pEnt) {
        return 0
    }

    set_entvar(pEnt, var_classname, ENT_CLASSNAME)
    set_entvar(pEnt, var_movetype, MOVETYPE_NONE)
    set_entvar(pEnt, var_solid, g_pEditor ? SOLID_NOT : SOLID_BBOX)
    engfunc(EngFunc_SetOrigin, pEnt, fOrigin)

    // good: with this we don't need to reload cfg to aply new zone size
    // bad: with this push will work and other entities can push zone entity
    // set_entvar(pEnt, var_movetype, MOVETYPE_FLY)

    engfunc(EngFunc_SetSize, pEnt, fMins, fMaxs)
    rg_set_entity_visibility(pEnt, .visible = iVisible)

    return pEnt
}

/* -------------------- */

func_OverWork() {
    remove_task(TASKID__HIGHLIGHT)

    new pEnt = MaxClients

    while((pEnt = rg_find_ent_by_class(pEnt, ENT_CLASSNAME, .useHashTable = false))) {
        /*set_entvar(pEnt, var_solid, SOLID_BBOX)
        rg_set_entity_visibility(pEnt, .visible = 0)*/

        set_entvar(pEnt, var_flags, FL_KILLME) // new
    }

    arrayset(g_pEnt, 0, sizeof(g_pEnt)) // new

    // new, reload cfg to apply new sizes, as we don't use MOVETYPE_FLY anymore
    func_LoadCfg()
}

/* -------------------- */

public task_Highlight() {
    static Float:fEntOrigin[3], Float:fUserOrigin[3], Float:fMins[3], Float:fMaxs[3], color[3], pEnt
    pEnt = 0

    if( !IsZoneValid( g_pEnt[g_pEditor] ) ) {
        return
    }
    
    while ((pEnt = rg_find_ent_by_class(pEnt, ENT_CLASSNAME, .useHashTable = false))) {
        get_entvar(pEnt, var_origin, fEntOrigin)
        get_entvar(pEnt, var_mins, fMins)
        get_entvar(pEnt, var_maxs, fMaxs)
        
        fMins[0] += fEntOrigin[0]
        fMins[1] += fEntOrigin[1]
        fMins[2] += fEntOrigin[2]
        fMaxs[0] += fEntOrigin[0]
        fMaxs[1] += fEntOrigin[1]
        fMaxs[2] += fEntOrigin[2]
        
        if (pEnt == g_pEnt[g_pEditor]) {
            get_entvar(g_pEditor, var_origin, fUserOrigin)
            fUserOrigin[2] -= 16.0

            func_DrawLine(g_pEditor, fUserOrigin[0], fUserOrigin[1], fUserOrigin[2], fEntOrigin[0], fEntOrigin[1], fEntOrigin[2], BOX_LINE_COLOR_MAIN)

            color[0] = BOX_LINE_COLOR_MAIN[0]
            color[1] = BOX_LINE_COLOR_MAIN[1]
            color[2] = BOX_LINE_COLOR_MAIN[2]

            new iAxis = g_iAxis[g_pEditor]

            switch (iAxis)
            {
                case 0:
                {
                    func_DrawLine(g_pEditor, fMaxs[0], fMaxs[1], fMaxs[2], fMaxs[0], fMins[1], fMins[2], BOX_LINE_COLOR_YELLOW)
                    func_DrawLine(g_pEditor, fMaxs[0], fMaxs[1], fMins[2], fMaxs[0], fMins[1], fMaxs[2], BOX_LINE_COLOR_YELLOW)
                    func_DrawLine(g_pEditor, fMins[0], fMaxs[1], fMaxs[2], fMins[0], fMins[1], fMins[2], BOX_LINE_COLOR_RED)
                    func_DrawLine(g_pEditor, fMins[0], fMaxs[1], fMins[2], fMins[0], fMins[1], fMaxs[2], BOX_LINE_COLOR_RED)
                }
                case 1:
                {
                    func_DrawLine(g_pEditor, fMins[0], fMins[1], fMins[2], fMaxs[0], fMins[1], fMaxs[2], BOX_LINE_COLOR_RED)
                    func_DrawLine(g_pEditor, fMaxs[0], fMins[1], fMins[2], fMins[0], fMins[1], fMaxs[2], BOX_LINE_COLOR_RED)
                    func_DrawLine(g_pEditor, fMins[0], fMaxs[1], fMins[2], fMaxs[0], fMaxs[1], fMaxs[2], BOX_LINE_COLOR_YELLOW)
                    func_DrawLine(g_pEditor, fMaxs[0], fMaxs[1], fMins[2], fMins[0], fMaxs[1], fMaxs[2], BOX_LINE_COLOR_YELLOW)
                }
                case 2:
                {
                    func_DrawLine(g_pEditor, fMaxs[0], fMaxs[1], fMaxs[2], fMins[0], fMins[1], fMaxs[2], BOX_LINE_COLOR_YELLOW)
                    func_DrawLine(g_pEditor, fMaxs[0], fMins[1], fMaxs[2], fMins[0], fMaxs[1], fMaxs[2], BOX_LINE_COLOR_YELLOW)
                    func_DrawLine(g_pEditor, fMaxs[0], fMaxs[1], fMins[2], fMins[0], fMins[1], fMins[2], BOX_LINE_COLOR_RED)
                    func_DrawLine(g_pEditor, fMaxs[0], fMins[1], fMins[2], fMins[0], fMaxs[1], fMins[2], BOX_LINE_COLOR_RED)
                }
            }
        }
        else {
            color[0] = BOX_LINE_COLOR_ALL[0]
            color[1] = BOX_LINE_COLOR_ALL[1]
            color[2] = BOX_LINE_COLOR_ALL[2]
        }
        func_DrawLine(g_pEditor, fMaxs[0], fMaxs[1], fMaxs[2], fMins[0], fMaxs[1], fMaxs[2], color)
        func_DrawLine(g_pEditor, fMaxs[0], fMaxs[1], fMaxs[2], fMaxs[0], fMins[1], fMaxs[2], color)
        func_DrawLine(g_pEditor, fMaxs[0], fMaxs[1], fMaxs[2], fMaxs[0], fMaxs[1], fMins[2], color)
        func_DrawLine(g_pEditor, fMins[0], fMins[1], fMins[2], fMaxs[0], fMins[1], fMins[2], color)
        func_DrawLine(g_pEditor, fMins[0], fMins[1], fMins[2], fMins[0], fMaxs[1], fMins[2], color)
        func_DrawLine(g_pEditor, fMins[0], fMins[1], fMins[2], fMins[0], fMins[1], fMaxs[2], color)
        func_DrawLine(g_pEditor, fMins[0], fMaxs[1], fMaxs[2], fMins[0], fMaxs[1], fMins[2], color)
        func_DrawLine(g_pEditor, fMins[0], fMaxs[1], fMins[2], fMaxs[0], fMaxs[1], fMins[2], color)
        func_DrawLine(g_pEditor, fMaxs[0], fMaxs[1], fMins[2], fMaxs[0], fMins[1], fMins[2], color)
        func_DrawLine(g_pEditor, fMaxs[0], fMins[1], fMins[2], fMaxs[0], fMins[1], fMaxs[2], color)
        func_DrawLine(g_pEditor, fMaxs[0], fMins[1], fMaxs[2], fMins[0], fMins[1], fMaxs[2], color)
        func_DrawLine(g_pEditor, fMins[0], fMins[1], fMaxs[2], fMins[0], fMaxs[1], fMaxs[2], color)
    }
}

/* -------------------- */

func_DrawLine(pPlayer, Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2, const iColor[3]) {
    static Float:fStart[3], Float:fEnd[3]

    fStart[0] = x1; fStart[1] = y1; fStart[2] = z1
    fEnd[0] = x2; fEnd[1] = y2; fEnd[2] = z2

    message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, .player = pPlayer)
    write_byte(TE_BEAMPOINTS)
    write_coord_f(fStart[0])
    write_coord_f(fStart[1])
    write_coord_f(fStart[2])
    write_coord_f(fEnd[0])
    write_coord_f(fEnd[1])
    write_coord_f(fEnd[2])
    write_short(g_iSpriteID)
    write_byte(1) // starting frame
    write_byte(0) // frame rate in 0.1's
    write_byte(4) // life in 0.1's
    write_byte(BOX_LINE_WIDTH)
    write_byte(0) // noise amplitude in 0.01's
    write_byte(iColor[0]) // R
    write_byte(iColor[1]) // G
    write_byte(iColor[2]) // B
    write_byte(BOX_LINE_BRIGHTNESS) // brightness
    write_byte(0) // scroll speed in 0.1's
    message_end()
}

/* -------------------- */

public plugin_precache() {
    g_iSpriteID = precache_model(LINE_SPRITE)
}

/* -------------------- */

public client_disconnected(pPlayer) {
    if(pPlayer == g_pEditor) {
        g_pEditor = 0
        func_OverWork()
    }
}

/* -------------------- */

stock rg_set_entity_visibility(entity, visible = 1) {
    set_entvar(entity, var_effects, visible == 1 ? get_entvar(entity, var_effects) & ~EF_NODRAW : get_entvar(entity, var_effects) | EF_NODRAW);
}
C++:
new const PLUGIN_VERSION[] = "1.0.1 lite" // based on Mogel's original Walkguard plugin

// Configs folder in 'amxmodx/configs'
new const CFG_DIR[] = "walkguard"

#include <amxmodx>
#include <amxmisc>
#include <reapi>
#include <fakemeta>

#define chx charsmax
#define chx_len(%0) charsmax(%0) - iLen

new const ENT_CLASSNAME[] = "walkguard_zone"

new g_szCfgPath[PLATFORM_MAX_PATH]
new g_pEditor
new g_szMapName[64]

/* -------------------- */

public plugin_init() {
    register_plugin("Walkguard", PLUGIN_VERSION, "mx?!")

    get_mapname(g_szMapName, chx(g_szMapName))
    func_LoadCfg()
}

/* -------------------- */

func_LoadCfg() {
    new iLen = get_configsdir(g_szCfgPath, chx(g_szCfgPath))

    iLen += formatex(g_szCfgPath[iLen], chx_len(g_szCfgPath), "/%s", CFG_DIR)

    if(!dir_exists(g_szCfgPath)) {
        mkdir(g_szCfgPath)
    }

    formatex(g_szCfgPath[iLen], chx_len(g_szCfgPath), "/%s.wgz", g_szMapName)

    new hFile = fopen(g_szCfgPath, "r")

    if(!hFile) {
        if(file_exists(g_szCfgPath)) {
            abort(AMX_ERR_GENERAL, "Can't read '%s'", g_szCfgPath)
        }

        return
    }

    new szText[256], szType[32], szOrigin[3][10], szMins[3][10], szMaxs[3][10],
        Float:fOrigin[3], Float:fMins[3], Float:fMaxs[3], pEnt;

    while(fgets(hFile, szText, chx(szText))) {
        trim(szText)

        if(!szText[0] || szText[0] == ';') {
            continue
        }

        parse( szText,
            szType, chx(szType),
            szOrigin[0], chx(szOrigin[]),
            szOrigin[1], chx(szOrigin[]),
            szOrigin[2], chx(szOrigin[]),
            szMins[0], chx(szMins[]),
            szMins[1], chx(szMins[]),
            szMins[2], chx(szMins[]),
            szMaxs[0], chx(szMins[]),
            szMaxs[1], chx(szMins[]),
            szMaxs[2], chx(szMins[])
        );

        if(!equal(szType, "wgz_block_all")) {
            continue
        }

        for(new i; i < 3; i++) {
            fOrigin[i] = str_to_float(szOrigin[i])
            fMins[i] = str_to_float(szMins[i])
            fMaxs[i] = str_to_float(szMaxs[i])
        }

        pEnt = func_CreateZone(fOrigin, fMins, fMaxs, 0)

        if(!pEnt) {
            fclose(hFile)
            abort(AMX_ERR_GENERAL, "Can't create entity in func_LoadCfg() !")
        }
    }

    fclose(hFile)
}

/* -------------------- */

func_CreateZone(const Float:fOrigin[3], const Float:fMins[3], const Float:fMaxs[3], iVisible) {
    new pEnt = rg_create_entity("info_target", .useHashTable = false)

    if(!pEnt) {
        return 0
    }

    set_entvar(pEnt, var_classname, ENT_CLASSNAME)
    set_entvar(pEnt, var_movetype, MOVETYPE_NONE)
    set_entvar(pEnt, var_solid, g_pEditor ? SOLID_NOT : SOLID_BBOX)
    engfunc(EngFunc_SetOrigin, pEnt, fOrigin)

    // good: with this we don't need to reload cfg to aply new zone size
    // bad: with this push will work and other entities can push zone entity
    // set_entvar(pEnt, var_movetype, MOVETYPE_FLY)

    engfunc(EngFunc_SetSize, pEnt, fMins, fMaxs)
    rg_set_entity_visibility(pEnt, .visible = iVisible)

    return pEnt
}

/* -------------------- */

stock rg_set_entity_visibility(entity, visible = 1) {
    set_entvar(entity, var_effects, visible == 1 ? get_entvar(entity, var_effects) & ~EF_NODRAW : get_entvar(entity, var_effects) | EF_NODRAW);
}
 
Сообщения
68
Реакции
4
Is it possible to disable the walkguard area via a cvar or something?
even when pausing the plugin, the blocking area is still active
 
Сообщения
34
Реакции
1
Прикольно было бы сделать флаг в конфиге чтобы могли пройти через зона.
А так прикольный плагин :good2:
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу