PHP Code:
#define WITH_MONEY
// Delete the line above for this plugin
// to work with other mods with different
// money system (from CS) / no money
#define MAX_MDLS 256
//Max models in menu
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <engine>
#include <fun>
#if defined WITH_MONEY
#include <cstrike>
#endif
#define PLUGIN "Shape shifter"
#define VERSION "1.7"
#define AUTHOR "Toster v2.1"
#define X 0
#define Y 1
#define Z 2
new ent[32]
new mdl[32]
new shifted[32]
new page[32]
new list[MAX_MDLS][64]
new seq[MAX_MDLS]
new name[MAX_MDLS][64]
new Float: off[MAX_MDLS]
new numlines, lp
new nofile
new file[64]
new mapf[64]
new map[16]
new ss_enabled
new ss_changecam
new ss_canmove
new ss_popup
#if defined WITH_MONEY
new ss_shape_cost
new ss_shift_cost
new ss_free_for_admins
#endif
new bool:g_restart_attempt[32]
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
ss_enabled = register_cvar("ss_enabled", "1")
ss_changecam = register_cvar("ss_changecam", "1")
ss_canmove = register_cvar("ss_canmove", "0")
ss_popup = register_cvar("ss_popup", "1")
#if defined WITH_MONEY
ss_shape_cost = register_cvar("ss_shape_cost", "800")
ss_shift_cost = register_cvar("ss_shift_cost", "200")
ss_free_for_admins = register_cvar("ss_free_for_admins", "0")
#endif
register_menucmd(register_menuid("ssmenu"),1023,"actionMenu")
register_forward(FM_PlayerPostThink, "postThink")
register_event("Damage", "event_Damage", "b", "2!0", "3=0", "4!0")
register_event("DeathMsg", "event_Dead", "a")
register_clcmd("say /ss", "ss_menu")
register_clcmd("say_team /ss", "ss_menu")
register_clcmd("+shift", "hidepl")
register_clcmd("-shift", "showpl")
register_clcmd("say /shift", "hidepl")
register_clcmd("say /unshift", "hidepl")
register_clcmd("ss_mdl_up", "mdlup", ADMIN_RCON)
register_clcmd("ss_mdl_down", "mdldown", ADMIN_RCON)
register_event("ResetHUD", "event_hud_reset", "be")
register_clcmd("fullupdate", "clcmd_fullupdate")
register_event("TextMsg", "event_restart_attempt", "a", "2=#Game_will_restart_in")
}
public mdlup(id)
{
off[mdl[id-1]] += 1.0
client_print(id, print_console, "[SS] Modle offset: %f", off[mdl[id-1]])
return PLUGIN_HANDLED
}
public mdldown(id)
{
off[mdl[id-1]] -= 1.0
client_print(id, print_console, "[SS] Modle offset: %f", off[mdl[id-1]])
return PLUGIN_HANDLED
}
public event_Damage(id)
{
if(shifted[id-1])
{
set_user_health(id, get_user_health(id)/2)
showpl(id)
}
}
public event_Dead()
{
new id = read_data(2)
showpl(id)
#if defined WITH_MONEY
mdl[id-1] = -1
#endif
}
public plugin_precache()
{
new lines=0,k=0, line[256]
new tmp[32]
get_configsdir(file, 63)
format(mapf, 64, file)
strcat(file, "/ss_models.ini", 63)
get_mapname(map, 15)
format(tmp, 31, "/ss_maps/%s.ini", map)
strcat(mapf, tmp, 63)
if(!file_exists(file))
{
nofile = 1
return PLUGIN_HANDLED
}
//Fix 3rd person bug
precache_model("models/rpgrocket.mdl")
while( read_file(file,lines++,line,255,k))
{
if((line[0] == ';') || !k) continue
strtok(line, tmp, 31, line, 255, ' ')
seq[numlines] = str_to_num(tmp)
strtok(line, tmp, 31, line, 255, ' ')
off[numlines] = str_to_float(tmp)
strtok(line, line, 255, name[numlines], 63, ' ')
if(numlines < MAX_MDLS && file_exists(line))
{
copy(list[numlines],63,line)
precache_model(line)
numlines++
}
else if(file_exists(line)) break
}
if(file_exists(mapf))
{
lines = 0
while( read_file(mapf,lines++,line,255,k))
{
if((line[0] == ';') || !k) continue
strtok(line, tmp, 31, line, 255, ' ')
seq[numlines] = str_to_num(tmp)
strtok(line, tmp, 31, line, 255, ' ')
off[numlines] = str_to_float(tmp)
strtok(line, line, 255, name[numlines], 63, ' ')
if(numlines < MAX_MDLS && file_exists(line))
{
copy(list[numlines],63,line)
precache_model(line)
numlines++
}
else if(file_exists(line)) break
}
}
lp = (numlines-1)/7
return PLUGIN_CONTINUE
}
public client_connect(id)
{
ent[id-1] = 0
mdl[id-1] = -1
page[id-1] = 0
}
public actionMenu(id,key)
{
if(key == 7 && page[id-1] != 0)
{
page[id-1]--
ss_menu(id)
}
else if(key == 8 && page[id-1] != lp)
{
page[id-1]++
ss_menu(id)
}
else if(key != 9)
{
if(page[id-1]*7+key > numlines-1) return PLUGIN_CONTINUE
#if defined WITH_MONEY
if(access(id, ADMIN_IMMUNITY) && get_pcvar_num(ss_free_for_admins)==1)
{
client_print(id, print_chat, "[SS] Free for admins!")
mdl[id-1] = page[id-1]*7+key
}
else
{
if(cs_get_user_money(id)>=get_pcvar_num(ss_shape_cost))
{
cs_set_user_money(id, cs_get_user_money(id)-get_pcvar_num(ss_shape_cost))
mdl[id-1] = page[id-1]*7+key
}
else client_print(id, print_chat, "[SS] Not enough money!")
}
#else
mdl[id-1] = page[id-1]*7+key
#endif
}
return PLUGIN_HANDLED
}
public ss_menu(id)
{
if(get_pcvar_num(ss_enabled)==0) return PLUGIN_HANDLED
else if(get_pcvar_num(ss_enabled)==2&&!access(id, ADMIN_IMMUNITY)) return PLUGIN_HANDLED
if(shifted[id-1])
{
client_print(id, print_chat, "[SS] You can't chnge shape while shifted!")
return PLUGIN_HANDLED
}
new menuBody[512]
new len = format(menuBody,511,"\rShape shifter Mod Menu^nbind + shift to hide^nType /ss in chat to see this menu\w^n^n")
#if defined WITH_MONEY
len += format(menuBody[len],511-len,"Shape cost: %d^n^n",get_pcvar_num(ss_shape_cost))
#endif
if(nofile == 1)len += format(menuBody[len],511-len,"File not found:^n%s", file)
else if(numlines == 0)len += format(menuBody[len],511-len,"No models found in^n%s", file)
for(new i=page[id-1]*7; i<(page[id-1]+1)*7 && i<numlines; i++)
{
len += format(menuBody[len],511-len,"%d. %s^n",i+8-(page[id-1]+1)*7, name[i])
}
len += format(menuBody[len],511-len,"^n")
if(page[id-1]!=0)len += format(menuBody[len],511-len,"8. Prev^n")
if(page[id-1]!=lp)len += format(menuBody[len],511-len,"9. Next^n")
len += format(menuBody[len],511-len,"0. Exit")
show_menu(id,1023,menuBody, _,"ssmenu")
return PLUGIN_HANDLED
}
public postThink(id)
{
if(get_pcvar_num(ss_canmove)==0) return FMRES_HANDLED
if(ent[id-1] == 0) return FMRES_HANDLED
new Float: orig[3], orig2[3]
pev(id, pev_origin, orig)
pev(ent[id-1], pev_origin, orig2)
if(pev(id, pev_flags) & FL_DUCKING)orig[Z] -= 18.0
else orig[Z] -= 36.0
orig[Z] += off[mdl[id-1]]
if(orig[X]!=orig2[X]||orig[Y]!=orig2[Y]||orig[Z]!=orig2[Z]) engfunc(EngFunc_SetOrigin, ent[id-1], orig)
return FMRES_HANDLED
}
public hidepl(id)
{
if(get_pcvar_num(ss_enabled)==0 || shifted[id-1]) return PLUGIN_HANDLED
else if(get_pcvar_num(ss_enabled)==2&&!access(id, ADMIN_IMMUNITY)) return PLUGIN_HANDLED
if(!is_user_alive(id))
{
client_print(id, print_chat, "[SS] Your dead....")
return PLUGIN_HANDLED
}
if(mdl[id-1]==-1)
{
client_print(id, print_chat, "[SS] No model selected!")
ss_menu(id)
return PLUGIN_HANDLED
}
#if defined WITH_MONEY
if(access(id, ADMIN_IMMUNITY) && get_pcvar_num(ss_free_for_admins)==1)
{
client_print(id, print_chat, "[SS] Free for admins!")
}
else
{
if(cs_get_user_money(id)<get_pcvar_num(ss_shift_cost))
{
client_print(id, print_chat, "[SS] Not enough money!")
return PLUGIN_HANDLED
}
cs_set_user_money(id, cs_get_user_money(id)-get_pcvar_num(ss_shift_cost))
}
#endif
shifted[id-1] = 1
new Float:origin[3]
engfunc(EngFunc_DropToFloor, id)
pev(id, pev_origin, origin)
if(pev(id, pev_flags) & FL_DUCKING)origin[Z] -= 18.0
else origin[Z] -= 36.0
origin[Z] += off[mdl[id-1]]
ent[id-1] = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
engfunc(EngFunc_SetOrigin, ent[id-1], origin)
set_pev(ent[id-1], pev_classname, "shape_shift")
engfunc(EngFunc_SetModel,ent[id-1], list[mdl[id-1]])
set_pev(ent[id-1], pev_animtime, 2.0)
set_pev(ent[id-1], pev_framerate, 1.0)
set_pev(ent[id-1], pev_sequence, seq[mdl[id-1]])
if(get_pcvar_num(ss_canmove)==0)set_pev(id, pev_flags, pev(id, pev_flags) | FL_FROZEN)
set_user_rendering(id,kRenderFxNone,0,0,0,kRenderTransAlpha,0)
if(get_pcvar_num(ss_changecam)==1) set_view(id, CAMERA_3RDPERSON)
return PLUGIN_HANDLED
}
public showpl(id)
{
if(get_pcvar_num(ss_enabled)==0) return PLUGIN_HANDLED
else if(get_pcvar_num(ss_enabled)==2&&!access(id, ADMIN_IMMUNITY)) return PLUGIN_HANDLED
shifted[id-1] = 0
if(ent[id-1]!=0)
{
engfunc(EngFunc_RemoveEntity, ent[id-1])
ent[id-1] = 0
set_pev(id, pev_flags, pev(id, pev_flags) & ~FL_FROZEN)
if(get_pcvar_num(ss_changecam)==1) set_view(id, CAMERA_NONE)
set_user_rendering(id,kRenderFxNone,0,0,0,kRenderTransAlpha,255)
}
return PLUGIN_HANDLED
}
public event_player_spawn(id)
{
if(ent[id-1]!=0) showpl(id)
else if(mdl[id-1]==-1 && get_pcvar_num(ss_popup)==1) ss_menu(id)
}
public clcmd_fullupdate() {
return PLUGIN_HANDLED_MAIN
}
public event_restart_attempt()
{
new players[32], num
get_players(players, num, "a")
for (new i; i < num; ++i)
g_restart_attempt[players[i]-1] = true
}
public event_hud_reset(id)
{
if (g_restart_attempt[id-1])
{
g_restart_attempt[id-1] = false
return
}
event_player_spawn(id)
}