wiremod-svn-archive/wire/lua/entities/gmod_wire_hoverball/init.lua

239 lines
5.9 KiB
Lua

AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
include('shared.lua')
ENT.WireDebugName = "Hoverball"
ENT.OnState = 0
/*---------------------------------------------------------
Name: Initialize
---------------------------------------------------------*/
function ENT:Initialize()
self.Entity:SetModel( "models/dav0r/hoverball.mdl" )
// Don't use the model's physics object, create a perfect sphere
self.Entity:PhysicsInitSphere( 8, "metal_bouncy" )
// Wake up our physics object so we don't start asleep
local phys = self.Entity:GetPhysicsObject()
if ( phys:IsValid() ) then
phys:SetMass( 100 )
phys:EnableGravity( false )
phys:Wake()
end
// Start the motion controller (so PhysicsSimulate gets called)
self.Entity:StartMotionController()
self.Fraction = 0
self.ZVelocity = 0
self:SetTargetZ( self.Entity:GetPos().z )
self:SetSpeed( 1 )
self:EnableHover()
self.Inputs = Wire_CreateInputs(self.Entity, { "A: ZVelocity", "B: HoverMode", "C: SetZTarget" })
self.Outputs = Wire_CreateOutputs(self.Entity, { "A: Zpos", "B: Xpos", "C: Ypos" })
end
function ENT:TriggerInput(iname, value)
if (iname == "A: ZVelocity") then
self:SetZVelocity( value )
elseif (iname == "B: HoverMode") then
if (value >= 1 && self.OnState==0) then
self:EnableHover()
else
self:DisableHover()
end
elseif (iname == "C: SetZTarget") then
self:SetTargetZ(value)
end
end
function ENT:EnableHover()
self.OnState = 1
self:SetHoverMode( true )
self:SetStrength( self.strength or 1 ) //reset weight so it will work
self:SetTargetZ ( self.Entity:GetPos().z ) //set height to current
local phys = self.Entity:GetPhysicsObject()
if ( phys:IsValid() ) then
phys:EnableGravity( false )
phys:Wake()
end
end
function ENT:DisableHover()
self.OnState = 0
self:SetHoverMode( false )
self:SetStrength(0.1) //for less dead weight while off
local phys = self.Entity:GetPhysicsObject()
if ( phys:IsValid() ) then
phys:EnableGravity( true ) //falls slowly otherwise
end
end
function ENT:OnRestore()
self.ZVelocity = 0
self.BaseClass.OnRestore(self)
end
/*---------------------------------------------------------
Name: OnTakeDamage
---------------------------------------------------------*/
function ENT:OnTakeDamage( dmginfo )
//self.Entity:TakePhysicsDamage( dmginfo )
end
/*---------------------------------------------------------
Name: Think
---------------------------------------------------------*/
function ENT:Think()
self.Entity:NextThink( CurTime() + 0.25 )
self.Entity:SetNetworkedInt( "TargetZ", self:GetTargetZ() )
return true
end
/*---------------------------------------------------------
Name: Simulate
---------------------------------------------------------*/
function ENT:PhysicsSimulate( phys, deltatime )
local Pos = phys:GetPos()
local txt = string.format( "Speed: %i\nResistance: %.2f", self:GetSpeed(), self:GetAirResistance() )
txt = txt.."\nZ pos: "..math.floor(Pos.z) //.."Target: "..math.floor(self:GetTargetZ())
Wire_TriggerOutput(self.Entity, "A: Zpos", Pos.z)
Wire_TriggerOutput(self.Entity, "B: Xpos", Pos.x)
Wire_TriggerOutput(self.Entity, "C: Ypos", Pos.y)
if (self:GetHoverMode()) then
txt = txt.." (on)"
self:SetOverlayText( txt )
if ( self.ZVelocity != 0 ) then
self:SetTargetZ( self:GetTargetZ() + (self.ZVelocity * deltatime * self:GetSpeed()) )
self.Entity:GetPhysicsObject():Wake()
end
phys:Wake()
local Vel = phys:GetVelocity()
local Distance = self:GetTargetZ() - Pos.z
local AirResistance = self:GetAirResistance()
if ( Distance == 0 ) then return end
local Exponent = Distance^2
if ( Distance < 0 ) then
Exponent = Exponent * -1
end
Exponent = Exponent * deltatime * 300
local physVel = phys:GetVelocity()
local zVel = physVel.z
Exponent = Exponent - (zVel * deltatime * 600 * ( AirResistance + 1 ) )
// The higher you make this 300 the less it will flop about
// I'm thinking it should actually be relative to any objects we're connected to
// Since it seems to flop more and more the heavier the object
Exponent = math.Clamp( Exponent, -5000, 5000 )
local Linear = Vector(0,0,0)
local Angular = Vector(0,0,0)
Linear.z = Exponent
if ( AirResistance > 0 ) then
Linear.y = physVel.y * -1 * AirResistance
Linear.x = physVel.x * -1 * AirResistance
end
return Angular, Linear, SIM_GLOBAL_ACCELERATION
else
txt = txt.." (off)"
self:SetOverlayText( txt )
return SIM_GLOBAL_FORCE
end
end
function ENT:SetZVelocity( z )
if ( z != 0 ) then
self.Entity:GetPhysicsObject():Wake()
end
self.ZVelocity = z * FrameTime() * 5000
end
/*---------------------------------------------------------
GetAirFriction
---------------------------------------------------------*/
function ENT:GetAirResistance( )
return self.Entity:GetVar( "AirResistance", 0 )
end
/*---------------------------------------------------------
SetAirFriction
---------------------------------------------------------*/
function ENT:SetAirResistance( num )
self.Entity:SetVar( "AirResistance", num )
end
/*---------------------------------------------------------
SetStrength
---------------------------------------------------------*/
function ENT:SetStrength( strength )
local phys = self.Entity:GetPhysicsObject()
if ( phys:IsValid() ) then
phys:SetMass( 150 * strength )
end
end
/*---------------------------------------------------------
--Duplicator support
---------------------------------------------------------*/
function ENT:BuildDupeInfo()
local info = self.BaseClass.BuildDupeInfo(self) or {}
info.OnState = self.OnState
return info
end
function ENT:ApplyDupeInfo(ply, ent, info, GetEntByID)
if(ply && ent && info && GetEntByID)then
self.BaseClass.ApplyDupeInfo(self, ply, ent, info, GetEntByID)
end
if (info && info.OnState) then
if(info.OnState==0)then
self:DisableHover()
else
self:EnableHover()
end
end
end