wiremod-svn-archive/wire/lua/entities/gmod_wire_winch_controller/init.lua
2007-03-24 20:49:28 +00:00

272 lines
6.8 KiB
Lua

AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
ENT.WireDebugName = "Winch"
include('shared.lua')
local MODEL = Model("models/jaanus/wiretool/wiretool_siren.mdl")
DIR_BACKWARD = -1
DIR_NONE = 0
DIR_FORWARD = 1
TYPE_NORMAL = 0
TYPE_MUSCLE = 1
/*---------------------------------------------------------
Name: Initialize
Desc: First function called. Use to set up your entity
---------------------------------------------------------*/
function ENT:Initialize()
self.Entity:SetModel( MODEL )
self.Entity:PhysicsInit( SOLID_VPHYSICS )
self.Entity:SetMoveType( MOVETYPE_VPHYSICS )
self.Entity:SetSolid( SOLID_VPHYSICS )
self.Inputs = Wire_CreateInputs( self.Entity, { "In", "Out", "Length" } )
self.Outputs = Wire_CreateOutputs(self.Entity, { "Length" })
self.Trigger = 0
self.last_time = CurTime()
self.init_time = CurTime()
self.min_length = self.min_length or 1
self.type = self.type or TYPE_NORMAL
self.ctime = self.ctime or 0
end
function ENT:Setup()
self.current_length = 0
self.IsOn = true
end
/*---------------------------------------------------------
Name: KeyValue
Desc: Called when a keyvalue is added to us
---------------------------------------------------------*/
function ENT:KeyValue( key, value )
if (key == "minlength") then self.min_length = tonumber(value)
elseif (key == "maxlength") then self.max_length = tonumber(value)
elseif (key == "type") then self.type = tonumber(value)
end
end
/*---------------------------------------------------------
Name: Think
Desc: Entity's think function.
---------------------------------------------------------*/
function ENT:Think()
self.Entity:NextThink( CurTime() + 0.01 )
local TimeDiff = CurTime() - self.last_time
self.last_time = CurTime()
if (!self.constraint) then return end
if (!self.direction) then return end
if (self.direction == DIR_NONE) then return end
local old_length = self.current_length
local current_length = self.current_length
if (self.type == TYPE_NORMAL) then
local speed = 0
local dist = 0
if (self.direction == DIR_FORWARD) then
local speed = self.constraint:GetTable().fwd_speed
dist = speed * TimeDiff
elseif (self.direction == DIR_BACKWARD) then
local speed = self.constraint:GetTable().bwd_speed
dist = -speed * TimeDiff
end
if (dist == 0) then return end
current_length = current_length + dist
if ( self.min_length && current_length < self.min_length ) then
current_length = self.min_length
if (self.toggle) then self.direction = DIR_NONE end
end
if (self.max_length) then
if (current_length > self.max_length) then
current_length = self.max_length
self.isexpanded = true
if (self.toggle) then self.direction = DIR_NONE end
else
self.isexpanded = false
end
end
elseif ( self.type == TYPE_MUSCLE ) then
local amp = self.constraint:GetTable().amplitude
local per = self.constraint:GetTable().period
local spos = ( math.sin( (self.ctime * math.pi * per )) + 1 ) * (amp / 2)
if (spos > amp) then spos = amp end
if (spos < 0) then spos = 0 end
current_length = self.min_length + spos
self.ctime = self.ctime + TimeDiff
end
self.current_length = current_length
self.constraint:Fire("SetSpringLength", current_length, 0)
if (self.rope) then self.rope:Fire("SetLength", current_length, 0) end
self:SetOverlayText( "Winch length : " .. current_length )
Wire_TriggerOutput(self.Entity, "Length", current_length)
end
function ENT:GetWPos( ent, phys, lpos )
if (ent:EntIndex() == 0) then
return lpos
end
if (phys) and (phys:IsValid()) then
return phys:LocalToWorld( lpos )
else
return ent:LocalToWorld( lpos )
end
end
function ENT:SetConstraint( c )
self.constraint = c
self.direction = DIR_NONE
self.toggle = c:GetTable().toggle
local p1 = self:GetWPos(c:GetTable().Ent1, c:GetTable().Phys1, c:GetTable().LPos1)
local p2 = self:GetWPos(c:GetTable().Ent2, c:GetTable().Phys2, c:GetTable().LPos2)
local dist = (p1 - p2)
self.current_length = dist:Length()
if (self.max_length) then
self.isexpanded = (self.current_length >= self.max_length)
end
if (self.type == TYPE_MUSCLE) then
local amp = self.constraint:GetTable().amplitude
local per = self.constraint:GetTable().period
local spos = self.current_length - self.min_length
spos = spos / (amp*2)
spos = spos - 1
spos = math.Clamp(spos, -1, 1) // just in case!
spos = math.asin(spos)
spos = spos / (per * math.pi)
self.ctime = spos
end
self:ShowOutput( dist:Length() )
self.constraint:Fire("SetSpringLength", self.current_length, 0)
if self.rope then self.rope:Fire("SetLength", self.current_length, 0) end
self:SetOverlayText( "Winch length : " .. self.current_length )
Wire_TriggerOutput(self.Entity, "Length", self.current_length)
end
function ENT:SetRope( r )
self.rope = r
end
function ENT:TriggerInput(iname, value)
if (iname == "In") then
if (value > 0) then
self.direction = -1
elseif (value < 0) then
self.direction = 1
else
self.direction = 0
end
elseif (iname == "Out") then
if (value > 0) then
self.direction = 1
elseif (value < 0) then
self.direction = -1
else
self.direction = 0
end
elseif (iname == "Length") then
self:ShowOutput( math.max(1, value) )
end
end
function ENT:ShowOutput( Length )
if ( Length ~= self.current_length and self.constraint ) then
self:SetOverlayText( "Winch length : " .. Length )
Wire_TriggerOutput(self.Entity, "Length", Length)
self.current_length = Length
self.constraint:Fire("SetSpringLength", self.current_length, 0)
if self.rope then self.rope:Fire("SetLength", self.current_length, 0) end
end
end
/*function ENT:BuildDupeInfo()
local info = self.BaseClass.BuildDupeInfo(self) or {}
if (self.constraint) and (self.constraint:IsValid()) then
info.constraint = self.constraint:EntIndex()
end
if (self.rope) and (self.rope:IsValid()) then
info.rope = self.rope:EntIndex()
end
return info
end*/
function ENT:ApplyDupeInfo(ply, ent, info, GetEntByID, GetConstByID)
self.BaseClass.ApplyDupeInfo(self, ply, ent, info, GetEntByID, GetConstByID)
if (GetConstByID) then
if (info.constraint) and (info.constraint > 0) then
local const = GetConstByID(info.constraint)
if (const) then
self:SetConstraint(const)
end
end
if (info.rope) and (info.rope > 0) then
local rope = GetConstByTable(info.rope)
if (rope) then
self:SetConstraint(rope)
end
end
end
end
function ENT:SetDirection( n )
self.direction = n
end
function ENT:GetDirection()
return self.direction
end
function ENT:IsExpanded()
return self.isexpanded
end