Ok made a new. Really i think this is the best way to do this. Its the most realistic and best performance I think. Please give me feedback on this.
PHP Code:
#include < amxmodx >
#include < fakemeta >
#include < engine >
#include < hamsandwich >
#include < fun >
new g_szPluginInfo[3][10] = { "Parachute", "1.0", "Pastout" }
#define PARACHUTE_MODEL "models/angel2.mdl"
#define MAX_PLAYERS 32
#define MarkUserHasParachute(%0) g_bitHasParachute |= (1<<(%0&31))
#define ClearUserHasParachute(%0) g_bitHasParachute &= ~(1<<(%0&31))
#define HasUserParachute(%0) g_bitHasParachute & (1<<(%0&31))
#define MarkUserAlive(%0) g_bitAlive |= (1<<(%0&31))
#define ClearUserAlive(%0) g_bitAlive &= ~(1<<(%0&31))
#define GetUserAlive(%0) g_bitAlive & (1<<(%0&31))
#define MarkUserButton(%0) g_bitButton |= (1<<(%0&31))
#define ClearUserButton(%0) g_bitButton &= ~(1<<(%0&31))
#define GetUserButton(%0) g_bitButton & (1<<(%0&31))
new g_bitAlive
new g_bitHasParachute
new g_bitButton
new g_iUserParachute[MAX_PLAYERS+1]
new Float:g_flEntityFrame[MAX_PLAYERS+1]
new Float:get_userGravity[MAX_PLAYERS+1]
new g_iModelIndex
new g_pCvarFallSpeed, g_pCvarDeploySpeed
//const m_afButtonPressed = 246
const m_afButtonReleased = 247
new const PARACHUTE_CLASS[] = "parachute"
new Float:get_cvar[2]
enum {
PARA_FALLSPEED,
PARA_DEPLOYSPEED
}
enum {
deploy,
idle,
detach
}
public plugin_init() {
register_plugin(g_szPluginInfo[0], g_szPluginInfo[1], g_szPluginInfo[2])
g_pCvarFallSpeed = register_cvar("p_fallspeed", "0.05")
g_pCvarDeploySpeed = register_cvar("p_deployspeed", "0.01")
static g_szPlayer[] = "player"
RegisterHam(Ham_Spawn, g_szPlayer, "Ham_CBasePlayer_Spawn_Post", .Post = true)
RegisterHam(Ham_Killed, g_szPlayer, "Ham_CBasePlayer_Killed_Post", .Post = true)
RegisterHam(Ham_ObjectCaps, g_szPlayer, "Ham_CBasePlayer_ObjectCaps", .Post = false)
register_forward(FM_CmdStart, "FM_CBasePlayer_CmdStart")
register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0")
register_think(PARACHUTE_CLASS, g_szPluginInfo[0])
}
public plugin_precache()
g_iModelIndex = precache_model(PARACHUTE_MODEL)
public client_putinserver(id)
ClearUserAlive(id)
public client_disconnect(id) {
SetParachuteSettings(id)
ClearUserAlive(id)
}
public Ham_CBasePlayer_Killed_Post( id ) {
SetParachuteSettings(id)
ClearUserAlive(id)
}
public Event_NewRound( ) {
get_cvar[0] = get_pcvar_float(g_pCvarFallSpeed)
get_cvar[1] = get_pcvar_float(g_pCvarDeploySpeed)
}
public Ham_CBasePlayer_Spawn_Post(id) {
if( is_user_alive(id) ) {
SetParachuteSettings(id)
ClearUserButton(id)
MarkUserAlive(id)
}
}
SetParachuteSettings(id)
if( HasUserParachute(id) )
RemoveUserParachute(id)
RemoveUserParachute(id) {
new iEnt = g_iUserParachute[id]
if(iEnt)
engfunc(EngFunc_RemoveEntity, iEnt)
g_iUserParachute[id] = 0
set_user_gravity(id, get_userGravity[id])
ClearUserHasParachute(id)
}
public FM_CBasePlayer_CmdStart(id, handle)
if(GetUserAlive(id))
if( entity_get_int( id, EV_INT_button ) & IN_USE )
MarkUserButton(id)
public Ham_CBasePlayer_ObjectCaps(id) {
if(GetUserButton(id))
{
new flags = get_entity_flags(id)
new isOnGround = flags & FL_ONGROUND
new isInWater = (pev(id, pev_waterlevel) > 0)
if(~HasUserParachute(id) && GetUserButton(id)) {
if( isOnGround || isInWater )
return
//client_print(id, print_chat, "Created parachute")
get_userGravity[id] = get_user_gravity(id)
CreateParachute(id)
}
else if(HasUserParachute(id) && get_pdata_int(id, m_afButtonReleased) & IN_USE) {
//client_print(id, print_chat, "You release IN_USE NO more parachute" )
RemoveUserParachute(id)
ClearUserButton(id)
}
if(HasUserParachute(id) && ( isOnGround || isInWater ) ) {
//client_print(id, print_chat, "NO more parachute on ground" )
RemoveUserParachute(id)
}
}
}
CreateParachute(id) {
static iszInfoTarget
if( !iszInfoTarget ) {
iszInfoTarget = engfunc(EngFunc_AllocString, "info_target")
}
new iEnt = engfunc(EngFunc_CreateNamedEntity, iszInfoTarget)
if( iEnt > 0) {
static iszClass = 0
if( !iszClass ) {
iszClass = engfunc(EngFunc_AllocString, PARACHUTE_CLASS)
}
set_pev_string(iEnt, pev_classname, iszClass)
set_pev(iEnt, pev_aiment, id)
set_pev(iEnt, pev_owner, id)
set_pev(iEnt, pev_movetype, MOVETYPE_FOLLOW)
static iszModel = 0
if( !iszModel ) {
iszModel = engfunc(EngFunc_AllocString, PARACHUTE_MODEL)
}
set_pev_string(iEnt, pev_model, iszModel)
set_pev(iEnt, pev_modelindex, g_iModelIndex)
set_pev(iEnt, pev_sequence, deploy)
set_pev(iEnt, pev_gaitsequence, 1)
set_pev(iEnt, pev_frame, 0.0)
set_pev(iEnt, pev_rendermode, pev(id, pev_rendermode))
set_pev(iEnt, pev_renderfx, pev(id, pev_renderfx))
new Float:f_renderamt
pev(id, pev_renderamt, f_renderamt)
set_pev(iEnt, pev_renderamt, f_renderamt)
g_flEntityFrame[id] = 0.0
g_iUserParachute[id] = iEnt
MarkUserHasParachute(id)
new Float:fVecOrigin[3]
pev(id, pev_origin, fVecOrigin)
set_pev(iEnt, pev_nextthink, get_gametime() + get_cvar[1])
return iEnt
}
return 0
}
public Parachute(iEnt)
{
if(!pev_valid(iEnt))
return
static id
id = pev(iEnt, pev_owner)
new Float:flFrame
new iEnt = g_iUserParachute[id]
if( HasUserParachute(id) ) {
new Float:fVecVelocity[3], Float:fVelocity_z
pev(id, pev_velocity, fVecVelocity)
fVelocity_z = fVecVelocity[2]
if( fVelocity_z < 0.0 ) {
if(iEnt <= 0) {
iEnt = CreateParachute(id)
}
//fVelocity_z = floatmin(fVelocity_z + 14.0, -get_cvar[PARA_FALLSPEED])
//fVecVelocity[2] = fVelocity_z
//set_pev(id, pev_velocity, fVecVelocity)
set_user_gravity(id, get_cvar[0]+get_cvar[0])
if( pev(iEnt, pev_sequence) == deploy) {
flFrame = g_flEntityFrame[id]++
if(flFrame > 100.0) {
set_pev(iEnt, pev_animtime, 0.0)
set_pev(iEnt, pev_framerate, 0.4)
set_pev(iEnt, pev_sequence, idle)
set_pev(iEnt, pev_gaitsequence, 1)
set_pev(iEnt, pev_frame, 0.0)
g_flEntityFrame[id] = 0.0
}
else {
set_pev(iEnt, pev_frame, flFrame)
}
}
}
}
set_pev(iEnt, pev_nextthink, get_gametime() + 0.01)
}