This website is under active development! You're very early! Please report any bugs directly to Durf

skull.lua Part LUA Script File

Asset Details

Name = skull.lua
Description = Part LUA Script File for d71aa6e8-5dd5-4a51-8090-a904273b4f66 (skull.lua)
Tags = script, scripted, lua
Author = 76561198014346778
RequiredAssets =
FileContents =
skull = class( nil )
skull.maxParentCount = 1
skull.maxChildCount = 0
skull.connectionInput = sm.interactable.connectionType.logic + sm.interactable.connectionType.power
skull.connectionOutput = sm.interactable.connectionType.none
skull.colorNormal = sm.color.new( 0x009999ff  )
skull.colorHighlight = sm.color.new( 0x11B2B2ff  )
skull.poseWeightCount = 1
skull.fireDelay = 120 --ticks
skull.livetime = 30 -- sec
skull.dodgeterrain = true

function skull.server_onCreate( self ) 
	self:server_init()
end

function skull.server_init( self ) 
	self.fireDelayProgress = 0
	self.canFire = true
	self.parentActive = false
end

function skull.server_onRefresh( self )
	self:server_init()
end

function skull.server_onFixedUpdate( self, timeStep )
	if not self.canFire then
		self.fireDelayProgress = self.fireDelayProgress + 1
		if self.fireDelayProgress >= self.fireDelay then
			self.fireDelayProgress = 0
			self.canFire = true	
		end
	end
	self:server_tryFire()
	local parent = self.interactable:getSingleParent()
	if parent then
		self.parentActive = parent:isActive()
	end
	
	for k, bullet in pairs(self.bullets) do
		if bullet then
			if bullet.hit then
				--position, level, destructionRadius, impulseRadius, magnitude
				sm.physics.explode( bullet.hit, 6, 0.5, 1, 10, "PropaneTank - ExplosionSmall")
			end
		end
	end
end

function skull.server_tryFire( self )
	local parent = self.interactable:getSingleParent()
	if parent then
		if parent:isActive()  and self.canFire then
			self.canFire = false
			local dir = sm.noise.gunSpread(self.shape.right, 45 ) * 5 * math.random(7000,10000)/10000
			local extra = dir*dir:dot(self.shape.velocity)*0.001
			if extra:dot(dir) > 0 then dir = dir+ extra end
			
			self.network:sendToClients( "client_onShoot", {dir = dir, player = 0, power = parent.power})
		end
	end
end

-- Client

function skull.client_onCreate( self )
	self.boltValue = 0.0
	self.bullets = {}
end

function skull.client_onFixedUpdate( self, dt )
	--print(self.bullets)
	for k, bullet in pairs(self.bullets) do
		if bullet then
			if bullet.alive + dt > skull.livetime or bullet.hit then --lives for 2 sec, clean up after
				bullet.effect:setPosition(sm.vec3.new(0,0,1000000))
				bullet.effect:stop()
				--bullet.effect2:setPosition(sm.vec3.new(0,0,1000000))
				--bullet.effect2:stop()
				bullet.alive = skull.livetime + dt
			end
			
			local distance = math.huge
			local pos = bullet.pos + bullet.direction
			for k, v in pairs(sm.player.getAllPlayers()) do
				local targetdir = (bullet.pos - v.character.worldPosition):normalize()
				local yaw = (180 + math.atan2(targetdir.y,targetdir.x)/math.pi * 180) - (180 + math.atan2(bullet.direction.y,bullet.direction.x)/math.pi * 180)
				yaw = (yaw>180) and yaw-360 or (yaw<-180 and yaw+360 or yaw)
				
				local dist = (bullet.pos - v.character.worldPosition):length() * math.max(0, (175-math.abs(yaw))^2) --10° dead spot behind it
				if dist < distance then
					pos = v.character.worldPosition --+ sm.vec3.new(0,0,0.6)
					distance = dist
				end
			end
			
			if bullet.alive > 2 then
				bullet.direction = (bullet.direction*0.7 + (pos - bullet.pos):normalize()*(0.125*bullet.power + bullet.direction:length()*0.3) )*0.995
			else
				bullet.direction = bullet.direction * 0.988
			end
			
			local hit, result =  sm.physics.raycast( bullet.pos, bullet.pos + bullet.direction * dt*1.1 )
			if hit and self.dodgeterrain then
				if result.type == "terrainSurface" then
					bullet.direction = bullet.direction*0.1 + sm.vec3.new(0,0,50)
				elseif result.type == "terrainAsset" then
					bullet.direction = bullet.direction*0.1 + sm.vec3.new(0,0,50) + bullet.direction:cross(sm.vec3.new(0,0,1))
				end
			end
			
			local hit, result =  sm.physics.raycast( bullet.pos, bullet.pos + bullet.direction * dt*1.1 )
			if hit then
				bullet.hit = result.pointWorld
			end
			
			--sm.particle.createParticle( "p_spudgun_basic_impact_potato", bullet.pos, rot, sm.color.new(0.2,0.2,0.2,1) )
			--sm.particle.createParticle( "paint_smoke", bullet.pos, rot, sm.color.new(0.2,0.2,0.2,1) )
			
			bullet.pos = bullet.pos + bullet.direction* dt
			bullet.effect:setPosition(bullet.pos)
			--bullet.effect2:setPosition(bullet.pos)
			bullet.effect:setVelocity(bullet.direction)
			--bullet.effect2:setVelocity(bullet.direction)
			local rot = sm.vec3.getRotation( sm.vec3.new( 0, 1, 0 ), bullet.direction )
			--if bullet.tick%2 == 1 then
				bullet.effect:setRotation( rot )
			--else
			--	bullet.effect2:setRotation( rot )
			--end
			bullet.alive = bullet.alive + dt
			bullet.tick = bullet.tick + 1
		end
		if bullet.alive - dt > skull.livetime then
			self.bullets[k] = nil
		end
	end
end

function skull.client_onShoot( self, data )
	self.boltValue = 1.0
	local rot = sm.vec3.getRotation( sm.vec3.new( 0, 1, 0 ), data.dir )
	--sm.particle.createParticle( "fire", self.shape.worldPosition-self.shape.right*0.3 + self.shape.at*0.1 , rot, sm.color.new(0,0,0) )
	
	local position = self.shape.worldPosition -- self.shape.up*0.7
	--local bullet = {effect = sm.effect.createEffect("fireskull"),effect2 = sm.effect.createEffect("fireskull"), pos = position, direction = data.dir, alive = 0, power = data.power, tick = 0}
	local bullet = {effect = sm.effect.createEffect("fireskull"), pos = position, direction = data.dir, alive = 0, power = data.power, tick = 0}
	bullet.effect:setPosition( position )
	bullet.effect:setVelocity( bullet.direction)
	bullet.effect:setRotation( rot )
	bullet.effect:start()
	--bullet.effect2:setPosition( position )
	--bullet.effect2:setVelocity( bullet.direction)
	--bullet.effect2:setRotation( rot )
	--bullet.effect2:start()
	self.bullets[#self.bullets+1] = bullet
end

function skull.client_onUpdate( self, deltaTime )

	if self.boltValue > 0.0 then
		self.boltValue = self.boltValue - deltaTime * 10
	end
	if self.boltValue ~= self.prevBoltValue then
		self.interactable:setPoseWeight( 0, self.boltValue ) --Clamping inside
		self.prevBoltValue = self.boltValue
	end
end


function getLocal(shape, vec)
    return sm.vec3.new(sm.shape.getRight(shape):dot(vec), sm.shape.getAt(shape):dot(vec), sm.shape.getUp(shape):dot(vec))
end

Advertisement