/* Copyright © 2008, ConnorMcLeod
No Kill Zones is free software;
you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with No Kill Zones; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
#define PLUGIN "No Kill Zones"
#define AUTHOR "ConnorMcLeod"
#define VERSION "0.0.4"
#define MAX_ZONES 32
#define MAX_PLAYERS 32
#define KEYS ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|(1<<9))
#define write_coord_f(%1) engfunc(EngFunc_WriteCoord,%1)
new g_iZonesNum
new Float:g_flZoneMin[MAX_ZONES][3], Float:g_flZoneMax[MAX_ZONES][3]
new Float:g_flTempMin[3], Float:g_flTempMax[3]
new g_szFile[100]
new g_iMenu, NKZ_MENU
new g_iMenuSettings[MAX_PLAYERS+1][2]
new iSprite
public plugin_precache()
{
iSprite = precache_model("sprites/lgtning.spr")
}
public plugin_init()
{
register_plugin(PLUGIN ,VERSION ,AUTHOR)
RegisterHam( Ham_TakeDamage, "player", "TakeDamage_player")
NKZ_MENU = register_menuid("NKZ")
register_menucmd( NKZ_MENU , KEYS, "actionZoneMenu")
register_clcmd("nkz_menu", "ClientCommand_Menu", ADMIN_CFG)
}
public plugin_cfg()
{
load_setting()
}
load_setting()
{
get_configsdir(g_szFile, 99)
new szMapName[32]
get_mapname(szMapName, 31)
format(g_szFile, 99, "%s/nkz/%s.ini", g_szFile, szMapName)
new iFile = fopen(g_szFile, "rt")
if( !iFile )
return
new szData[50], szCoords[6][8]
while(!feof(iFile) && g_iZonesNum<MAX_ZONES)
{
fgets(iFile, szData, 49)
trim( szData )
if(!szData[0] || szData[0] == ';' || (szData[0] == '/' && szData[1] == '/'))
continue
parse(szData, szCoords[0], 7, szCoords[1], 7, szCoords[2], 7,
szCoords[3], 7, szCoords[4], 7, szCoords[5], 7)
for(new i; i<3; i++)
{
g_flZoneMin[g_iZonesNum] = str_to_float( szCoords )
g_flZoneMax[g_iZonesNum] = str_to_float( szCoords[i+3] )
}
g_iZonesNum++
}
fclose(iFile)
}
public plugin_end()
{
delete_file(g_szFile)
new iFile = fopen(g_szFile, "a+")
if( !iFile )
return
new szData[50]
for(new i; i<g_iZonesNum; i++)
{
formatex( szData, 49, "%.1f %.1f %.1f %.1f %.1f %.1f^n",
g_flZoneMin[0], g_flZoneMin[1], g_flZoneMin[2],
g_flZoneMax[0], g_flZoneMax[1], g_flZoneMax[2] )
fputs(iFile, szData)
}
fclose(iFile)
}
public TakeDamage_player(id, iEnt, idattacker, Float:damage, damagebits)
{
for(new i; i<g_iZonesNum; i++)
{
if( is_user_in_zone(id, i) || is_user_in_zone(idattacker, i) )
{
SetHamParamFloat(4, 0.0)
return HAM_HANDLED
}
}
return HAM_IGNORED
}
public client_putinserver(id)
{
reset_setting(id)
}
reset_setting(id)
{
g_iMenuSettings[id][0] = -2
g_iMenuSettings[id][1] = 0
}
public client_disconnect(id)
{
if( g_iMenu == id )
{
g_iMenu = 0
}
}
public ClientCommand_Menu(id, level, cid)
{
if( !cmd_access(id, level, cid, 1) )
return PLUGIN_HANDLED
if( g_iMenu )
{
new iMenuId, LoL
get_user_menu(g_iMenu, iMenuId, LoL)
if( iMenuId == NKZ_MENU )
{
client_print(id, print_chat, "Sorry, someone already uses this menu, try again later...")
client_print(id, print_console, "Sorry, someone already uses this menu, try again later...")
return PLUGIN_HANDLED
}
}
g_iMenu = id
reset_setting(id)
display_menu(id)
return PLUGIN_HANDLED
}
display_menu(id)
{
new szMenu[1024], n, iZone = g_iMenuSettings[id][0]
static const szAxes[][] = { "x (red)" , "y (blue)" , "z (green)" }
n = formatex(szMenu, 1023, "\rNoKill Zone Menu\y ")
if(iZone < 0)
n += formatex(szMenu[n], 1023-n, "(New Zone)^n")
else
n += formatex(szMenu[n], 1023-n, "(Zone %d/%d)^n", iZone+1, g_iZonesNum)
n += formatex(szMenu[n], 1023-n, "\w1. %s^n^n", g_iZonesNum ? "Next Zone":"Create Zone")
n += formatex(szMenu[n], 1023-n, "2. Current Axe %s^n", szAxes[g_iMenuSettings[id][1]])
n += formatex(szMenu[n], 1023-n, "3. Move ++^n")
n += formatex(szMenu[n], 1023-n, "4. Move --^n")
n += formatex(szMenu[n], 1023-n, "5. Increase size^n")
n += formatex(szMenu[n], 1023-n, "6. Decrease size^n")
n += formatex(szMenu[n], 1023-n, "7. \yDraw Zone^n^n")
n += formatex(szMenu[n], 1023-n, "\w9. \rSave Zone & Exit^n")
n += formatex(szMenu[n], 1023-n, "\w0. Cancel")
if(iZone == -2)
{
Create_Temp_Zone(id)
g_iMenuSettings[id][0] = -1
}
show_menu(id, KEYS, szMenu, -1, "NKZ")
}
public actionZoneMenu(id, key)
{
new iZone = g_iMenuSettings[id][0]
switch( key )
{
case 0:
{
if( iZone < g_iZonesNum-1 )
{
iZone = ++g_iMenuSettings[id][0]
vec_copy(g_flZoneMin[iZone], g_flTempMin)
vec_copy(g_flZoneMax[iZone], g_flTempMax)
Draw_Ent(id)
}
else
{
Create_Temp_Zone(id)
g_iMenuSettings[id][0] = -1
}
display_menu(id)
}
case 1:
{
if( ++g_iMenuSettings[id][1] >= 3 )
g_iMenuSettings[id][1] = 0
display_menu(id)
}
case 2:
{
new iAxe = g_iMenuSettings[id][1]
g_flTempMin[iAxe] += 1
g_flTempMax[iAxe] += 1
Draw_Ent(id, 50)
display_menu(id)
}
case 3:
{
new iAxe = g_iMenuSettings[id][1]
g_flTempMin[iAxe] -= 1
g_flTempMax[iAxe] -= 1
Draw_Ent(id, 50)
display_menu(id)
}
case 4:
{
new iAxe = g_iMenuSettings[id][1]
g_flTempMin[iAxe] -= 1
g_flTempMax[iAxe] += 1
Draw_Ent(id, 50)
display_menu(id)
}
case 5:
{
new iAxe = g_iMenuSettings[id][1]
g_flTempMin[iAxe] += 1
g_flTempMax[iAxe] -= 1
Draw_Ent(id, 50)
display_menu(id)
}
case 6:
{
client_print(id,print_chat,"MIN %.3f %.3f %.3f",g_flTempMin[0],g_flTempMin[1],g_flTempMin[2]);
client_print(id,print_chat,"MAX %.3f %.3f %.3f",g_flTempMax[0],g_flTempMax[1],g_flTempMax[2]);
Draw_Ent(id)
display_menu(id)
}
case 8:
{
if( iZone == -1 )
{
if( g_iZonesNum < MAX_ZONES-1 )
{
vec_copy(g_flTempMin, g_flZoneMin[g_iZonesNum])
vec_copy(g_flTempMax, g_flZoneMax[g_iZonesNum])
g_iZonesNum++
client_print(id, print_chat, "[NKZ] Zone #%d saved", g_iZonesNum)
}
else
{
client_print(id, print_chat, "Too much zones created")
}
}
else
{
vec_copy(g_flTempMin, g_flZoneMin[iZone])
vec_copy(g_flTempMax, g_flZoneMax[iZone])
client_print(id, print_chat, "[NKZ] Zone #%d modified", iZone)
}
arrayset_f(g_flTempMin, 0.0, 3)
arrayset_f(g_flTempMax, 0.0, 3)
reset_setting(id)
g_iMenu = 0
}
case 9:
{
arrayset_f(g_flTempMin, 0.0, 3)
arrayset_f(g_flTempMax, 0.0, 3)
reset_setting(id)
g_iMenu = 0
}
}
}
Create_Temp_Zone( id )
{
new Float:flOrigin[3]
pev(id, pev_origin, flOrigin)
flOrigin[0] -= 40.0
flOrigin[1] -= 40.0
flOrigin[2] -= 36.0
vec_copy(flOrigin, g_flTempMin)
flOrigin[0] += 80.0
flOrigin[1] += 80.0
flOrigin[2] += 72.0
vec_copy(flOrigin, g_flTempMax)
client_print(id, print_chat, "New Zone Created (not saved yet)")
}
Draw_Ent(id, life=100)
{
new Float:flAbsmin[3], Float:flAbsmax[3]
vec_copy(g_flTempMin, flAbsmin)
vec_copy(g_flTempMax, flAbsmax)
/*
7----------8
/| /|
/ | / |
5----------6 |
| | | |
| 3-------|--4
| / | /
|/ |/
1----------2
*/
/*x red*/
UTIL_DrawBeam(id, flAbsmin[0],flAbsmin[1],flAbsmin[2] , flAbsmax[0],flAbsmin[1],flAbsmin[2] , life, 20, 1, 200, 20, 20, 255, 0)
UTIL_DrawBeam(id, flAbsmin[0],flAbsmin[1],flAbsmax[2] , flAbsmax[0],flAbsmin[1],flAbsmax[2] , life, 20, 1, 200, 20, 20, 255, 0)
UTIL_DrawBeam(id, flAbsmin[0],flAbsmax[1],flAbsmin[2] , flAbsmax[0],flAbsmax[1],flAbsmin[2] , life, 20, 1, 200, 20, 20, 255, 0)
UTIL_DrawBeam(id, flAbsmin[0],flAbsmax[1],flAbsmax[2] , flAbsmax[0],flAbsmax[1],flAbsmax[2] , life, 20, 1, 200, 20, 20, 255, 0)
/*y blue*/
UTIL_DrawBeam(id, flAbsmin[0],flAbsmin[1],flAbsmin[2] , flAbsmin[0],flAbsmax[1],flAbsmin[2] , life, 20, 1, 20, 20, 200, 255, 0)
UTIL_DrawBeam(id, flAbsmin[0],flAbsmin[1],flAbsmax[2] , flAbsmin[0],flAbsmax[1],flAbsmax[2] , life, 20, 1, 20, 20, 200, 255, 0)
UTIL_DrawBeam(id, flAbsmax[0],flAbsmin[1],flAbsmin[2] , flAbsmax[0],flAbsmax[1],flAbsmin[2] , life, 20, 1, 20, 20, 200, 255, 0)
UTIL_DrawBeam(id, flAbsmax[0],flAbsmin[1],flAbsmax[2] , flAbsmax[0],flAbsmax[1],flAbsmax[2] , life, 20, 1, 20, 20, 200, 255, 0)
/*z green*/
UTIL_DrawBeam(id, flAbsmin[0],flAbsmin[1],flAbsmin[2] , flAbsmin[0],flAbsmin[1],flAbsmax[2] , life, 20, 1, 20, 200, 20, 255, 0)
UTIL_DrawBeam(id, flAbsmax[0],flAbsmax[1],flAbsmin[2] , flAbsmax[0],flAbsmax[1],flAbsmax[2] , life, 20, 1, 20, 200, 20, 255, 0)
UTIL_DrawBeam(id, flAbsmax[0],flAbsmin[1],flAbsmin[2] , flAbsmax[0],flAbsmin[1],flAbsmax[2] , life, 20, 1, 20, 200, 20, 255, 0)
UTIL_DrawBeam(id, flAbsmin[0],flAbsmax[1],flAbsmin[2] , flAbsmin[0],flAbsmax[1],flAbsmax[2] , life, 20, 1, 20, 200, 20, 255, 0)
}
// shptools
UTIL_DrawBeam(id, Float:start0, Float:start1, Float:start2, Float:end0, Float:end1, Float:end2, life, width, noise, red, green, blue, brightness, speed)
{
message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, id)
write_byte(TE_BEAMPOINTS)
write_coord_f(start0)
write_coord_f(start1)
write_coord_f(start2)
write_coord_f(end0)
write_coord_f(end1)
write_coord_f(end2)
write_short(iSprite)
write_byte(1) // framestart
write_byte(10) // framerate
write_byte(life) // life in 0.1's
write_byte(width) // width
write_byte(noise) // noise
write_byte(red) // r, g, b
write_byte(green) // r, g, b
write_byte(blue) // r, g, b
write_byte(brightness) // brightness
write_byte(speed) // speed
message_end()
}
vec_copy(const Float:vecIn[], Float:vecOut[])
{
vecOut[0] = vecIn[0]
vecOut[1] = vecIn[1]
vecOut[2] = vecIn[2]
}
is_user_in_zone(id, i)
{
new Float:flOrigin[3]
pev(id, pev_origin, flOrigin)
if( g_flZoneMin[0] < flOrigin[0] &&
g_flZoneMin[i][1] < flOrigin[1] &&
g_flZoneMin[i][2] < flOrigin[2] &&
g_flZoneMax[i][0] > flOrigin[0] &&
g_flZoneMax[i][1] > flOrigin[1] &&
g_flZoneMax[i][2] > flOrigin[2] )
return 1
return 0
}
arrayset_f(Float:flArray[], Float:flValue, iSize)
{
for(--iSize; iSize>=0; iSize--)
{
flArray[iSize] = flValue
}
}