Quote: "@ smallg; brilliant!
are you trying to make another "Teardown"?! lol J/K
destructible objects are all the rage now- I wish.
If Lee can get spawn object @ MAX script level, maybe something
can be finagled together?"
that would require a lot of optimization in the engine for that many draw calls to match the likes of teardown but some lesser destruction is possible - i'd be happy to just get a spawn object for normal reasons (dropping loot etc)
@amen, thanks, fixed my script now, i added in the different material detection which is cool
p.s. where did you find the GetBulletHit() function? it's not listed anywhere that i can see
i did try to improve the ray accuracy by using the bullet location values returned (i.e. start at player location and ray to the GetBulletHit() values but for some reason it didn't work correctly.. maybe next time i'll figure it out
edit: quick fix to remove bullet holes from being placed on characters
p.s. as amen pointed out in his thread this won't work correctly with animated or movable objects as the particles don't move with the object - perhaps something to fix in the future
-- DESCRIPTION: BULLET HOLE SETTINGS:
-- DESCRIPTION: [MAXBULLETHOLES=100], [FOLLOWPLAYER!=0] (1 = yes, 0 = no - entity placement)
-- DESCRIPTION: [SANIMSPD=1], [SSTARTRANDANGLE=0], [SFREQUENCY=0], [SMINLIFE=200], [SMAXLIFE=200]
-- DESCRIPTION: [SOFFX1=0], [SOFFY1=0], [SOFFZ1=0], [SOFFX2=0], [SOFFY2=0], [SOFFZ2=0],
-- DESCRIPTION: [SSPDX1=0], [SSPDY1=0.5], [SSPDZ1=0], [SSPDX2=0], [SSPDY2=1.2], [SSPDZ2=0],
-- DESCRIPTION: [SROTATEX=0], [SROTATEZ=0], [SSCALESTARTMIN=3], [SSCALESTARTMAX=4], [SSCALEENDMIN=30], [SSCALEENDMAX=60]
-- DESCRIPTION: [SALPHASTARTMIN=200], [SALPHASTARTMAX=255], [SALPHAENDMIN=80], [SALPHAENDMAX=100]
-- DESCRIPTION: [FRAMES=1], [EXPLOSIONLIMB=0], [GRAVITY=5], [PARTICLESPERFRAME=10]
U = U or require "scriptbank\\utillib"
--local bulletholeimg = bulletholeimg or ParticlesLoadImage("scriptbank\\smallg\\images\\bulletholes\\bullethole1.dds")
local metalFile = metalFile or ParticlesLoadImage( "effectbank\\particles\\metalbh.dds", 10 )
local woodFile = woodFile or ParticlesLoadImage( "effectbank\\particles\\woodbh.dds", 11 )
local stoneFile = stoneFile or ParticlesLoadImage( "effectbank\\particles\\stonebh2.dds", 12 )
local emitterList, bullethole = {},{}
local oldammo, bulletholescreated = 0,0
local firedposx, firedposy, firedposz, firedangx, firedangy, firedangz, firedmaterial
local makebulletholes, shotFired = 0, false
g_bulletholes = {}
function bulletholes_properties(e, maxbulletholes, followplayer, sanimspd, sstartrandangle, sfrequency, sminlife, smaxlife, soffx1, soffy1, soffz1, soffx2, soffy2, soffz2,
sspdx1, sspdy1, sspdz1, sspdx2, sspdy2, sspdz2, srotatex, srotatez, sscalestartmin, sscalestartmax, sscaleendmin, sscaleendmax,
salphastartmin, salphastartmax, salphaendmin, salphaendmax, frames, explosionlimb, gravity, particlesperframe)
g_bulletholes[e]['maxbulletholes'] = maxbulletholes
g_bulletholes[e]['followplayer'] = followplayer
g_bulletholes[e]['sanimspd'] = sanimspd
g_bulletholes[e]['sstartrandangle'] = sstartrandangle
g_bulletholes[e]['sfrequency'] = sfrequency
g_bulletholes[e]['sminlife'] = sminlife
g_bulletholes[e]['smaxlife'] = smaxlife
g_bulletholes[e]['soffx1'] = soffx1
g_bulletholes[e]['soffy1'] = soffy1
g_bulletholes[e]['soffz1'] = soffz1
g_bulletholes[e]['soffx2'] = soffx2
g_bulletholes[e]['soffy2'] = soffy2
g_bulletholes[e]['soffz2'] = soffz2
g_bulletholes[e]['sspdx1'] = sspdx1
g_bulletholes[e]['sspdy1'] = sspdy1
g_bulletholes[e]['sspdz1'] = sspdz1
g_bulletholes[e]['sspdx2'] = sspdx2
g_bulletholes[e]['sspdy2'] = sspdy2
g_bulletholes[e]['sspdz2'] = sspdz2
g_bulletholes[e]['srotatex'] = srotatex
g_bulletholes[e]['srotatez'] = srotatez
g_bulletholes[e]['sscalestartmin'] = sscalestartmin
g_bulletholes[e]['sscalestartmax'] = sscalestartmax
g_bulletholes[e]['sscaleendmin'] = sscaleendmin
g_bulletholes[e]['sscaleendmax'] = sscaleendmax
g_bulletholes[e]['salphastartmin'] = salphastartmin
g_bulletholes[e]['salphastartmax'] = salphastartmax
g_bulletholes[e]['salphaendmin'] = salphaendmin
g_bulletholes[e]['salphaendmax'] = salphaendmax
g_bulletholes[e]['frames'] = frames
g_bulletholes[e]['explosionlimb'] = explosionlimb
g_bulletholes[e]['gravity'] = gravity
g_bulletholes[e]['particlesperframe'] = particlesperframe
if g_bulletholes[e]['followplayer'] == 1 then
g_bulletholes[e]['followplayer'] = -1
else
g_bulletholes[e]['followplayer'] = e
end
end
function bulletholes_init(e)
emitterList[e] = {}
g_bulletholes[e] = {}
bullethole[e] = {}
g_bulletholes[e]['maxbulletholes'] = 50000
g_bulletholes[e]['followplayer'] = -1
g_bulletholes[e]['sanimspd'] = 0
g_bulletholes[e]['sstartrandangle'] = 0
g_bulletholes[e]['sfrequency'] = 0
g_bulletholes[e]['sminlife'] = 3500000
g_bulletholes[e]['smaxlife'] = 4500000
g_bulletholes[e]['soffx1'] = 0
g_bulletholes[e]['soffy1'] = 0
g_bulletholes[e]['soffz1'] = 0
g_bulletholes[e]['soffx2'] = 0
g_bulletholes[e]['soffy2'] = 0
g_bulletholes[e]['soffz2'] = 0
g_bulletholes[e]['sspdx1'] = 0
g_bulletholes[e]['sspdy1'] = 0
g_bulletholes[e]['sspdz1'] = 0
g_bulletholes[e]['sspdx2'] = 0
g_bulletholes[e]['sspdy2'] = 0
g_bulletholes[e]['sspdz2'] = 0
g_bulletholes[e]['srotatex'] = 0
g_bulletholes[e]['srotatez'] = 0
g_bulletholes[e]['sscalestartmin'] = 2
g_bulletholes[e]['sscalestartmax'] = 2
g_bulletholes[e]['sscaleendmin'] = 1
g_bulletholes[e]['sscaleendmax'] = 1
g_bulletholes[e]['salphastartmin'] = 55
g_bulletholes[e]['salphastartmax'] = 55
g_bulletholes[e]['salphaendmin'] = 155
g_bulletholes[e]['salphaendmax'] = 155
g_bulletholes[e]['frames'] = 16
g_bulletholes[e]['explosionlimb'] = 0
g_bulletholes[e]['gravity'] = 0
g_bulletholes[e]['particlesperframe'] = 1
CollisionOff(e)
Hide(e)
--Scale(e,0.1)
end
function bulletholes_main(e)
local function Rotate3D(e,x,y,z)
CollisionOff(e)
SetCameraOverride(1)
local px,py,pz
local pax,pay,paz
px,py,pz = GetCameraPositionX(0),GetCameraPositionY(0),GetCameraPositionZ(0)
pax,pay,paz = GetCameraAngleX(0),GetCameraAngleY(0),GetCameraAngleZ(0)
PositionCamera(0,g_Entity[e]['x'],g_Entity[e]['y'],g_Entity[e]['z'])
PointCamera(0,x,y,z)
local rx,ry,rz = 0,0,0
rx,ry,rz = GetCameraAngleX(0),GetCameraAngleY(0),GetCameraAngleZ(0)
SetRotation(e,rx,ry,rz)
SetCameraAngle(0,pax,pay,paz)
SetCameraPosition(0,px,py,pz)
SetCameraOverride(0)
end
if g_PlayerGunFired == 1 then
local bx, by, bz, m, t = GetBulletHit()
if bx ~= nil then
if not shotFired then
shotFired = true
firedmaterial = m
if m > 9 and m < 13 then
local gunname = string.lower(g_PlayerGunName)
--Prompt(firedmaterial)
if string.find(gunname, "shotgun") ~= nil then
makebulletholes = 5
else
makebulletholes = 1
end
end
--PromptDuration(bx.." , "..by.." , "..bz, 2000)
end
else
shotFired = false
firedposx, firedposy, firedposz = g_PlayerPosX, g_PlayerPosY, g_PlayerPosZ
firedangx, firedangy, firedangz = g_PlayerAngX, g_PlayerAngY, g_PlayerAngZ
end
else
firedposx, firedposy, firedposz = g_PlayerPosX, g_PlayerPosY, g_PlayerPosZ
firedangx, firedangy, firedangz = g_PlayerAngX, g_PlayerAngY, g_PlayerAngZ
end
--Prompt(bulletholescreated)
if makebulletholes > 0 then
local x1, y1, z1, x2, y2, z2
local ax1, ay1, az1, ax2, ay2, az2
local ox, oy, oz , ray, oax, oay, oaz
local rad = math.rad
if GetGamePlayerStatePlayerDucking() == 0 then
x1,y1,z1 = firedposx, firedposy+28, firedposz
else
x1,y1,z1 = firedposx, firedposy+10, firedposz
end
SetPosition(e, x1, y1 + 5000, z1)
ax1, ay1, az1 = firedangx, firedangy, firedangz
if makebulletholes == 1 then
oax = 0
oay = 0
elseif makebulletholes == 2 then
oax = -3
oay = 0
elseif makebulletholes == 3 then
oax = 3
oay = 0
elseif makebulletholes == 4 then
oax = 0
oay = -3
elseif makebulletholes == 5 then
oax = 0
oay = 3
end
oaz = 0
ax1 = ax1 + oax
ay1 = ay1 + oay
ox,oy,oz = U.Rotate3D(0, 0, 3000, rad(ax1), rad(ay1), rad(az1))
x2, y2, z2 = x1 + ox, y1 + oy, z1 + oz
ray = IntersectAll(x1, y1, z1, x2, y2, z2, 0)
if ray == nil then ray = 0 end
if ray ~= 0 then
x2 = GetIntersectCollisionX()
y2 = GetIntersectCollisionY()
z2 = GetIntersectCollisionZ()
SetPosition(e, x2, y2, z2)
ResetPosition(e, x2, y2, z2)
local x3, y3, z3, nx, ny, nz
nx = GetIntersectCollisionNX()
ny = GetIntersectCollisionNY()
nz = GetIntersectCollisionNZ()
x3 = (nx * 10000)
y3 = (ny * 10000)
z3 = (nz * 10000)
x3 = x2 + x3
y3 = y2 + y3
z3 = z2 + z3
Rotate3D(e, x3, y3, z3)
x2 = x2 + (nx * 0.2)
y2 = y2 + (ny * 0.2)
z2 = z2 + (nz * 0.2)
SetPosition(e, x2, y2, z2)
--Show(e)
_, _, _, ax2, ay2, az2 = GetEntityPosAng(e)
bulletholescreated = bulletholescreated + 1
bullethole[e][bulletholescreated] = CreateBulletHole(e, e, 0, firedmaterial)
ParticlesSetAngle(bullethole[e][bulletholescreated], ax2, ay2, az2 )
--ParticlesSpawnParticle(bullethole[e][bulletholescreated], x2, y2, z2 )
end
makebulletholes = makebulletholes - 1
end
--TextCenterOnX(50,80,3,bulletholescreated)
end
function CreateBulletHole(e, entity, limbhitid, firedmaterial)
--PromptLocal(e, "made a bullet hole")
local emitter = emitterList[e]
if emitter == nil then
emitterList[e] = { used = false }
else
if not emitter.used then
local bhole = PE_CreateNamedEmitter(e, firedmaterial, g_bulletholes[e]['frames'], entity, limbhitid)
return bhole
end
end
end
function PE_CreateNamedEmitter(e, image, frames, entity, limb )
if e == nil then return end
local epos = {}
local escl = {}
local espd = {}
local erot = {}
local elife = {}
local ealpha = {}
local easpd = 0
local esrot = 0
local efreq = 0
local efollowp = entity
epos[1] = g_bulletholes[e]['soffx1']
epos[2] = g_bulletholes[e]['soffy1']
epos[3] = g_bulletholes[e]['soffz1']
epos[4] = g_bulletholes[e]['soffx2']
epos[5] = g_bulletholes[e]['soffy2']
epos[6] = g_bulletholes[e]['soffz2']
escl[1] = g_bulletholes[e]['sscalestartmin']
escl[2] = g_bulletholes[e]['sscalestartmax']
escl[3] = g_bulletholes[e]['sscaleendmin']
escl[4] = g_bulletholes[e]['sscaleendmin']
espd[1] = g_bulletholes[e]['sspdx1']
espd[2] = g_bulletholes[e]['sspdy1']
espd[3] = g_bulletholes[e]['sspdz1']
espd[4] = g_bulletholes[e]['sspdx2']
espd[5] = g_bulletholes[e]['sspdy2']
espd[6] = g_bulletholes[e]['sspdz2']
erot[1] = g_bulletholes[e]['srotatex']
erot[2] = g_bulletholes[e]['srotatez']
elife[1] = g_bulletholes[e]['sminlife']
elife[2] = g_bulletholes[e]['smaxlife']
ealpha[1] = g_bulletholes[e]['salphastartmin']
ealpha[2] = g_bulletholes[e]['salphastartmax']
ealpha[3] = g_bulletholes[e]['salphaendmin']
ealpha[4] = g_bulletholes[e]['salphaendmax']
easpd = g_bulletholes[e]['sanimspd']
esrot = g_bulletholes[e]['sstartrandangle']
efreq = g_bulletholes[e]['sfrequency']
local emitter = ParticlesGetFreeEmitter()
if emitter == -1 then return end
local tempscale = 1
if image == 10 or image == 11 then
image = stoneFile
elseif image == 12 then
image = metalFile
else
image = woodFile
tempscale = tempscale * 1.5
end
ParticlesAddEmitterEx( emitter, easpd, esrot,
epos[1], epos[2], epos[3], epos[4], epos[5], epos[6],
escl[1] * tempscale, escl[2] * tempscale, escl[3] * tempscale, escl[4] * tempscale,
espd[1], espd[2], espd[3], espd[4], espd[5], espd[6],
erot[1], erot[2], elife[1], elife[2],
ealpha[1], ealpha[2], ealpha[3], ealpha[4],
efreq, efollowp, limb, image, frames )
local perframe = g_bulletholes[e]['particlesperframe']
ParticlesSetLife( emitter, 0, g_bulletholes[e]['smaxlife'], 0, perframe, perframe )
ParticlesSetGravity( emitter, 0, g_bulletholes[e]['gravity'] )
return emitter
end