#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#define PLUGIN "Wall Text"
#define AUTHOR "stupok"
#define VERSION "1.09"
#define CHAR_WIDTH 12
#define MESSAGE_LEN 64
#define BUFFER_LEN 512
#define ACCESS_LEVEL ADMIN_KICK
new Array:g_aOrigins
new Array:g_aVectors
new Array:g_aMessages
new Array:g_aSaved
new g_szConfigsDir[128]
new g_szMapName[64]
new g_szFile[256]
new g_iDecalAlpha, g_iDecalAlphaBk, g_iDecalDigit, g_iDecalDigitBk
new g_iDecalResetEvent
new g_fwdidPrecacheEvent
public plugin_init()
{
register_plugin( PLUGIN, VERSION, AUTHOR )
register_clcmd( "amx_walltext", "cmd_WallText", ACCESS_LEVEL, "- amx_walltext <Szoveg ami a falra kerul>" )
register_clcmd( "amx_walltextmenu", "cmd_WallTextMenu", ACCESS_LEVEL, "- Fal szoveg menu" )
register_clcmd( "say walltextmenu", "cmd_WallTextMenu", ACCESS_LEVEL, "- Fal szoveg menu" )
if( get_user_msgid( "HLTV" ) )
register_event( "HLTV", "event_NewRound", "a", "1=0", "2=0" )
g_aOrigins = ArrayCreate( 3 )
g_aVectors = ArrayCreate( 3 )
g_aMessages = ArrayCreate( MESSAGE_LEN )
g_aSaved = ArrayCreate()
get_configsdir( g_szConfigsDir, charsmax( g_szConfigsDir ) )
get_mapname( g_szMapName, charsmax( g_szMapName ) )
formatex( g_szFile, charsmax( g_szFile ), "%s/maps", g_szConfigsDir )
if( !dir_exists( g_szFile ) )
mkdir( g_szFile )
formatex( g_szFile, charsmax( g_szFile ), "%s/maps/walltext-%s.ini", g_szConfigsDir, g_szMapName )
g_iDecalAlphaBk = engfunc( EngFunc_DecalIndex, "{smscorch2" )
g_iDecalAlpha = engfunc( EngFunc_DecalIndex, "{capsa" )
g_iDecalDigitBk = engfunc( EngFunc_DecalIndex, "{break3" )
g_iDecalDigit = engfunc( EngFunc_DecalIndex, "{small#s0" )
LoadMessagesFromFile()
}
public plugin_precache()
{
g_fwdidPrecacheEvent = register_forward( FM_PrecacheEvent, "forward_PrecacheEvent", 1 )
}
public forward_PrecacheEvent( type, const szName[] )
{
if( equal( szName, "events/decal_reset.sc" ) )
{
g_iDecalResetEvent = get_orig_retval()
unregister_forward( FM_PrecacheEvent, g_fwdidPrecacheEvent, 1 )
}
}
public event_NewRound()
{
set_task( 0.2, "LoadMessagesFromArray" )
}
public client_putinserver( id )
{
set_task( 3.0, "LoadMessagesFromArray" )
}
public cmd_WallText( id )
{
if( !( get_user_flags( id ) & ACCESS_LEVEL ) )
return PLUGIN_HANDLED
new szArg[MESSAGE_LEN]
read_args( szArg, charsmax( szArg ) )
strtoupper( szArg )
CreateNewMessage( id, szArg )
return PLUGIN_HANDLED
}
public cmd_WallTextMenu( id )
{
if( !( get_user_flags( id ) & ACCESS_LEVEL ) )
return PLUGIN_HANDLED
new iMenu = menu_create( "Fal szoveg menu:", "menu_HandleMainMenu" )
menu_additem( iMenu, "Uj szoveg", "1" )
menu_additem( iMenu, "Szoveg mentese", "2" )
menu_additem( iMenu, "Szoveg torlese", "3" )
if( g_iDecalResetEvent != 0 )
menu_additem( iMenu, "Refresh Canvas", "4" )
menu_setprop( iMenu, MPROP_EXIT, MEXIT_ALL )
menu_display( id, iMenu, 0 )
return PLUGIN_HANDLED
}
public cmd_SaveWallText( id )
{
if( !( get_user_flags( id ) & ACCESS_LEVEL ) )
return PLUGIN_HANDLED
new iSize = ArraySize(g_aMessages)
new szMessage[MESSAGE_LEN]
new szIndex[8]
new iMenu = menu_create( "Szoveg mentese menu:", "menu_HandleSaveMenu" )
for( new i = 0; i < iSize; i++ )
{
if( ArrayGetCell( g_aSaved, i ) )
continue
ArrayGetString( g_aMessages, i, szMessage, MESSAGE_LEN - 1 )
num_to_str( i, szIndex, charsmax( szIndex ) )
menu_additem( iMenu, szMessage, szIndex, 0 )
}
menu_additem( iMenu, "Vissza", "-1", 0 )
menu_setprop( iMenu, MPROP_EXIT, MEXIT_NEVER )
menu_display( id, iMenu, 0 )
return PLUGIN_HANDLED
}
public cmd_DeleteWallText( id )
{
if( !( get_user_flags( id ) & ACCESS_LEVEL ) )
return PLUGIN_HANDLED
new fh = fopen( g_szFile, "rt" )
if( !fh )
return PLUGIN_HANDLED
new iLine
new szIndex[8]
new szBuffer[BUFFER_LEN]
new iMenu = menu_create( "Mentett szoveg torlese:", "menu_HandleDeleteMenu" )
while( !feof( fh ) )
{
fgets( fh, szBuffer, charsmax( szBuffer ) )
if( ExtractMessage( szBuffer ) )
{
num_to_str( iLine, szIndex, charsmax( szIndex) )
menu_additem( iMenu, szBuffer, szIndex, 0 )
szBuffer[0] = 0
}
iLine++
}
fclose( fh )
menu_additem( iMenu, "Back", "-1", 0 )
menu_setprop( iMenu, MPROP_EXIT, MEXIT_NEVER )
menu_display( id, iMenu, 0 )
return PLUGIN_HANDLED
}
public menu_HandleMainMenu( id, menu, item )
{
if( item == MENU_EXIT )
{
menu_destroy( menu )
return PLUGIN_HANDLED
}
new iAccess, szInfo[8], szName[32], iCallBack
menu_item_getinfo( menu, item, iAccess, szInfo, charsmax( szInfo ), szName, charsmax( szName ), iCallBack )
switch( str_to_num( szInfo ) )
{
case 1:
{
client_cmd( id, "messagemode amx_walltext" )
cmd_WallTextMenu( id )
}
case 2:
{
menu_destroy( menu )
cmd_SaveWallText( id )
}
case 3:
{
menu_destroy( menu )
cmd_DeleteWallText( id )
}
case 4:
{
engfunc( EngFunc_PlaybackEvent, FEV_GLOBAL, 0, g_iDecalResetEvent )
cmd_WallTextMenu( id )
set_task( 0.2, "LoadMessagesFromArray" )
}
}
return PLUGIN_HANDLED
}
public menu_HandleSaveMenu( id, menu, item )
{
if( item == MENU_EXIT )
{
menu_destroy( menu )
cmd_WallTextMenu( id )
return PLUGIN_HANDLED
}
new szMessage[MESSAGE_LEN], szIndex[8]
new iAccess, iCallBack
menu_item_getinfo( menu, item, iAccess, szIndex, charsmax( szIndex ), szMessage, charsmax( szMessage ), iCallBack )
new iIndex = str_to_num( szIndex )
if( iIndex == -1 )
{
menu_destroy( menu )
cmd_WallTextMenu( id )
return PLUGIN_HANDLED
}
WriteToFile( iIndex )
client_print( id, print_chat, "* Hozzaadva a szoveg '%s' '%s'", szMessage, g_szFile )
cmd_SaveWallText( id )
return PLUGIN_HANDLED
}
public menu_HandleDeleteMenu( id, menu, item )
{
if( item == MENU_EXIT )
{
menu_destroy( menu )
cmd_WallTextMenu( id )
return PLUGIN_HANDLED
}
new szMessage[MESSAGE_LEN], szIndex[8]
new iAccess, iCallBack
menu_item_getinfo( menu, item, iAccess, szIndex, charsmax( szIndex ), szMessage, charsmax( szMessage ), iCallBack )
if( str_to_num( szIndex ) == -1 )
{
menu_destroy( menu )
cmd_WallTextMenu( id )
return PLUGIN_HANDLED
}
new fh = fopen( g_szFile, "rt" )
if( !fh )
return PLUGIN_HANDLED
new szBuffer[BUFFER_LEN]
new iLine
while( !feof( fh ) )
{
fgets( fh, szBuffer, charsmax( szBuffer ) )
if( ExtractMessage( szBuffer ) )
{
if( equal( szBuffer, szMessage ) )
{
fclose( fh )
write_file( g_szFile, "", iLine )
client_print( id, print_chat, "* Torolve a '%s' uzenet '%s'", szMessage, g_szFile )
cmd_DeleteWallText( id )
ArrayClear( g_aOrigins )
ArrayClear( g_aVectors )
ArrayClear( g_aMessages )
ArrayClear( g_aSaved )
LoadMessagesFromFile()
return PLUGIN_HANDLED
}
szBuffer[0] = 0
}
iLine++
}
fclose( fh )
return PLUGIN_HANDLED
}
public LoadMessagesFromArray()
{
new iSize = ArraySize( g_aOrigins )
new Float:fOrigin[3]
new Float:fVector[3]
new szMessage[MESSAGE_LEN]
for( new i = 0; i < iSize; i++ )
{
ArrayGetArray( g_aOrigins, i, fOrigin )
ArrayGetArray( g_aVectors, i, fVector )
ArrayGetString( g_aMessages, i, szMessage, charsmax( szMessage ) )
DrawMessage( szMessage, fOrigin, fVector )
}
}
public LoadMessagesFromFile()
{
new fh = fopen( g_szFile, "rt" )
if( !fh )
return PLUGIN_HANDLED
new szBuffer[BUFFER_LEN]
new szPart[BUFFER_LEN]
new Float:fOrigin[3]
new Float:fVector[3]
new szMessage[MESSAGE_LEN]
while( !feof( fh ) )
{
fgets( fh, szBuffer, charsmax( szBuffer ) )
if( strlen(szBuffer) < 13 ) continue
strtok( szBuffer, szPart, charsmax( szPart ), szBuffer, charsmax( szBuffer ), ';', 1 )
fOrigin[0] = str_to_float( szPart )
strtok( szBuffer, szPart, charsmax( szPart ), szBuffer, charsmax( szBuffer ), ';', 1 )
fOrigin[1] = str_to_float( szPart )
strtok( szBuffer, szPart, charsmax( szPart ), szBuffer, charsmax( szBuffer ), ';', 1 )
fOrigin[2] = str_to_float( szPart )
strtok( szBuffer, szPart, charsmax( szPart ), szBuffer, charsmax( szBuffer ), ';', 1 )
fVector[0] = str_to_float( szPart )
strtok( szBuffer, szPart, charsmax( szPart ), szBuffer, charsmax( szBuffer ), ';', 1 )
fVector[1] = str_to_float( szPart )
strtok( szBuffer, szPart, charsmax( szPart ), szMessage, charsmax( szMessage ), ';', 1 )
fVector[2] = str_to_float( szPart )
replace( szMessage, charsmax( szMessage ), "^n", "" )
if( file_exists( szMessage ) )
{
new fh2 = fopen( szMessage, "rt" )
if( fh2 )
{
fgets( fh2, szMessage, charsmax( szMessage ) )
fclose( fh2 )
}
}
strtoupper( szMessage )
ArrayPushArray( g_aOrigins, fOrigin )
ArrayPushArray( g_aVectors, fVector )
ArrayPushString( g_aMessages, szMessage )
ArrayPushCell( g_aSaved, 1 )
DrawMessage( szMessage, fOrigin, fVector )
}
fclose( fh )
return PLUGIN_HANDLED
}
ExtractMessage( szBuffer[BUFFER_LEN] )
{
new iLen = strlen( szBuffer )
new iSemicolonCount = 0
for( new i = 0; i < iLen; i++ )
{
if( szBuffer[i] == ';' )
{
iSemicolonCount++
}
if( iSemicolonCount == 6 )
{
copy( szBuffer, charsmax( szBuffer ), szBuffer[i+1] )
replace(szBuffer, charsmax( szBuffer ), "^n", "")
return 1
}
}
return 0
}
WriteToFile( iIndex )
{
new Float:fOrigin[3]
new Float:fVector[3]
new szMessage[MESSAGE_LEN]
ArrayGetArray( g_aOrigins, iIndex, fOrigin )
ArrayGetArray( g_aVectors, iIndex, fVector )
ArrayGetString( g_aMessages, iIndex, szMessage, charsmax( szMessage ) )
new szBuffer[BUFFER_LEN]
formatex( szBuffer, charsmax( szBuffer ), "%f;%f;%f;%f;%f;%f;%s",
fOrigin[0], fOrigin[1], fOrigin[2],
fVector[0], fVector[1], fVector[2],
szMessage )
write_file( g_szFile, szBuffer, -1 )
ArraySetCell( g_aSaved, iIndex, 1 )
}
DrawMessage( szMessage[MESSAGE_LEN], Float:fAimOrigin[3], Float:fTextVector[3] )
{
new Float:fOffset[3]
new iLen = strlen( szMessage )
fOffset[0] = 0.0
fOffset[1] = 0.0
fOffset[2] = 0.0
for( new i = 0; i < iLen; i++ )
{
if( isalpha( szMessage[i] ) )
{
DrawDecal( fAimOrigin[0] + fOffset[0], fAimOrigin[1] + fOffset[1], fAimOrigin[2] + fOffset[2], g_iDecalAlphaBk )
}
else if( szMessage[i] == ',' )
{
fOffset[0] = 0.0
fOffset[1] = 0.0
fOffset[2] -= 23.0
}
fOffset[0] += fTextVector[0]
fOffset[1] += fTextVector[1]
}
fOffset[0] = 0.0
fOffset[1] = 0.0
fOffset[2] = 0.0
for( new i = 0; i < iLen; i++ )
{
if( '0' <= szMessage[i] <= '9' )
{
DrawDecal( fAimOrigin[0] + fOffset[0], fAimOrigin[1] + fOffset[1], fAimOrigin[2] + fOffset[2], g_iDecalDigitBk )
}
else if( szMessage[i] == ',' )
{
fOffset[0] = 0.0
fOffset[1] = 0.0
fOffset[2] -= 23.0
}
fOffset[0] += fTextVector[0]
fOffset[1] += fTextVector[1]
}
fOffset[0] = 0.0
fOffset[1] = 0.0
fOffset[2] = 0.0
for( new i = 0; i < iLen; i++ )
{
if( isalpha( szMessage[i] ) )
{
DrawDecal( fAimOrigin[0] + fOffset[0], fAimOrigin[1] + fOffset[1], fAimOrigin[2] + fOffset[2], g_iDecalAlpha + 'A' - szMessage[i] )
}
else if( szMessage[i] == ',' )
{
fOffset[0] = 0.0
fOffset[1] = 0.0
fOffset[2] -= 23.0
}
fOffset[0] += fTextVector[0]
fOffset[1] += fTextVector[1]
}
fOffset[0] = 0.0
fOffset[1] = 0.0
fOffset[2] = 0.0
for( new i = 0; i < iLen; i++ )
{
if( '0' <= szMessage[i] <= '9' )
{
DrawDecal( fAimOrigin[0] + fOffset[0], fAimOrigin[1] + fOffset[1], fAimOrigin[2] + fOffset[2], g_iDecalDigit + '0' - szMessage[i] )
}
else if( szMessage[i] == ',' )
{
fOffset[0] = 0.0
fOffset[1] = 0.0
fOffset[2] -= 23.0
}
fOffset[0] += fTextVector[0]
fOffset[1] += fTextVector[1]
}
}
CreateNewMessage( id, szMessage[MESSAGE_LEN] )
{
new Float:fAimOrigin[3]
new Float:fPlayerOrigin[3]
new Float:fAimVector[3]
new Float:fNormalVector[3]
new Float:fTextVector[3]
pev( id, pev_v_angle, fAimVector )
angle_vector( fAimVector, ANGLEVECTOR_FORWARD, fAimVector )
pev( id, pev_origin, fPlayerOrigin )
fAimVector[0] = fAimVector[0] * 9999.0 + fPlayerOrigin[0]
fAimVector[1] = fAimVector[1] * 9999.0 + fPlayerOrigin[1]
fAimVector[2] = fAimVector[2] * 9999.0 + fPlayerOrigin[2]
new iTr = create_tr2()
engfunc( EngFunc_TraceLine, fPlayerOrigin, fAimVector, IGNORE_MONSTERS, id, iTr )
get_tr2( iTr, TR_vecEndPos, fAimOrigin )
get_tr2( iTr, TR_vecPlaneNormal, fNormalVector )
free_tr2( iTr )
vector_to_angle( fNormalVector, fTextVector )
angle_vector( fTextVector, ANGLEVECTOR_RIGHT, fTextVector )
fTextVector[0] *= -1.0 * CHAR_WIDTH
fTextVector[1] *= -1.0 * CHAR_WIDTH
fTextVector[2] *= -1.0 * CHAR_WIDTH
DrawMessage( szMessage, fAimOrigin, fTextVector )
ArrayPushArray( g_aOrigins, fAimOrigin )
ArrayPushArray( g_aVectors, fTextVector )
remove_quotes( szMessage )
replace( szMessage, charsmax( szMessage ), "^n", "" )
ArrayPushString( g_aMessages, szMessage )
ArrayPushCell( g_aSaved, 0 )
}
DrawDecal( Float:x, Float:y, Float:z, tid )
{
message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
if( tid > 255 )
{
tid -= 255
write_byte( TE_WORLDDECALHIGH )
}
else
{
write_byte( TE_WORLDDECAL )
}
engfunc( EngFunc_WriteCoord, x )
engfunc( EngFunc_WriteCoord, y )
engfunc( EngFunc_WriteCoord, z )
write_byte( tid )
message_end()
}