-- LUA Script - precede every function and global member with lowercase name of script + '_main' local U = require "scriptbank\\utillib" local Q = require "scriptbank\\quatlib" local rad = math.rad local random = math.random local hurtAmount = 5 local spikeVars = { baseAng = -90, framestart = 1, frameend = 80, spikelen = 60 } local swordVars = { baseAng = -90, framestart = 1, frameend = 78, spikelen = 45 } local spikes ={} function spikes_init_name( e, name ) Include( "utillib.lua" ) Include( "quatlib.lua" ) spikes[ e ] = { name = name, state = 'init', npcTimer = 0 } end local function gotPlayer( x, y, z, dist ) ppx, ppy, ppz = GetCameraPositionX(0) , GetCameraPositionY(0) , GetCameraPositionZ(0) return U.CloserThan( ppx, ppy, ppz, x, y, z, dist ) or U.CloserThan( ppx, ppy - 20, ppz, x, y, z, dist ) end local function HurtOthers( e, s, pos, dist ) for _, v in pairs( s.npcList ) do if spikes[ v ] == nil then local Ent = g_Entity[ v ] if U.CloserThan( Ent.x, Ent.y + 10, Ent.z, pos.x, pos.y, pos.z, dist ) or U.CloserThan( Ent.x, Ent.y + 40, Ent.z, pos.x, pos.y, pos.z, dist ) then SetEntityHealth( v, 0 ) end end end end local minFrame = math.huge local maxFrame = 0 local soundBitRate = 11025 function spikes_main( e ) local spike = spikes[ e ] if spike == nil then return end local frame = GetAnimationFrame( e ) if spike.state == 'ready' then if g_Time > spike.npcTimer then spike.npcList = U.ClosestEntities( 200, 10, spike.pos.x, spike.pos.z ) spike.npcTimer = g_Time + random( 400, 800 ) end end if spike.name == 'rotatespikes' then if spike.state == 'init' then local speed = 0.5 + random() SetAnimationSpeed( e, speed ) spike.obj = g_Entity[ e ].obj local x, y, z, xA, yA, zA = GetObjectPosAng( spike.obj ) spike.pos = { x = x, y = y, z = z } local baseRotQ = Q.FromEuler( 0, rad( spikeVars.baseAng ), 0 ) spike.quat = Q.Mul( Q.FromEuler( rad( xA ), rad( yA ), rad( zA ) ), baseRotQ ) spike.state = 'ready' LoopSound( e, 1 ) SetSound( e, 1 ) SetSoundSpeed( soundBitRate * speed ) spike.soundPlaying = true elseif spike.state == 'ready' and ( U.PlayerCloserThanPos( spike.pos.x, spike.pos.y, spike.pos.z, 200 ) or #spike.npcList > 1 ) then local angle = ( frame - spikeVars.framestart ) * ( -360 / ( spikeVars.frameend - spikeVars.framestart ) ) local quat = Q.Mul( spike.quat, Q.FromEuler( 0, rad( angle ), 0 ) ) local xa, ya, za = Q.ToEuler( quat ) local xo, yo, zo = U.Rotate3D( 0, 20, spikeVars.spikelen, xa, ya, za ) local x, y, z = spike.pos.x, spike.pos.y, spike.pos.z if gotPlayer( x + xo, y + yo, z + zo, 30 ) then HurtPlayer( e, hurtAmount ) end HurtOthers( e, spike, { x = x + xo, y = y + yo, z = z + zo }, 40 ) xo, yo, zo = U.Rotate3D( 0, 60, spikeVars.spikelen, xa, ya, za ) if gotPlayer( x + xo, y + yo, z + zo, 30 ) then HurtPlayer( e, hurtAmount ) end HurtOthers( e, spike, { x = x + xo, y = y + yo, z = z + zo }, 40 ) end elseif spike.name == 'rotatingswordtrap' then if spike.state == 'init' then spike.obj = g_Entity[ e ].obj local speed = 0.5 + random() SetAnimationSpeed( e, speed ) local x, y, z, xA, yA, zA = GetObjectPosAng( spike.obj ) spike.pos = { x = x, y = y, z = z } local baseRotQ = Q.FromEuler( 0, rad( swordVars.baseAng ), 0 ) spike.quat = Q.Mul( Q.FromEuler( rad( xA ), rad( yA ), rad( zA ) ), baseRotQ ) spike.state = 'ready' LoopSound( e, 1 ) SetSound( e, 1 ) SetSoundSpeed( soundBitRate * speed ) spike.soundPlaying = true elseif spike.state == 'ready' and ( U.PlayerCloserThanPos( spike.pos.x, spike.pos.y, spike.pos.z, 200 ) or #spike.npcList > 1 ) then local angle = ( frame - swordVars.framestart ) * ( -360 / ( swordVars.frameend - swordVars.framestart ) ) local rotquat1 = Q.FromEuler( 0, rad( angle ), 0 ) local quat = Q.Mul( spike.quat, rotquat1 ) local xa, ya, za = Q.ToEuler( quat ) local xo, yo, zo = U.Rotate3D( 0, 55, swordVars.spikelen, xa, ya, za ) local x, y, z = spike.pos.x, spike.pos.y, spike.pos.z if gotPlayer( x + xo, y + yo, z + zo, 30 ) then HurtPlayer( e, hurtAmount ) end HurtOthers( e, spike, { x = x + xo, y = y + yo, z = z + zo }, 40 ) local rotquat2 = Q.FromEuler( 0, rad( angle -180 ), 0 ) quat = Q.Mul( spike.quat, rotquat2 ) xa, ya, za = Q.ToEuler( quat ) xo, yo, zo = U.Rotate3D( 0, 20, swordVars.spikelen, xa, ya, za ) if gotPlayer( x + xo, y + yo, z + zo, 30 ) then HurtPlayer( e, hurtAmount ) end HurtOthers( e, spike, { x = x + xo, y = y + yo, z = z + zo }, 40 ) end elseif spike.name == 'rotatespikes2_ani' then if spike.state == 'init' then local speed = 0.5 + random() / 2 SetAnimationSpeed( e, speed ) spike.obj = g_Entity[ e ].obj local x, y, z, xA, yA, zA = GetObjectPosAng( spike.obj ) xA, yA, zA = rad( xA ), rad( yA ), rad( zA ) spike.quat = Q.FromEuler( xA, yA, zA ) local xo, yo, zo = U.Rotate3D( 0, 100, 0, xA, yA, zA ) spike.pos = { x = x + xo, y = y + yo, z = z + zo } CollisionOff( e ) spike.state = 'ready' LoopSound( e, 1 ) SetSound( e, 1 ) SetSoundSpeed( soundBitRate * speed ) spike.soundPlaying = true elseif spike.state == 'ready' and ( U.PlayerCloserThanPos( spike.pos.x, spike.pos.y, spike.pos.z, 200 ) or #spike.npcList > 1 )then local angle = 0 if frame < 50 then angle = ( 50 - frame ) * 180 / 50 else angle = ( frame - 50 ) * 180 / 50 end -- PromptLocal( e, frame .. ", " .. angle ) local quat = Q.Mul( spike.quat, Q.FromEuler( rad( angle ), 0, 0 ) ) local xa, ya, za = Q.ToEuler( quat ) local xo, yo, zo = U.Rotate3D( -30, 0, 80, xa, ya, za ) local x, y, z = spike.pos.x, spike.pos.y, spike.pos.z if gotPlayer( x + xo, y + yo, z + zo, 30 ) then HurtPlayer( e, hurtAmount * 2 ) end HurtOthers( e, spike, { x = x + xo, y = y + yo, z = z + zo }, 40 ) xo, yo, zo = U.Rotate3D( 30, 0 ,80, xa, ya, za ) if gotPlayer( x + xo, y + yo, z + zo, 30 ) then HurtPlayer( e, hurtAmount * 2 ) end HurtOthers( e, spike, { x = x + xo, y = y + yo, z = z + zo }, 40 ) end elseif spike.name == 'spikefloor' then if spike.state == 'init' then SetAnimationSpeed( e, 1.0 ) spike.obj = g_Entity[ e ].obj local x, y, z = GetObjectPosAng( spike.obj ) spike.pos = { x = x, y = y, z = z } spike.rate = 800 + random() * 1600 spike.timer = g_Time + spike.rate spike.state = 'ready' StopAnimation( e ) SetAnimationFrame( e, 25 ) CollisionOff( e ) elseif spike.state == 'ready' then if g_Time > spike.timer then SetAnimationFrames( 25, 46 ) PlayAnimation( e ) spike.state = 'strike' PlaySound( e, 1 ) spike.soundPlaying = true end elseif spike.state == 'strike' then if frame == 46 then spike.timer = g_Time + spike.rate SetAnimationFrame( e, 25 ) spike.state = 'ready' spike.soundPlaying = false elseif frame > 27 and frame < 44 then if U.PlayerCloserThan( e, 80 ) then HurtPlayer( e, hurtAmount ) end HurtOthers( e, spike, spike.pos, 80 ) end end end if spike.soundPlaying then SetSound( e, 1 ) SetSoundVolume( 99 - ( GetPlayerDistance( e ) / 30 ) ) end end