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

Nuke.lua Part LUA Script File

Asset Details

Name = Nuke.lua
Description = Part LUA Script File for 88ed5ad6-84e3-4450-a104-7f9f1e5b4d02 (Nuke.lua)
Tags = script, scripted, lua
Author = 76561198014346778
RequiredAssets =
FileContents =
-- Nuke.lua --

Nuke = class()
--Nuke.poseWeightCount = 0

Nuke.fireDelay = 20 --ticks (0.5 seconds)
--Nuke.fuseDelay = 0.0625


--[[ Server ]]

-- (Event) Called upon creation on server
function Nuke.server_onCreate( self )
	self:server_init()
end

-- (Event) Called when script is refreshed (in [-dev])
function Nuke.server_onRefresh( self )
	self:server_init()
end

-- Initialize Nuke
function Nuke.server_init( self )
	self.alive = true
	self.counting = false
	self.fireDelayProgress = 0

	-- Default values. Overwritten by data.
	self.destructionLevel = 10
	self.destructionRadius = 100.0
	self.impulseRadius = 200.0
	self.impulseMagnitude = 1000.0

	-- Read data from interactive.json. See "scripted": "data".
	if self.data then
		if self.data.destructionLevel then
			self.destructionLevel = self.data.destructionLevel
		end
		if self.data.destructionRadius then
			self.destructionRadius = self.data.destructionRadius
		end
		if self.data.impulseRadius then
			self.impulseRadius = self.data.impulseRadius
		end
		if self.data.impulseMagnitude then
			self.impulseMagnitude = self.data.impulseMagnitude
		end
	end
end

-- (Event) Called upon game tick. (40 times a second)
function Nuke.server_onFixedUpdate( self, timeStep )
	sm.physics.applyImpulse(self.shape, sm.vec3.new(0,0,1)* self.shape.mass/50, true, sm.shape.getUp(self.shape)*-1)
	if self.counting then
		self.fireDelayProgress = self.fireDelayProgress + 1
		if self.fireDelayProgress >= self.fireDelay then
			self:server_tryExplode()
		end
	end
end

-- Attempt to create an explosion
function Nuke.server_tryExplode( self )
	if self.alive then
		self.alive = false
		self.counting = false
		self.fireDelayProgress = 0

		-- Create explosion
		sm.physics.explode( self.shape.worldPosition, self.destructionLevel, self.destructionRadius, self.impulseRadius, self.impulseMagnitude, self.explosionEffectName, self.shape )
		sm.shape.destroyPart( self.shape )
	end
end

-- (Event) Called upon getting hit by a projectile.
function Nuke.server_onProjectile( self, hitPos, hitTime, hitVelocity, hitType )
	if self.alive then
		if self.counting then
			self.fireDelayProgress = self.fireDelayProgress + self.fireDelay * 0.5
		else
			-- Trigger explosion countdown
			self:server_startCountdown()
			self.network:sendToClients( "client_hitActivation", hitPos )
		end
	end
end

-- (Event) Called upon getting hit by a sledgehammer.
function Nuke.server_onSledgehammer( self, hitPos, player )
	if self.alive then
		if self.counting then
			self.fireDelayProgress = self.fireDelayProgress + self.fireDelay * 0.5
		else
			-- Trigger explosion countdown
			self:server_startCountdown()
			self.network:sendToClients( "client_hitActivation", hitPos )
		end
	end
end

-- (Event) Called upon collision with an explosion nearby
function Nuke.server_onExplosion( self, center, destructionLevel )
	-- Explode within a few ticks
	if self.alive then
		self.fireDelay = 5
		self.counting = true
	end
end

-- (Event) Called upon collision with another object
function Nuke.server_onCollision( self, other, collisionPosition, selfPointVelocity, otherPointVelocity, collisionNormal )

	local collisionDirection = (selfPointVelocity - otherPointVelocity):normalize()
	local diffVelocity = (selfPointVelocity - otherPointVelocity):length()
	local selfPointVelocityLength = selfPointVelocity:length()
	local otherPointVelocityLength = otherPointVelocity:length()
	local scaleFraction = 1.0 - ( self.fireDelayProgress / self.fireDelay )
	local dotFraction = math.abs( collisionDirection:dot( collisionNormal ) )

	--old collision
	local hardTrigger = ( selfPointVelocityLength >= 10 * scaleFraction or otherPointVelocityLength >= 10 * scaleFraction ) and diffVelocity > 10 * scaleFraction
	local lightTrigger = ( ( selfPointVelocityLength >= 4 * scaleFraction and selfPointVelocityLength < 10 * scaleFraction and diffVelocity >= 4 * scaleFraction ) or ( otherPointVelocityLength >= 4 * scaleFraction and otherPointVelocityLength < 10 * scaleFraction and diffVelocity >= 4 * scaleFraction ) )

	-- new collision 
	--local hardTrigger = diffVelocity * dotFraction >= 10 * scaleFraction
	--local lightTrigger = diffVelocity * dotFraction >= 6 * scaleFraction

	if self.alive then
		if hardTrigger  then
			-- Trigger explosion immediately
			self.counting = true
			self.fireDelayProgress = self.fireDelayProgress + self.fireDelay
		elseif lightTrigger then
			-- Trigger explosion countdown
			if not self.counting then
				self:server_startCountdown()
				self.network:sendToClients( "client_hitActivation", collisionPosition )
			else
				self.fireDelayProgress = self.fireDelayProgress + self.fireDelay * ( 1.0 - scaleFraction )
			end
		end
	end
end

-- Start countdown and update clients
function Nuke.server_startCountdown( self )
	self.counting = true
	self.network:sendToClients( "client_startCountdown" )
end


--[[ Client ]]

-- (Event) Called upon creation on client
function Nuke.client_onCreate( self )
	self.client_counting = false
	--self.client_fuseDelayProgress = 0
	self.client_fireDelayProgress = 0
	--self.client_poseScale = 0
	self.client_effect_doOnce = true

	-- Default values. Overwritten by data.
--	self.explosionEffectName = "PropaneTank - ExplosionBig"
--	self.activateEffectName = "PropaneTank - ActivateBig"
	self.explosionEffectName = "Nuke - Explosion"
	self.activateEffectName = "Nuke - Activate"

	-- Read data from interactive.json. See "scripted": "data".
	if self.data then
		if self.data.effectExplosion then
			self.explosionEffectName = self.data.effectExplosion
		end
		if self.data.effectActivate then
			self.activateEffectName = self.data.effectActivate
		end
	end

--	self.singleHitEffect = sm.effect.createEffect( "PropaneTank - SingleActivate", self.interactable )
	self.singleHitEffect = sm.effect.createEffect( "Nuke - SingleActivate", self.interactable )
	self.activateEffect = sm.effect.createEffect( self.activateEffectName, self.interactable )
end

-- (Event) Called upon every frame. (Same as fps)
function Nuke.client_onUpdate( self, dt )
	if self.client_counting then
		--self.interactable:setPoseWeight( 0,(self.client_fuseDelayProgress*1.5) +self.client_poseScale )
		--self.client_fuseDelayProgress = self.client_fuseDelayProgress + dt
		--self.client_poseScale = self.client_poseScale +(0.25*dt)

		--if self.client_fuseDelayProgress >= self.fuseDelay then
		--	self.client_fuseDelayProgress = self.client_fuseDelayProgress - self.fuseDelay
		--end

		self.client_fireDelayProgress = self.client_fireDelayProgress + dt
		self.activateEffect:setParameter( "progress", self.client_fireDelayProgress / ( self.fireDelay * ( 1 / 40 ) ) )
	end
end

-- Called from server upon getting triggered by a hit
function Nuke.client_hitActivation( self, hitPos )
	local localPos = self.shape:transformPoint( hitPos )

	local smokeDirection = ( hitPos - self.shape.worldPosition ):normalize()
	local worldRot = sm.vec3.getRotation( sm.vec3.new( 0, 0, 1 ), smokeDirection )
	local localRot = self.shape:transformRotation( worldRot )

	self.singleHitEffect:start()
	self.singleHitEffect:setOffsetRotation( localRot )
	self.singleHitEffect:setOffsetPosition( localPos )
end

-- Called from server upon countdown start
function Nuke.client_startCountdown( self )
	self.client_counting = true
	self.activateEffect:start()

	local offsetRotation = sm.vec3.getRotation( sm.vec3.new( 0, 0, 1 ), sm.vec3.new( 0, 1, 0 ) ) * sm.vec3.getRotation( sm.vec3.new( 1, 0, 0 ), sm.vec3.new( 0, 1, 0 ) )
	self.activateEffect:setOffsetRotation( offsetRotation )
end

Advertisement