I need to write "physics engine" for the smoke cause it stucks on the floor and no entvars can fix it. Heres how it looks. On certain direction it just bounces back - have hard time to get to the reason.
PHP Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <fakemeta_util>
#include <xs>
#include <float>
#include <voi_pub1>
#include <Vexd_Utilities>
//#include <bmod>
#define PLUGIN "Smoke Room"
#define AUTHOR "Voi"
#define VERSION "0.5"
#define SMOKE_THINKER 666
#define SMOKE_SPRITE 667
#define WIND_TASKID 23134
new Float:SMOKE_SIZE_MIN[3] = {-50.0, -50.0, -15.0}
new Float:SMOKE_SIZE_MAX[3] = {50.0, 50.0, 15.0}
new gun_smoke_spr
new Float:windvelocity[3]
new windforce
new smokeamount
new smokeradius
new directsmoke
new const room_smoke_spr[] = "sprites/voi/smoke_room17.spr"
public plugin_init()
{
windforce = register_cvar("smoke_windforce", "25") //Controls the force of the wind.
smokeamount = register_cvar("smoke_amount", "0.5") //Base scale of smoke sprite.
smokeradius = register_cvar("smoke_radius", "32") //Minimum radius between creation of new smoke sprites.
directsmoke = register_cvar("smoke_direct", "1") //Direct weapon smoke sprite - currently very fps consuming.
register_forward(FM_Think,"smoke_think",0)
//register_think("env_sprite", "sprite_think")
register_clcmd("say /test","fire")
register_plugin(PLUGIN, VERSION, AUTHOR)
// Add your own code here
wind_change()
}
public plugin_precache()
{
gun_smoke_spr = precache_model( "sprites/rifle_smoke3.spr" );
precache_model(room_smoke_spr)
}
public fire(id)
{
new Float:gunpos[3], stringClassname[24]
//ExecuteHam(Ham_Player_GetGunPosition, id, gunpos)
new Float:origin[3]
//pev(id, pev_origin, origin)
UTIL_GetGunPosition_voi( id, origin )
new found, eIndex[2]
new entity = -1
if(get_pcvar_float(directsmoke))
{
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, origin, 0)
write_byte(TE_SPRITE)
engfunc( EngFunc_WriteCoord, origin[ 0 ] );
engfunc( EngFunc_WriteCoord, origin[ 1 ] );
engfunc( EngFunc_WriteCoord, origin[ 2 ] );
write_short(gun_smoke_spr) // sprite
write_byte(1) // Count
write_byte(3) // Count
message_end()
}
/*engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, origin, 0)
write_byte(TE_ARMOR_RICOCHET)
engfunc( EngFunc_WriteCoord, origin[ 0 ] );
engfunc( EngFunc_WriteCoord, origin[ 1 ] );
engfunc( EngFunc_WriteCoord, origin[ 2 ] );
write_byte(1)
message_end()*/
//client_print(id, print_chat, "DEBUG: fire!(CHECKING FOR SMOKE)")
while( (entity = fm_find_ent_in_sphere(entity, origin, get_pcvar_float(smokeradius))) > 0)
{
if(!fm_is_valid_ent(entity))
continue
//pev(entity, pev_classname, stringClassname, charsmax(stringClassname))
//client_print(id, print_chat, "DEBUG: CLASSNAME = %s", stringClassname)
//
//if( equali("info_target", stringClassname) && pev(entity, pev_iuser4) == 666 )
if(pev(entity, pev_iuser4) == SMOKE_SPRITE )
{
/*new check
pev(entity, pev_iuser4, check)
if(check != 666)
continue*/
found += 1
if(found == 1)
eIndex[0] = entity
else if(found == 2)
eIndex[1] = entity
//client_print(id, print_chat, "DEBUG: SMOKE FOUND! %i %s, eIndex[0] = %i, eIndex[1] = %i iuser4 =%i iuser2=%i found=%i", entity, stringClassname, eIndex[0],eIndex[1],pev(entity, pev_iuser4), pev(entity, pev_iuser2), found )
}
}
if(!found)
{
//client_print(id, print_chat, "DEBUG: SMOKE NOT FOUND - CREATING NEW SMOKE!, found = %i",found)
create_room_smoke(id)
}
else
{
new Float:Eorigin1[3], Float:Eorigin2[3]
if(eIndex[0])
pev(eIndex[0], pev_origin, Eorigin1)
if(eIndex[1])
pev(eIndex[1], pev_origin, Eorigin2)
if(get_distance_f(origin, Eorigin1) > get_distance_f(origin, Eorigin2) && eIndex[1])
smoke_increase(id, eIndex[1])
else if(eIndex[0])
smoke_increase(id, eIndex[0])
}
}
public create_room_smoke(id)
{
/*new iEntO = fm_create_entity("info_target")
if(!pev_valid(iEntO))
{
return
}
set_pev(iEntO, pev_classname, "info_target")
engfunc(EngFunc_SetOrigin, iEntO, origin);
set_pev(iEntO, pev_movetype, MOVETYPE_BOUNCEMISSILE)
set_pev(iEntO, pev_solid, SOLID_TRIGGER)
set_pev(iEntO, pev_iuser4, SMOKE_THINKER )
set_pev(iEntO, pev_nextthink, get_gametime()+0.1)
//engfunc(EngFunc_SetSize, iEntO, Float:{64.0, 64.0, 64.0} , Float:{64.0, 64.0, 64.0})*/
new iEnt = fm_create_entity("info_target")
if(!pev_valid(iEnt))
{
//server_print("DEBUG: qENTITY = %i", iEnt)
return
}
//
//set_pev(iEnt, pev_iuser2, iEnt)
//server_cmd("say DEBUG: iEnt = %i, valid = %i", pev(iEntO, pev_iuser2), pev_valid( pev(iEntO, pev_iuser2)))
new Float:origin[3]
//pev(id, pev_origin, origin)
UTIL_GetGunPosition_voi( id, origin )
set_pev(iEnt, pev_owner, id)
set_pev(iEnt, pev_classname, "info_target")
set_pev(iEnt, pev_spawnflags, SF_SPRITE_STARTON)
engfunc(EngFunc_SetOrigin, iEnt, origin);
engfunc(EngFunc_SetModel, iEnt, room_smoke_spr)
set_pev(iEnt, pev_scale, get_pcvar_float(smokeamount) * 0.1)
set_pev(iEnt, pev_solid, SOLID_NOT)
set_pev(iEnt, pev_rendermode, kRenderTransAlpha)
set_pev(iEnt, pev_renderamt, 5.0)
set_pev(iEnt, pev_iuser4, SMOKE_SPRITE )
//set_pev(iEnt, pev_friction, 999.0)
//set_pev(iEnt, pev_velocity, {0.0, 0.0, 50.0})
set_pev(iEnt, pev_nextthink, get_gametime()+0.01)
new Float:angles[3]
switch(random_num(0,1))
{
case 1:
{
xs_vec_set(angles, 0.0,0.0,180.0)
}
}
xs_vec_mul_scalar(angles, random_float(0.75, 1.25), angles)
set_pev(iEnt, pev_angles, angles)
dllfunc(DLLFunc_Spawn,iEnt)
set_pev(iEnt, pev_movetype, MOVETYPE_NOCLIP )
smoke_increase(id, iEnt)
//new object = bmod_obj_from_ent(iEnt)
//bmod_obj_assign_ent(object, iEnt)
//hook entity with bmod object
//bmod_obj_assign_ent(object, entity);
//bmod_obj_update_pos(object);
//set_pev(iEnt, pev_aiment, iEntO)
}
public smoke_increase(id, iEnt)
{
new Float:scale, Float:renderamt, Float:entityvelocity[3], Float:playervelocity[3], Float:gunvelocity[3]
pev(id, pev_velocity, playervelocity)
pev(iEnt, pev_velocity, entityvelocity)
velocity_by_aim(id, 250, gunvelocity)
xs_vec_add(gunvelocity, playervelocity, playervelocity)
xs_vec_mul_scalar(playervelocity, 0.01, playervelocity)
xs_vec_add(entityvelocity, playervelocity, entityvelocity)
set_pev(iEnt, pev_velocity, entityvelocity)
//client_print(id, print_chat, "DEBUG: SMOKE VELOCITY ADDED = %f %f %f", entityvelocity[0], entityvelocity[1], entityvelocity[2])
pev(iEnt, pev_scale, scale)
pev(iEnt, pev_renderamt, renderamt)
scale += 0.005
renderamt += 1.0
floatclamp(renderamt, 0.0, 255.0)
set_pev(iEnt, pev_scale, scale)
set_pev(iEnt, pev_renderamt, renderamt)
//set_pev(id, pev_velocity, entityvelocity)
return FMRES_IGNORED
}
public smoke_think(iEnt)
{
if(!fm_is_valid_ent(iEnt) )
return FMRES_IGNORED
new smoke_id = pev(iEnt, pev_iuser4)
//if(smoke_id)
//server_print("DEBUG: SMOKE THINK ENTITY = %i, SMOKE ID = %i, SPRITE ID =%i", iEntO, smoke_id, iEnt)
if ( smoke_id == SMOKE_THINKER)
{
set_pev(iEnt, pev_nextthink, get_gametime()+0.01)
smoke_id = pev(iEnt, pev_iuser4)
}
if(smoke_id == SMOKE_SPRITE)
{
new Float:renderamt, Float:origin[3], Float:scale, Float:velocity[3], Float:velocity_old[3], num_push, Float:time_push, Float:time_push_small, num_push_small, Float:size_min[3], Float:size_max[3]
pev(iEnt, pev_scale, scale)
pev(iEnt, pev_renderamt, renderamt)
pev(iEnt, pev_velocity, velocity)
pev(iEnt, pev_origin, origin)
pev(iEnt, pev_fuser2, time_push)
pev(iEnt, pev_fuser3, time_push_small)
pev(iEnt, pev_fuser4, velocity_old)
//pev(iEnt, pev_maxs, size_max)
//pev(iEnt, pev_mins, size_min)
//if(!time_push)
// time_push = get_gametime()
//if(!time_push_small)
// time_push_small = get_gametime()
num_push = pev(iEnt, pev_iuser1)
num_push_small = pev(iEnt, pev_iuser2)
new Float:velocitynoise[3]
switch(random_num(1,50))
{
case 24:
{
new Texture[32], Float:origin[3], Float:direction[3] = {0.0,0.0,400.0}, Float:EndPos[3], TraceHandle
pev(iEnt, pev_origin, origin)
origin[2] += 60.0
xs_vec_set(direction, 0.0,0.0,400.0)
xs_vec_mul_scalar(direction, 8120.0, EndPos)
VectorMA( origin, 8192.0, direction, EndPos )
engfunc( EngFunc_TraceTexture, max( 0, get_tr2( TraceHandle, TR_pHit ) ) , origin, EndPos, Texture, charsmax( Texture ) );
//server_print("DEBUG: TEXTURE = %s", Texture)
if(equali(Texture, "sky"))
set_pev(iEnt, pev_iuser3, 1)
else
{
xs_vec_set(direction, 400.0,0.0,0.0)
xs_vec_mul_scalar(direction, 8120.0, EndPos)
engfunc( EngFunc_TraceTexture, max( 0, get_tr2( TraceHandle, TR_pHit ) ) , origin, EndPos, Texture, charsmax( Texture ) );
if(equali(Texture, "sky"))
set_pev(iEnt, pev_iuser3, 1)
else
{
xs_vec_set(direction, -400.0,0.0,0.0)
xs_vec_mul_scalar(direction, 8120.0, EndPos)
engfunc( EngFunc_TraceTexture, max( 0, get_tr2( TraceHandle, TR_pHit ) ) , origin, EndPos, Texture, charsmax( Texture ) );
if(equali(Texture, "sky"))
set_pev(iEnt, pev_iuser3, 1)
else
{
xs_vec_set(direction, 0.0,400.0,0.0)
xs_vec_mul_scalar(direction, 8120.0, EndPos)
engfunc( EngFunc_TraceTexture, max( 0, get_tr2( TraceHandle, TR_pHit ) ) , origin, EndPos, Texture, charsmax( Texture ) );
if(equali(Texture, "sky"))
set_pev(iEnt, pev_iuser3, 1)
else
{
xs_vec_set(direction, 0.0,-400.0,0.0)
xs_vec_mul_scalar(direction, 8120.0, EndPos)
engfunc( EngFunc_TraceTexture, max( 0, get_tr2( TraceHandle, TR_pHit ) ) , origin, EndPos, Texture, charsmax( Texture ) );
if(equali(Texture, "sky"))
set_pev(iEnt, pev_iuser3, 1)
else
set_pev(iEnt, pev_iuser3, 0)
}
}
}
}
}
}
if(num_push < 10 && get_gametime() > time_push)
{
num_push += 1
set_pev(iEnt, pev_iuser1, num_push)
new Float:windvelocity_calc[3]
if(pev(iEnt, pev_iuser3) == 1) // IF ITS OUTDOOR
xs_vec_mul_scalar(windvelocity, get_pcvar_float(windforce), windvelocity_calc)
else
xs_vec_mul_scalar(windvelocity, get_pcvar_float(windforce) * 0.005 + (float(num_push) /200.0), windvelocity_calc)
xs_vec_add(velocity, windvelocity_calc, velocity)
}
if(num_push >= 10 && get_gametime() > time_push)
{
time_push = get_gametime() + 20.0
set_pev(iEnt, pev_fuser2, time_push)
num_push = 0
set_pev(iEnt, pev_iuser1, num_push)
}
if(num_push_small < 10 && get_gametime() > time_push_small)
{
num_push_small += 1
set_pev(iEnt, pev_iuser2, num_push_small)
new Float:windvelocity_calc[3]
xs_vec_set(velocitynoise, random_float(-100.0, 100.0),random_float(-100.0, 100.0),random_float(-100.0, 100.0))
if(pev(iEnt, pev_iuser3) != 1) // IF ITS OUTDOOR
xs_vec_mul_scalar(windvelocity, get_pcvar_float(windforce) * 0.005 + (float(num_push_small) /200.0), windvelocity_calc)
xs_vec_mul_scalar(velocitynoise, 0.01 , velocitynoise)
xs_vec_add(velocity, windvelocity_calc, velocity)
}
if(num_push_small >= 10 && get_gametime() > time_push_small)
{
time_push_small = get_gametime() + random_float(0.1, 1.0)
set_pev(iEnt, pev_fuser3, time_push_small)
num_push_small = 0
set_pev(iEnt, pev_iuser2, num_push_small)
}
xs_vec_mul_scalar(velocity, 0.99, velocity)
renderamt -= 0.1 + 0.0001 * floatabs(xs_vec_len(velocity))
if(renderamt < 0.3)
{
fm_remove_entity(iEnt)
return FMRES_IGNORED
}
scale += 0.001 + 0.0001 * floatabs(xs_vec_len(velocity))
//new Float:angles[3]
//xs_vec_set(angles, random_float(-100.0, 100.0),random_float(-100.0, 100.0),random_float(-100.0, 100.0))
//set_pev(iEnt, pev_angles, angles)
xs_vec_mul_scalar(SMOKE_SIZE_MAX, scale, size_max)
xs_vec_mul_scalar(SMOKE_SIZE_MIN, scale, size_min)
new Float:scan_point[3], direction
new Float:speed = (velocity[0] + velocity[1] + velocity[2])
new Float:angle[3], found
check_direction(iEnt, 1, DIRECTION_NONE, velocity, origin, angle, scan_point)
if(fm_point_contents(scan_point) == CONTENTS_SOLID)
{
//angle[0] = 35.0
check_direction(iEnt, 1, DIRECTION_UP, velocity, origin, angle, scan_point)
//client_print(pev(iEnt, pev_owner), print_chat, "DEBUG: SMOKE CHECKING DIRECTION UP sp = %f %f %f", scan_point[0], scan_point[1], scan_point[2])
if(fm_point_contents(scan_point) == CONTENTS_SOLID)
{
//angle[0] = 70.0
check_direction(iEnt, 1, DIRECTION_UP, velocity, origin, angle, scan_point)
//client_print(pev(iEnt, pev_owner), print_chat, "DEBUG: SMOKE CHECKING DIRECTION UP sp = %f %f %f", scan_point[0], scan_point[1], scan_point[2])
if(fm_point_contents(scan_point) == CONTENTS_SOLID)
{
//angle[0] = -35.0
check_direction(iEnt, 1, DIRECTION_DOWN, velocity, origin, angle, scan_point)
//client_print(pev(iEnt, pev_owner), print_chat, "DEBUG: SMOKE CHECKING DIRECTION DOWN sp = %f %f %f", scan_point[0], scan_point[1], scan_point[2])
if(fm_point_contents(scan_point) == CONTENTS_SOLID)
{
//angle[0] = -70.0
check_direction(iEnt, 1, DIRECTION_DOWN, velocity, origin, angle, scan_point)
//client_print(pev(iEnt, pev_owner), print_chat, "DEBUG: SMOKE CHECKING DIRECTION DOWN sp = %f %f %f", scan_point[0], scan_point[1], scan_point[2])
if(fm_point_contents(scan_point) == CONTENTS_SOLID)
{
}
else if(!found)
{
check_direction(iEnt, 0, DIRECTION_DOWN, velocity, origin, angle, scan_point)
found = 1
//xs_vec_sub(scan_point, origin,scan_point)
xs_vec_mul_scalar(scan_point, speed/50.0, velocity)
}
}
else if(!found)
{
check_direction(iEnt, 0, DIRECTION_DOWN, velocity, origin, angle, scan_point)
found = 1
//xs_vec_sub(scan_point, origin,scan_point)
xs_vec_mul_scalar(scan_point, speed/50.0, velocity)
}
}
else if(!found)
{
check_direction(iEnt, 0, DIRECTION_UP, velocity, origin, angle, scan_point)
found = 1
//xs_vec_sub(scan_point, origin, scan_point)
xs_vec_mul_scalar(scan_point, speed/50.0, velocity)
}
}
else if(!found)
{
check_direction(iEnt, 0, DIRECTION_UP, velocity, origin, angle, scan_point)
found = 1
//xs_vec_mul_scalar(scan_point, speed * 0.04, velocity)
//xs_vec_sub(scan_point, origin,scan_point)
xs_vec_mul_scalar(scan_point, speed/50.0, velocity)
}
//client_print(pev(iEnt, pev_owner), print_chat, "DEBUG: smoke speed %f, direction %f %f %f", speed, scan_point[0], scan_point[1], scan_point[2])
}
set_pev(iEnt, pev_fuser4, velocity)
xs_vec_mul_scalar(velocity, 0.75, velocity)
xs_vec_mul_scalar(velocity_old, 0.25, velocity_old)
xs_vec_add(velocity, velocity_old, velocity)
set_pev(iEnt, pev_velocity, velocity)
set_pev(iEnt, pev_scale, scale)
set_pev(iEnt, pev_renderamt, renderamt)
engfunc(EngFunc_SetSize, iEnt, SMOKE_SIZE_MIN , SMOKE_SIZE_MAX)
set_pev(iEnt, pev_nextthink, get_gametime()+0.1)
//debug_gunshot(iEnt)
//client_print(pev(iEnt, pev_owner), print_chat, "DEBUG: smoke size_max = %f %f %f",size_max[0],size_max[1],size_max[2])
//client_print(pev(iEnt, pev_owner), print_chat, "DEBUG: SMOKE np = %i, tp = %f, nps = %i, tps = %f, v=|%i|%i|%i|, vn=|%i|%i|%i|, out=%i", num_push, time_push, num_push_small, time_push_small, floatround(velocity[0]), floatround(velocity[1]), floatround(velocity[2]), floatround(velocitynoise[0]), floatround(velocitynoise[1]), floatround(velocitynoise[2]), pev(iEnt, pev_iuser3))
}
return FMRES_IGNORED
}
stock check_direction(iEnt, addorigin, direction, Float:velocity[3], Float:origin[3], Float:angle[3], Float:scan_point[3])
{
new Float:scan_point_dir[3], Float:oldangle[3], Float:scan_point2[3]
xs_vec_copy(velocity, scan_point_dir)
vector_to_angle(scan_point_dir, angle)
switch(direction)
{
case DIRECTION_UP:
{
angle[0] += 15.0
if(angle[0] > 360.0)
angle[0] -=360.0
}
case DIRECTION_DOWN:
{
angle[0] -= 15.0
if(angle[0] < 0.0)
angle[0] +=360.0
}
case DIRECTION_LEFT:
{
angle[1] += 15.0
if(angle[1] > 360.0)
angle[1] -=360.0
}
case DIRECTION_RIGHT:
{
angle[1] -= 15.0
if(angle[1] < 0.0)
angle[1] +=360.0
}
}
//xs_vec_add(oldangle, angle, angle)
//if(direction == DIRECTION_DOWN || direction == DIRECTION_UP)
angle[0] *= -1.0
///angle[1] = floatabs(angle[1]) - (-angle[1] * 2.0)
//angle[2] = floatabs(angle[2])
angle_vector(angle, ANGLEVECTOR_FORWARD, scan_point)
//scan_point[0] = floatabs(scan_point[0]) - (-scan_point[0] * 2.0)
xs_vec_mul_scalar(scan_point, 50.0, scan_point)
//if(!inv)
//client_print(pev(iEnt, pev_owner), print_chat, "DEBUG: SMOKE o=%f %f %f oa=%f %f %f a=%f %f %f", origin[0], origin[1], origin[2], angle[0], angle[1], angle[2], oldangle[0], oldangle[1], oldangle[2])
if(addorigin)
{
xs_vec_add(origin, scan_point,scan_point)
//debug_gunshot_origin(scan_point)
// client_print(pev(iEnt, pev_owner), print_chat, "DEBUG: SMOKE o=%f %f %f a=%f %f %f sp=%f %f %f", origin[0], origin[1], origin[2], angle[0], angle[1], angle[2], scan_point[0],scan_point[1], scan_point[2])
}
else
//debug_gunshot(iEnt)
return 1
}
public debug_gunshot(iEnt)
{
new Float:origins[3]
pev(iEnt, pev_origin, origins)
message_begin(MSG_BROADCAST ,SVC_TEMPENTITY)
write_byte(TE_GUNSHOT)
write_coord(floatround(origins[0])) // start position
write_coord(floatround(origins[1]))
write_coord(floatround(origins[2]))
message_end()
}
public debug_gunshot_origin(Float:origin[3])
{
message_begin(MSG_BROADCAST ,SVC_TEMPENTITY)
write_byte(TE_GUNSHOT)
write_coord(floatround(origin[0])) // start position
write_coord(floatround(origin[1]))
write_coord(floatround(origin[2]))
message_end()
}
public wind_change()
{
xs_vec_set(windvelocity, random_float(-4.0,4.0), random_float(-4.0,4.0), 0.1)
set_task(random_float(10.0,20.0), "wind_change", WIND_TASKID)
}