diff --git a/lua/entities/gmod_tardis/modules/sh_flight.lua b/lua/entities/gmod_tardis/modules/sh_flight.lua index 451082568..743c19589 100644 --- a/lua/entities/gmod_tardis/modules/sh_flight.lua +++ b/lua/entities/gmod_tardis/modules/sh_flight.lua @@ -100,10 +100,6 @@ function ENT:GetFlight() return self:GetData("flight",false) end -function ENT:IsTravelling() - return self:CallHook("IsTravelling") -end - ENT:AddHook("IsTravelling", "flight", function(self) if self:GetFlight() then return true diff --git a/lua/entities/gmod_tardis/modules/sh_state.lua b/lua/entities/gmod_tardis/modules/sh_state.lua new file mode 100644 index 000000000..4b8c5da7b --- /dev/null +++ b/lua/entities/gmod_tardis/modules/sh_state.lua @@ -0,0 +1,168 @@ +-- TARDIS State + +-- A list of supported states +TARDIS.States = { + ["dead"] = true, + + ["off"] = true, + ["idle"] = true, + ["handbrake"] = true, + ["travel"] = true, + ["demat_abort"] = true, + ["demat_fail"] = true, + ["mat_fail"] = true, + ["takeoff"] = true, + ["parking"] = true, + + ["off_warning"] = true, + ["idle_warning"] = true, + ["handbrake_warning"] = true, + ["travel_warning"] = true, + ["demat_abort_warning"] = true, + ["demat_fail_warning"] = true, + ["mat_fail_warning"] = true, + ["takeoff_warning"] = true, + ["parking_warning"] = true, +} + +-- We add all the hooks here to ensure the integrity of state logic +TARDIS.StateUpdateHooks = { + ["PostInitialize"] = true, + + ["OnHealthDepleted"] = true, + ["OnHealthChange"] = true, + + ["WarningToggled"] = true, + ["PowerToggled"] = true, + ["HandbrakeToggled"] = true, + + ["DematStart"] = true, + ["MatStart"] = true, + ["PreMatStart"] = true, + ["StopDemat"] = true, + ["StopMat"] = true, + ["InterruptTeleport"] = true, + ["DematInterrupted"] = true, + ["DematFailed"] = true, + ["DematFailStopped"] = true, + ["MatFailed"] = true, + ["MatFailStopped"] = true, + + ["TakeoffStateToggled"] = true, + ["ParkingStateToggled"] = true, + ["DematAbortStateToggled"] = true, + + ["FlightToggled"] = true, +} + +-- Adding the hooks +for hook_name, hook_val in pairs(TARDIS.StateUpdateHooks) do + ENT:AddHook(hook_name, "state_update", function(self) + self:UpdateState() + end) +end + +-- + +function ENT:SetState(state) + if not TARDIS.States[state] then + error("Attempted to apply unsupported state " .. state) + end + return self:SetData("state", state, true) +end + +function ENT:GetState() + return self:GetData("state") +end + +function ENT:SelectState() + local function select_warning(state) + return self:GetWarning() and (state .. "_warning") or state + end + + if self:IsDead() then + return "dead", false + end + + if not self:GetPower() then + return select_warning("off") + end + + if self:IsTravelling() then + if self:GetData("failing-mat") then + return select_warning("mat_fail") + end + if self:GetData("state_takeoff") then + return select_warning("takeoff") + end + return select_warning("travel") + end + + if self:GetData("failing-demat") then + return select_warning("demat_fail") + end + + if self:GetData("state_demat_abort") then + return select_warning("demat_abort") + end + + if self:GetHandbrake() then + return select_warning("handbrake") + end + + if self:GetData("state_parking") then + return select_warning("parking") + end + + return select_warning("idle") +end + +function ENT:UpdateState() + return self:SetState(self:SelectState()) +end + +-- +-- "Travelling" generalisation +-- + +function ENT:IsTravelling() + return self:CallHook("IsTravelling") +end + +-- +-- Custom states for visual effects with no functionality +-- + +local function ProcessTemporaryState(self, time, data_id, hook_name) + if time ~= 0 then + self:SetData(data_id, true) + self:CallHook(hook_name, true) + self:Timer(data_id .. "reset", time, function() + self:SetData(data_id, nil) + self:CallHook(hook_name, false) + end) + end +end + +ENT:AddHook("DematStart", "state_takeoff", function(self) + ProcessTemporaryState(self, self.metadata.Timings.TakeOffState, "state_takeoff", "TakeoffStateToggled") + self:UpdateState() +end) + +ENT:AddHook("StopMat", "state_parking", function(self) + ProcessTemporaryState(self, self.metadata.Timings.ParkingState, "state_parking", "ParkingStateToggled") + self:UpdateState() +end) + +ENT:AddHook("DematInterrupted", "state_demat_abort", function(self) + ProcessTemporaryState(self, self.metadata.Timings.DematAbortState, "state_demat_abort", "DematAbortStateToggled") + self:UpdateState() +end) + +-- fixing handbrake + stopmat conflict +ENT:AddHook("HandbrakeToggled", "state_parking", function(self, on) + if on and self:GetData("state_parking") then + self:SetData("state_parking", nil) + self:CancelTimer("state_parking_reset") + end +end) diff --git a/lua/entities/gmod_tardis/modules/teleport/sh_tp_failed.lua b/lua/entities/gmod_tardis/modules/teleport/sh_tp_failed.lua index e14f89120..3a09fc58d 100644 --- a/lua/entities/gmod_tardis/modules/teleport/sh_tp_failed.lua +++ b/lua/entities/gmod_tardis/modules/teleport/sh_tp_failed.lua @@ -10,6 +10,8 @@ if SERVER then local time = self.metadata.Timings.DematFail self:Timer("failed-demat-stop", time, function() self:SetData("failing-demat", false, true) + self:CallCommonHook("DematFailStopped") + self:CallClientCommonHook("DematFailStopped") end) end @@ -42,10 +44,13 @@ if SERVER then end self:SetData("failing-mat", true, true) + self:CallCommonHook("MatFailed") self:SendMessage("failed-mat") local time = self.metadata.Timings.MatFail self:Timer("failed-mat-stop", time, function() self:SetData("failing-mat", false, true) + self:CallCommonHook("MatFailStopped") + self:CallClientCommonHook("MatFailStopped") end) if callback then callback(false) end end @@ -156,6 +161,7 @@ else -- CLIENT end) ENT:OnMessage("failed-mat", function(self, data, ply) + self:CallCommonHook("MatFailed") if TARDIS:GetSetting("teleport-sound") and TARDIS:GetSetting("sound") then local ext = self.metadata.Exterior.Sounds.Teleport local int = self.metadata.Interior.Sounds.Teleport diff --git a/lua/entities/gmod_tardis/modules/teleport/sh_tp_interrupt.lua b/lua/entities/gmod_tardis/modules/teleport/sh_tp_interrupt.lua index b86970dc6..dea0866b9 100644 --- a/lua/entities/gmod_tardis/modules/teleport/sh_tp_interrupt.lua +++ b/lua/entities/gmod_tardis/modules/teleport/sh_tp_interrupt.lua @@ -57,11 +57,8 @@ if SERVER then self:SetData("teleport-interrupt-time", CurTime(), true) self:SetData("teleport-interrupt-effects", true, true) else - local time = self.metadata.Timings.DematInterrupt - self:SetData("demat-interrupted", true, true) - self:Timer("interrupt_demat", time, function() - self:SetData("demat-interrupted", nil, true) - end) + self:CallCommonHook("DematInterrupted") + self:CallClientCommonHook("DematInterrupted") end end @@ -134,32 +131,32 @@ else end ENT:AddHook("Think", "tp_interrupt", function(self) - if self:GetData("teleport-interrupted", false) then - local timediff = CurTime() - self:GetData("teleport-interrupt-time") + if not self:GetData("teleport-interrupted", false) then return end - if timediff > 6 and timediff < 6.2 and self:GetData("teleport-interrupt-effects", false) then - self:SetData("teleport-interrupt-effects", false, true) - end + local timediff = CurTime() - self:GetData("teleport-interrupt-time") - local showeffects = (CLIENT and self:GetData("teleport-interrupt-effects", false) - and LocalPlayer():GetTardisData("exterior") == self - and (not LocalPlayer():GetTardisData("thirdperson")) - and TARDIS:GetSetting("breakdown-effects")) + if timediff > 6 and timediff < 6.2 and self:GetData("teleport-interrupt-effects", false) then + self:SetData("teleport-interrupt-effects", false, true) + end - if showeffects then - if math.Round(10 * CurTime()) % 2 == 0 then - self:InteriorSparks(1) - end - if timediff < 0.1 or (timediff > 2 and timediff < 2.1) - or (timediff > 2.6 and timediff < 2.7) - then - self:InteriorExplosion() - end - end + local showeffects = (CLIENT and self:GetData("teleport-interrupt-effects", false) + and LocalPlayer():GetTardisData("exterior") == self + and (not LocalPlayer():GetTardisData("thirdperson")) + and TARDIS:GetSetting("breakdown-effects")) - if timediff > 10 then - self:SetData("teleport-interrupted", false, true) + if showeffects then + if math.Round(10 * CurTime()) % 2 == 0 then + self:InteriorSparks(1) + end + if timediff < 0.1 or (timediff > 2 and timediff < 2.1) + or (timediff > 2.6 and timediff < 2.7) + then + self:InteriorExplosion() end end + + if timediff > 10 then + self:SetData("teleport-interrupted", false, true) + end end) diff --git a/lua/entities/gmod_tardis/shared.lua b/lua/entities/gmod_tardis/shared.lua index c8f91fa16..0bbcb974d 100644 --- a/lua/entities/gmod_tardis/shared.lua +++ b/lua/entities/gmod_tardis/shared.lua @@ -126,4 +126,22 @@ function ENT:LoadFolder(folder,addonly,noprefix) end ENT:LoadFolder("modules/libraries") -ENT:LoadFolder("modules") \ No newline at end of file + +if SERVER then + function ENT:CallClientHook(name, ...) + self:SendMessage("client_hook", {name, ...}) + end + function ENT:CallClientCommonHook(name, ...) + self:SendMessage("client_common_hook", {name, ...}) + end +else + ENT:OnMessage("client_hook", function(self, data, ply) + self:CallHook(unpack(data)) + end) + ENT:OnMessage("client_common_hook", function(self, data, ply) + self:CallCommonHook(unpack(data)) + end) +end + + +ENT:LoadFolder("modules") diff --git a/lua/entities/gmod_tardis_interior/modules/cl_render.lua b/lua/entities/gmod_tardis_interior/modules/lighting/cl_render.lua similarity index 100% rename from lua/entities/gmod_tardis_interior/modules/cl_render.lua rename to lua/entities/gmod_tardis_interior/modules/lighting/cl_render.lua diff --git a/lua/entities/gmod_tardis_interior/modules/lighting/cl_roundthings.lua b/lua/entities/gmod_tardis_interior/modules/lighting/cl_roundthings.lua new file mode 100644 index 000000000..455130944 --- /dev/null +++ b/lua/entities/gmod_tardis_interior/modules/lighting/cl_roundthings.lua @@ -0,0 +1,32 @@ +-- Round things (light sprites for old default interior) + +if CLIENT then + function ENT:AddRoundThing(pos) + self.roundthings[pos]=util.GetPixelVisibleHandle() + end + + ENT:AddHook("Initialize", "lights-roundthings", function(self) + if self.metadata.Interior.RoundThings then + self.roundthingmat=Material("sprites/light_ignorez") + self.roundthings={} + for k,v in pairs(self.metadata.Interior.RoundThings) do + self:AddRoundThing(v) + end + end + end) + + local size=32 + ENT:AddHook("Draw", "lights-roundthings", function(self) + if self.roundthings then + if self:CallHook("ShouldDrawLight")==false then return end + for k,v in pairs(self.roundthings) do + local pos = self:LocalToWorld(k) + local vis = util.PixelVisible(pos, 3, v)*255 + if vis > 0 then + render.SetMaterial(self.roundthingmat) + render.DrawSprite(pos, size, size, Color(255,153,0, vis)) + end + end + end + end) +end diff --git a/lua/entities/gmod_tardis_interior/modules/lighting/sh_baselight.lua b/lua/entities/gmod_tardis_interior/modules/lighting/sh_baselight.lua new file mode 100644 index 000000000..e15738c93 --- /dev/null +++ b/lua/entities/gmod_tardis_interior/modules/lighting/sh_baselight.lua @@ -0,0 +1,90 @@ + +-- Base light + +function ENT:GetCustomBaseLightEnabled() + return self:GetData("interior_custom_base_light_enabled", false) +end + +function ENT:GetCustomBaseLightColor() + return self:GetData("interior_custom_base_light_color") +end + +function ENT:GetGetBaseLightColorVector() + return self:GetData("interior_base_light_color_vec") +end + +function ENT:GetCustomBaseLightBrightness() + return self:GetData("interior_custom_base_light_brightness") +end + + +if SERVER then + function ENT:SetCustomBaseLightEnabled(enabled) + self:SetData("interior_custom_base_light_enabled", enabled or false, true) + end + + function ENT:ToggleCustomBaseLightEnabled() + self:SetCustomBaseLightEnabled(not self:GetCustomBaseLightEnabled()) + end + + function ENT:SetCustomBaseLightColor(color) + self:SetData("interior_custom_base_light_color", color, true) + end + + function ENT:SetCustomBaseLightBrightness(brightness) + self:SetData("interior_custom_base_light_brightness", brightness, true) + end +else + function ENT:GetBaseLightColorVector() + return self:GetData("interior_base_light_color_vec", TARDIS.color_white_vector) + end + + function ENT:GetBaseLightColor() + return self:GetBaseLightColorVector():ToColor() + end + + ENT:AddHook("Think", "baselight", function(self) + local lo = self.metadata.Interior.LightOverride + if not lo then return end + + local power = self:GetPower() + + local normalbr = power and lo.basebrightness or lo.nopowerbrightness + local normalcolvec = power and lo.basebrightnessRGB or lo.nopowerbrightnessRGB or TARDIS.color_white_vector + + local customcol = self:GetData("interior_custom_base_light_color") + local custombr = self:GetData("interior_custom_base_light_brightness", normalbr) + + local currentcolvec = self:GetData("interior_base_light_color_vec") + local targetcolvec + if self:GetData("interior_custom_base_light_enabled") and customcol then + targetcolvec = customcol:ToVector() * (custombr or normalbr) + else + targetcolvec = normalcolvec * normalbr + end + + if currentcolvec == targetcolvec then + return + elseif not currentcolvec then + self:SetData("interior_base_light_color_vec", targetcolvec) + return + end + + local savedtargetcolvec = self:GetData("interior_base_light_target_color_vec") + + if savedtargetcolvec ~= targetcolvec then + self:SetData("interior_base_light_target_color_vec", targetcolvec) + self:SetData("interior_base_light_previous_color_vec", currentcolvec) + self:SetData("interior_base_light_transition_fraction", 0) + end + + local prevcolvec = self:GetData("interior_base_light_previous_color_vec", currentcolvec) + local fraction = self:GetData("interior_base_light_transition_fraction", 0) + fraction = math.min(fraction + (FrameTime() * self.metadata.Interior.LightOverride.transitionspeed), 1) + + local colvec = LerpVector(fraction, prevcolvec, targetcolvec) + + self:SetData("interior_base_light_color_vec", colvec) + self:SetData("interior_base_light_transition_fraction", fraction) + end) +end \ No newline at end of file diff --git a/lua/entities/gmod_tardis_interior/modules/lighting/sh_debug_lamps.lua b/lua/entities/gmod_tardis_interior/modules/lighting/sh_debug_lamps.lua new file mode 100644 index 000000000..8fdc8dfa6 --- /dev/null +++ b/lua/entities/gmod_tardis_interior/modules/lighting/sh_debug_lamps.lua @@ -0,0 +1,99 @@ +CreateConVar("tardis2_debug_lamps", 0, {FCVAR_ARCHIVE}, "TARDIS - enable debugging interior lamps") +TARDIS.debug_lamps_enabled = GetConVar("tardis2_debug_lamps"):GetBool() + + +-- Debug Lamps (a way for developers to set up the projected lights) + +if SERVER then + + util.AddNetworkString("TARDIS-DebugLampsToggled") + cvars.AddChangeCallback("tardis2_debug_lamps", function() + TARDIS.debug_lamps_enabled = GetConVar("tardis2_debug_lamps"):GetBool() + net.Start("TARDIS-DebugLampsToggled") + net.WriteBool(TARDIS.debug_lamps_enabled) + net.Broadcast() + -- It was required to manually code networking for this convar + -- AddChangeCallback doesn't callback client convars with FCVAR_REPLICATED + -- Details: https://github.com/Facepunch/garrysmod-issues/issues/3740 + end) + + ENT:AddHook("Initialize", "debug_lamps", function(self) + if not TARDIS.debug_lamps_enabled then return end + + local lamps = self.metadata.Interior.Lamps + if not lamps then return end + + self.debug_lamps = {} + + for k,v in pairs(lamps) do + if v then + if not v.color then + v.color = Color(255,255,255) + end + local lamp = MakeLamp(nil, -- creator + v.color.r, v.color.g, v.color.b, + KEY_NONE, -- toggle key + true, -- toggle + v.texture or "effects/flashlight/soft", -- projected texture + "models/maxofs2d/lamp_projector.mdl", -- lamp model + v.fov or 90, + v.distance or 1024, + v.brightness or 3.0, + true, -- enabled + { + Pos = self:LocalToWorld(v.pos or Vector(0,0,0)), + Angle = v.ang or Angle(0,0,0), + } + ) + + lamp:SetUnFreezable(false) + lamp:GetPhysicsObject():EnableGravity(false) + lamp:GetPhysicsObject():EnableMotion(false) + + lamp:SetUseType(SIMPLE_USE) + lamp.Use = function(lamp, ply) + local clr = lamp:GetColor() + local pos = self:WorldToLocal(lamp:GetPos()) + local ang = lamp:GetAngles() + + print("{\n\tcolor = Color(" .. clr.r .. ", " .. clr.g .. ", " .. clr.b .. "),") + print("\ttexture = \"" .. lamp:GetFlashlightTexture() .. "\",") + print("\tfov = " .. lamp:GetLightFOV() .. ",") + print("\tdistance = " .. lamp:GetDistance() .. ",") + print("\tbrightness = " .. lamp:GetBrightness() .. ",") + print("\tpos = Vector(" .. pos.x .. ", " .. pos.y .. ", " .. pos.z .. "),") + print("\tang = Angle(" .. ang.x .. ", " .. ang.y .. ", " .. ang.z .. "),") + print("},") + end + lamp:SetCollisionGroup(COLLISION_GROUP_WORLD) + + lamp.lamp_data = v + + table.insert(self.debug_lamps, lamp) + end + end + end) + + ENT:AddHook("OnRemove", "debug_lamps", function(self) + if not self.debug_lamps then return end + for k,v in pairs(self.debug_lamps) do + if IsValid(v) then + v:Remove() + end + end + end) + + ENT:AddHook("PowerToggled", "debug_lamps", function(self, on) + if not self.debug_lamps then return end + + for k,v in pairs(self.debug_lamps) do + if IsValid(v) and v.lamp_data.nopower ~= true then + v:SetOn(on) + end + end + end) +else + net.Receive("TARDIS-DebugLampsToggled", function() + TARDIS.debug_lamps_enabled = net.ReadBool() + end) +end \ No newline at end of file diff --git a/lua/entities/gmod_tardis_interior/modules/lighting/sh_lamps.lua b/lua/entities/gmod_tardis_interior/modules/lighting/sh_lamps.lua new file mode 100644 index 000000000..51bbdb908 --- /dev/null +++ b/lua/entities/gmod_tardis_interior/modules/lighting/sh_lamps.lua @@ -0,0 +1,239 @@ +-- Lamps (projected lights) + +if CLIENT then + local function MergeLampTable(tbl, base, keep_warn_off_options) + if not tbl then return nil end + + local new_table = TARDIS:CopyTable(base) + new_table.states = nil + if not keep_warn_off_options then + new_table.warn = nil + new_table.off = nil + new_table.off_warn = nil + end + table.Merge(new_table, tbl) + return new_table + end + + local function ParseLampTable(lmp) + if not lmp then return end + if lmp.parsed == true then return end + + lmp.texture = lmp.texture or "effects/flashlight/soft" + lmp.pos = lmp.pos or Vector(0,0,0) + lmp.ang = lmp.ang or Angle(0,0,0) + lmp.fov = lmp.fov or 90 + lmp.color = lmp.color or Color(255,255,255) + lmp.brightness = lmp.brightness or 3.0 + lmp.distance = lmp.distance or 1024 + lmp.shadows = lmp.shadows or false + + lmp.warn = MergeLampTable(lmp.warn, lmp, false) + lmp.off = MergeLampTable(lmp.off, lmp, false) + lmp.off_warn = MergeLampTable(lmp.off_warn, lmp.off or lmp, false) + + if lmp.states then + for k,v in pairs(lmp.states) do + lmp.states[k] = MergeLampTable(v, lmp, true) + end + end + + lmp.parsed = true + end + + function ENT:InitLampData(lmp) + if not lmp or not lmp.pos then return end + lmp.pos_global = self:LocalToWorld(lmp.pos) + if lmp.sprite then + lmp.spritepixvis = util.GetPixelVisibleHandle() + lmp.sprite_brightness = lmp.sprite_brightness or 1 + end + self:InitLampData(lmp.warn) + self:InitLampData(lmp.off) + self:InitLampData(lmp.off_warn) + + if not lmp.states then return end + for k,v in pairs(lmp.states) do + self:InitLampData(v) + end + end + + function ENT:LoadLamps() + local lamps = self.metadata.Interior.Lamps + if not lamps then return end + + self.lamps_data = {} + + for k,v in pairs(lamps) do + ParseLampTable(v) -- only once per metadata + local this_lamp = TARDIS:CopyTable(v) + self:InitLampData(this_lamp) + self.lamps_data[k] = this_lamp + end + end + + ENT:AddHook("Initialize", "lamps", function(self) + self:LoadLamps() + self:CreateLamps() + self:RunLampUpdate() + end) + + function ENT:CreateLamp(lmp) + if not lmp then return end + if lmp.enabled == false then return end + local pl = ProjectedTexture() + pl:SetTexture(lmp.texture) + pl:SetPos(lmp.pos_global) + pl:SetAngles(lmp.ang) + pl:SetFOV(lmp.fov) + pl:SetColor(lmp.color) + pl:SetBrightness(lmp.brightness) + pl:SetFarZ(lmp.distance) + pl:SetEnableShadows(lmp.shadows) + pl:Update() + return pl + end + + local function SelectLampTable(self, lmp) + local state = self:GetData("light_state") + local warning = self:GetData("warning", false) + local power = self:GetPower() + local l = lmp + + if lmp and lmp.states then + l = lmp.states[state] or l + end + + if not power and lmp.nopower ~= true then + return nil + end + + if not power and warning then + l = l.off_warn or l + elseif not power then + l = l.off or l + elseif warning then + l = l.warn or l + end + + return l + end + + function ENT:CreateLamps() + if not TARDIS:GetSetting("lamps-enabled") then return end + if TARDIS.debug_lamps_enabled then return end + if not self.lamps_data then return end + + self.lamps = {} + for k,v in pairs(self.lamps_data) do + self.lamps[k] = self:CreateLamp(SelectLampTable(self, v)) + end + end + + function ENT:RemoveLamps() + if not self.lamps then return end + for k,v in pairs(self.lamps) do + if IsValid(v) then + v:Remove() + end + end + self.lamps = nil + end + + local function ReplaceLamps(self) + if not TARDIS:GetSetting("lamps-enabled") then return end + self:RemoveLamps() + self:CreateLamps() + self:RunLampUpdate() + end + + ENT:AddHook("LightStateChanged", "lamps", ReplaceLamps) + + ENT:AddHook("PowerToggled", "lamps", ReplaceLamps) + + ENT:AddHook("WarningToggled", "lamps", ReplaceLamps) + + + function ENT:RunLampUpdate() + if not TARDIS:GetSetting("lamps-enabled") then return end + if not self.lamps then return end + + self.lamps_need_updating = true + + self:Timer("lamps_update_stop", 0.3, function() + self.lamps_need_updating = false + end) + end + + ENT:AddHook("Think", "lamps_updates", function(self) + if not self.lamps_need_updating then return end + + if not TARDIS:GetSetting("lamps-enabled") then return end + if not self.lamps then return end + + for k,v in pairs(self.lamps) do + if IsValid(v) then + v:Update() + end + end + end) + + local matLight = Material("sprites/light_ignorez") + ENT:AddHook("Draw", "lamps", function(self) + if not TARDIS:GetSetting("lamps-enabled") then return end + if not self.lamps_data then return end + + for k,v in pairs(self.lamps_data) do + local data = SelectLampTable(self, v) + if not data then return end + if data.sprite then + -- adapted from https://github.com/Facepunch/garrysmod/blob/master/garrysmod/gamemodes/sandbox/entities/entities/gmod_lamp.lua + + local lightPos = data.pos_global + local viewNormal = lightPos - EyePos() + local distance = viewNormal:Length() + + render.SetMaterial( matLight ) + local visible = util.PixelVisible(lightPos, 16, data.spritepixvis) + if not visible then return end + + local size = math.Clamp(distance * visible * 2, 64, 512) + + distance = math.Clamp(distance, 32, 800) + local alpha = math.Clamp((1000 - distance) * visible * data.sprite_brightness, 0, 100) + + render.DrawSprite(lightPos, size, size, ColorAlpha(data.color, alpha)) + render.DrawSprite(lightPos, size * 0.4, size * 0.4, Color( 255, 255, 255, alpha )) + end + end + end) + + + ENT:AddHook("SettingChanged", "lamps", function(self, id, val) + if id ~= "lamps-enabled" then return end + + if val and self.lamps == nil then + self:CreateLamps() + self:RunLampUpdate() + elseif not val and self.lamps then + self:RemoveLamps() + end + end) + + ENT:AddHook("PostInitialize", "lamps", function(self) + self:RunLampUpdate() + end) + + ENT:AddHook("ToggleDoor", "lamps", function(self) + self:RunLampUpdate() + end) + + ENT:AddHook("PlayerEnter", "lamps", function(self) + self:RunLampUpdate() + end) + + ENT:AddHook("OnRemove", "lamps", function(self) + self:RemoveLamps() + end) +end + diff --git a/lua/entities/gmod_tardis_interior/modules/lighting/sh_lights.lua b/lua/entities/gmod_tardis_interior/modules/lighting/sh_lights.lua new file mode 100644 index 000000000..d3dbde7c3 --- /dev/null +++ b/lua/entities/gmod_tardis_interior/modules/lighting/sh_lights.lua @@ -0,0 +1,250 @@ +-- Lights + +local function ParseLightTable(lt, interior, default_falloff) + if SERVER then return end + + if not lt then return end + + lt.falloff = lt.falloff or default_falloff + -- default falloff values were taken from cl_render.lua::predraw_o + + if lt.warncolor then + lt.warn_color = lt.warncolor + lt.warncolor = nil + end + + lt.warn_color = lt.warn_color or lt.color + lt.warn_pos = lt.warn_pos or lt.pos + lt.warn_brightness = lt.warn_brightness or lt.brightness + lt.warn_falloff = lt.warn_falloff or lt.falloff + + if lt.nopower then + lt.off_color = lt.off_color or lt.color + lt.off_pos = lt.off_pos or lt.pos + lt.off_brightness = lt.off_brightness or lt.brightness + lt.off_falloff = lt.off_falloff or lt.falloff + + -- defaulting `off + warn` to `off` unless specified otherwise + lt.off_warn_color = lt.off_warn_color or lt.off_color + lt.off_warn_pos = lt.off_warn_pos or lt.off_pos + lt.off_warn_brightness = lt.off_warn_brightness or lt.off_brightness + lt.off_warn_falloff = lt.off_warn_falloff or lt.off_falloff + end + + -- optimize calculations in `cl_render.lua::predraw_o` + lt.color_vec = lt.color:ToVector() * lt.brightness + lt.pos_global = interior:LocalToWorld(lt.pos) + + lt.warn_color_vec = lt.warn_color:ToVector() * lt.warn_brightness + lt.warn_pos_global = interior:LocalToWorld(lt.warn_pos) + + if lt.nopower then + lt.off_pos_global = interior:LocalToWorld(lt.off_pos) + lt.off_color_vec = lt.off_color:ToVector() * lt.off_brightness + + lt.off_warn_pos_global = interior:LocalToWorld(lt.off_warn_pos) + lt.off_warn_color_vec = lt.off_warn_color:ToVector() * lt.off_warn_brightness + end + + lt.render_table = { + type = MATERIAL_LIGHT_POINT, + color = lt.color_vec, + pos = lt.pos_global, + quadraticFalloff = lt.falloff, + } + lt.warn_render_table = { + type = MATERIAL_LIGHT_POINT, + color = lt.warn_color_vec, + pos = lt.warn_pos_global, + quadraticFalloff = lt.warn_falloff, + } + + if lt.nopower then + lt.off_render_table = { + type = MATERIAL_LIGHT_POINT, + color = lt.off_color_vec, + pos = lt.off_pos_global, + quadraticFalloff = lt.off_falloff, + } + lt.off_warn_render_table = { + type = MATERIAL_LIGHT_POINT, + color = lt.off_warn_color_vec, + pos = lt.off_warn_pos_global, + quadraticFalloff = lt.off_warn_falloff, + } + else + lt.off_render_table = {} + lt.off_warn_render_table = {} + end +end + +if CLIENT then + local function MergeLightTable(tbl, base) + local new_table = TARDIS:CopyTable(base) + if not tbl then return new_table end + + new_table.NoLO = nil + new_table.NoExtra = nil + new_table.NoExtraNoLO = nil + + table.Merge(new_table, tbl) + return new_table + end + + function ENT:LoadLights() + local noLO = not TARDIS:GetSetting("lightoverride-enabled") + local noExtra = not TARDIS:GetSetting("extra-lights") + + local int_metadata = self.metadata.Interior + local light = int_metadata.Light + local lights = int_metadata.Lights + + local light_alt + + if noLO and noExtra then + light_alt = light.NoExtraNoLO or light.NoLO + elseif noLO then + light_alt = light.NoLO + elseif noExtra then + light_alt = light.NoExtra + end + + self.light_data = { + main = MergeLightTable(light_alt, light), + extra = {}, + } + ParseLightTable(self.light_data.main, self, 20) + + if not lights then return end + for k,v in pairs(lights) do + if v and istable(v) then + local v_alt + if noLO then + v_alt = v.NoLO + end + self.light_data.extra[k] = MergeLightTable(v_alt, v) + ParseLightTable(self.light_data.extra[k], self, 10) + end + end + end + + ENT:AddHook("Initialize", "lights", function(self) + self:LoadLights() + end) + + ENT:AddHook("SettingChanged", "lights", function(self, id, val) + if id ~= "lightoverride-enabled" and id ~= "extra-lights" then return end + self:LoadLights() + end) + + function ENT:DrawLight(id,light) + if self:CallHook("ShouldDrawLight",id,light)==false then return end + + local dlight = DynamicLight(id, true) + if not dlight then return end + + local warning = self:GetData("warning", false) + local power = self:GetPower() + + if not power and warning then + dlight.Pos = light.off_warn_pos_global + dlight.r = light.off_warn_color.r + dlight.g = light.off_warn_color.g + dlight.b = light.off_warn_color.b + dlight.Brightness = light.off_warn_brightness + elseif not power then + dlight.Pos = light.off_pos_global + dlight.r = light.off_color.r + dlight.g = light.off_color.g + dlight.b = light.off_color.b + dlight.Brightness = light.off_brightness + elseif warning then + dlight.Pos = light.warn_pos_global + dlight.r = light.warn_color.r + dlight.g = light.warn_color.g + dlight.b = light.warn_color.b + dlight.Brightness = light.warn_brightness + else -- power & no warning + dlight.Pos = light.pos_global + dlight.r = light.color.r + dlight.g = light.color.g + dlight.b = light.color.b + dlight.Brightness = light.brightness + end + + dlight.Decay = 5120 + dlight.Size = 1024 + dlight.DieTime = CurTime() + 1 + end + + ENT:AddHook("Think", "lights", function(self) + if TARDIS:GetSetting("lightoverride-enabled") then return end + local light = self.light_data.main + local lights = self.light_data.extra + local index=self:EntIndex() + if light then + self:DrawLight(index,light) + end + if lights and TARDIS:GetSetting("extra-lights") then + local i=0 + for _,light in pairs(lights) do + i=i+1 + self:DrawLight((index*1000)+i,light) + end + end + end) + + ENT:AddHook("ShouldDrawLight", "interior_light_enabled", function(self,id,light) + if light and light.enabled == false then return false end + -- allow disabling lights with light states + end) +end + + + + +-- Light states + +local function ChangeSingleLightState(light_table, state) + local new_state = light_table.states and light_table.states[state] + if not new_state then return end + table.Merge(light_table, new_state) +end + +function ENT:ApplyLightState(state) + self:SetData("light_state", state) + self:CallHook("LightStateChanged", state) + + if SERVER then + self:SendMessage("light_state", {state} ) + else + local ldata = self.light_data + ChangeSingleLightState(ldata.main, state) + ParseLightTable(ldata.main, self, 20) + + for k,v in pairs(ldata.extra) do + ChangeSingleLightState(v, state) + ParseLightTable(v, self, 10) + end + end +end + +if CLIENT then + ENT:OnMessage("light_state", function(self, data, ply) + self:ApplyLightState(data[1]) + end) +end + + +if CLIENT then + ENT:AddHook("SlowThink", "lights", function(self) + local pos = self:GetPos() + if self.lights_lastpos == pos then return end + if self.lights_lastpos ~= nil then + self:LoadLights() + self:LoadLamps() + self:CreateLamps() + end + self.lights_lastpos = pos + end) +end \ No newline at end of file diff --git a/lua/entities/gmod_tardis_interior/modules/sh_interior_lights.lua b/lua/entities/gmod_tardis_interior/modules/sh_interior_lights.lua deleted file mode 100644 index a2851b50e..000000000 --- a/lua/entities/gmod_tardis_interior/modules/sh_interior_lights.lua +++ /dev/null @@ -1,717 +0,0 @@ --- Lights - --- Convar - -CreateConVar("tardis2_debug_lamps", 0, {FCVAR_ARCHIVE}, "TARDIS - enable debugging interior lamps") -TARDIS.debug_lamps_enabled = GetConVar("tardis2_debug_lamps"):GetBool() - - - --- Dynamic lights - -local function ParseLightTable(lt, interior, default_falloff) - if SERVER then return end - - if not lt then return end - - lt.falloff = lt.falloff or default_falloff - -- default falloff values were taken from cl_render.lua::predraw_o - - if lt.warncolor then - lt.warn_color = lt.warncolor - lt.warncolor = nil - end - - lt.warn_color = lt.warn_color or lt.color - lt.warn_pos = lt.warn_pos or lt.pos - lt.warn_brightness = lt.warn_brightness or lt.brightness - lt.warn_falloff = lt.warn_falloff or lt.falloff - - if lt.nopower then - lt.off_color = lt.off_color or lt.color - lt.off_pos = lt.off_pos or lt.pos - lt.off_brightness = lt.off_brightness or lt.brightness - lt.off_falloff = lt.off_falloff or lt.falloff - - -- defaulting `off + warn` to `off` unless specified otherwise - lt.off_warn_color = lt.off_warn_color or lt.off_color - lt.off_warn_pos = lt.off_warn_pos or lt.off_pos - lt.off_warn_brightness = lt.off_warn_brightness or lt.off_brightness - lt.off_warn_falloff = lt.off_warn_falloff or lt.off_falloff - end - - -- optimize calculations in `cl_render.lua::predraw_o` - lt.color_vec = lt.color:ToVector() * lt.brightness - lt.pos_global = interior:LocalToWorld(lt.pos) - - lt.warn_color_vec = lt.warn_color:ToVector() * lt.warn_brightness - lt.warn_pos_global = interior:LocalToWorld(lt.warn_pos) - - if lt.nopower then - lt.off_pos_global = interior:LocalToWorld(lt.off_pos) - lt.off_color_vec = lt.off_color:ToVector() * lt.off_brightness - - lt.off_warn_pos_global = interior:LocalToWorld(lt.off_warn_pos) - lt.off_warn_color_vec = lt.off_warn_color:ToVector() * lt.off_warn_brightness - end - - lt.render_table = { - type = MATERIAL_LIGHT_POINT, - color = lt.color_vec, - pos = lt.pos_global, - quadraticFalloff = lt.falloff, - } - lt.warn_render_table = { - type = MATERIAL_LIGHT_POINT, - color = lt.warn_color_vec, - pos = lt.warn_pos_global, - quadraticFalloff = lt.warn_falloff, - } - - if lt.nopower then - lt.off_render_table = { - type = MATERIAL_LIGHT_POINT, - color = lt.off_color_vec, - pos = lt.off_pos_global, - quadraticFalloff = lt.off_falloff, - } - lt.off_warn_render_table = { - type = MATERIAL_LIGHT_POINT, - color = lt.off_warn_color_vec, - pos = lt.off_warn_pos_global, - quadraticFalloff = lt.off_warn_falloff, - } - else - lt.off_render_table = {} - lt.off_warn_render_table = {} - end -end - -if CLIENT then - local function MergeLightTable(tbl, base) - local new_table = TARDIS:CopyTable(base) - if not tbl then return new_table end - - new_table.NoLO = nil - new_table.NoExtra = nil - new_table.NoExtraNoLO = nil - - table.Merge(new_table, tbl) - return new_table - end - - function ENT:LoadLights() - local noLO = not TARDIS:GetSetting("lightoverride-enabled") - local noExtra = not TARDIS:GetSetting("extra-lights") - - local int_metadata = self.metadata.Interior - local light = int_metadata.Light - local lights = int_metadata.Lights - - local light_alt - - if noLO and noExtra then - light_alt = light.NoExtraNoLO or light.NoLO - elseif noLO then - light_alt = light.NoLO - elseif noExtra then - light_alt = light.NoExtra - end - - self.light_data = { - main = MergeLightTable(light_alt, light), - extra = {}, - } - ParseLightTable(self.light_data.main, self, 20) - - if not lights then return end - for k,v in pairs(lights) do - if v and istable(v) then - local v_alt - if noLO then - v_alt = v.NoLO - end - self.light_data.extra[k] = MergeLightTable(v_alt, v) - ParseLightTable(self.light_data.extra[k], self, 10) - end - end - end - - ENT:AddHook("Initialize", "lights", function(self) - self:LoadLights() - end) - - ENT:AddHook("SettingChanged", "lights", function(self, id, val) - if id ~= "lightoverride-enabled" and id ~= "extra-lights" then return end - self:LoadLights() - end) - - function ENT:DrawLight(id,light) - if self:CallHook("ShouldDrawLight",id,light)==false then return end - - local dlight = DynamicLight(id, true) - if not dlight then return end - - local warning = self:GetData("warning", false) - local power = self:GetPower() - - if not power and warning then - dlight.Pos = light.off_warn_pos_global - dlight.r = light.off_warn_color.r - dlight.g = light.off_warn_color.g - dlight.b = light.off_warn_color.b - dlight.Brightness = light.off_warn_brightness - elseif not power then - dlight.Pos = light.off_pos_global - dlight.r = light.off_color.r - dlight.g = light.off_color.g - dlight.b = light.off_color.b - dlight.Brightness = light.off_brightness - elseif warning then - dlight.Pos = light.warn_pos_global - dlight.r = light.warn_color.r - dlight.g = light.warn_color.g - dlight.b = light.warn_color.b - dlight.Brightness = light.warn_brightness - else -- power & no warning - dlight.Pos = light.pos_global - dlight.r = light.color.r - dlight.g = light.color.g - dlight.b = light.color.b - dlight.Brightness = light.brightness - end - - dlight.Decay = 5120 - dlight.Size = 1024 - dlight.DieTime = CurTime() + 1 - end - - ENT:AddHook("Think", "lights", function(self) - if TARDIS:GetSetting("lightoverride-enabled") then return end - local light = self.light_data.main - local lights = self.light_data.extra - local index=self:EntIndex() - if light then - self:DrawLight(index,light) - end - if lights and TARDIS:GetSetting("extra-lights") then - local i=0 - for _,light in pairs(lights) do - i=i+1 - self:DrawLight((index*1000)+i,light) - end - end - end) - - ENT:AddHook("ShouldDrawLight", "interior_light_enabled", function(self,id,light) - if light and light.enabled == false then return false end - -- allow disabling lights with light states - end) -end - - - --- Lamps (projected lights) - -if CLIENT then - local function MergeLampTable(tbl, base, keep_warn_off_options) - if not tbl then return nil end - - local new_table = TARDIS:CopyTable(base) - new_table.states = nil - if not keep_warn_off_options then - new_table.warn = nil - new_table.off = nil - new_table.off_warn = nil - end - table.Merge(new_table, tbl) - return new_table - end - - local function ParseLampTable(lmp) - if not lmp then return end - if lmp.parsed == true then return end - - lmp.texture = lmp.texture or "effects/flashlight/soft" - lmp.pos = lmp.pos or Vector(0,0,0) - lmp.ang = lmp.ang or Angle(0,0,0) - lmp.fov = lmp.fov or 90 - lmp.color = lmp.color or Color(255,255,255) - lmp.brightness = lmp.brightness or 3.0 - lmp.distance = lmp.distance or 1024 - lmp.shadows = lmp.shadows or false - - lmp.warn = MergeLampTable(lmp.warn, lmp, false) - lmp.off = MergeLampTable(lmp.off, lmp, false) - lmp.off_warn = MergeLampTable(lmp.off_warn, lmp.off or lmp, false) - - if lmp.states then - for k,v in pairs(lmp.states) do - lmp.states[k] = MergeLampTable(v, lmp, true) - end - end - - lmp.parsed = true - end - - function ENT:InitLampData(lmp) - if not lmp or not lmp.pos then return end - lmp.pos_global = self:LocalToWorld(lmp.pos) - if lmp.sprite then - lmp.spritepixvis = util.GetPixelVisibleHandle() - lmp.sprite_brightness = lmp.sprite_brightness or 1 - end - self:InitLampData(lmp.warn) - self:InitLampData(lmp.off) - self:InitLampData(lmp.off_warn) - - if not lmp.states then return end - for k,v in pairs(lmp.states) do - self:InitLampData(v) - end - end - - function ENT:LoadLamps() - local lamps = self.metadata.Interior.Lamps - if not lamps then return end - - self.lamps_data = {} - - for k,v in pairs(lamps) do - ParseLampTable(v) -- only once per metadata - local this_lamp = TARDIS:CopyTable(v) - self:InitLampData(this_lamp) - self.lamps_data[k] = this_lamp - end - end - - ENT:AddHook("Initialize", "lamps", function(self) - self:LoadLamps() - self:CreateLamps() - self:RunLampUpdate() - end) - - function ENT:CreateLamp(lmp) - if not lmp then return end - if lmp.enabled == false then return end - local pl = ProjectedTexture() - pl:SetTexture(lmp.texture) - pl:SetPos(lmp.pos_global) - pl:SetAngles(lmp.ang) - pl:SetFOV(lmp.fov) - pl:SetColor(lmp.color) - pl:SetBrightness(lmp.brightness) - pl:SetFarZ(lmp.distance) - pl:SetEnableShadows(lmp.shadows) - pl:Update() - return pl - end - - local function SelectLampTable(self, lmp) - local state = self:GetData("light_state") - local warning = self:GetData("warning", false) - local power = self:GetPower() - local l = lmp - - if lmp and lmp.states then - l = lmp.states[state] or l - end - - if not power and lmp.nopower ~= true then - return nil - end - - if not power and warning then - l = l.off_warn or l - elseif not power then - l = l.off or l - elseif warning then - l = l.warn or l - end - - return l - end - - function ENT:CreateLamps() - if not TARDIS:GetSetting("lamps-enabled") then return end - if TARDIS.debug_lamps_enabled then return end - if not self.lamps_data then return end - - self.lamps = {} - for k,v in pairs(self.lamps_data) do - self.lamps[k] = self:CreateLamp(SelectLampTable(self, v)) - end - end - - function ENT:RemoveLamps() - if not self.lamps then return end - for k,v in pairs(self.lamps) do - if IsValid(v) then - v:Remove() - end - end - self.lamps = nil - end - - local function ReplaceLamps(self) - if not TARDIS:GetSetting("lamps-enabled") then return end - self:RemoveLamps() - self:CreateLamps() - self:RunLampUpdate() - end - - ENT:AddHook("LightStateChanged", "lamps", ReplaceLamps) - - ENT:AddHook("PowerToggled", "lamps", ReplaceLamps) - - ENT:AddHook("WarningToggled", "lamps", ReplaceLamps) - - - function ENT:RunLampUpdate() - if not TARDIS:GetSetting("lamps-enabled") then return end - if not self.lamps then return end - - self.lamps_need_updating = true - - self:Timer("lamps_update_stop", 0.3, function() - self.lamps_need_updating = false - end) - end - - ENT:AddHook("Think", "lamps_updates", function(self) - if not self.lamps_need_updating then return end - - if not TARDIS:GetSetting("lamps-enabled") then return end - if not self.lamps then return end - - for k,v in pairs(self.lamps) do - if IsValid(v) then - v:Update() - end - end - end) - - local matLight = Material("sprites/light_ignorez") - ENT:AddHook("Draw", "lamps", function(self) - if not TARDIS:GetSetting("lamps-enabled") then return end - if not self.lamps_data then return end - - for k,v in pairs(self.lamps_data) do - local data = SelectLampTable(self, v) - if not data then return end - if data.sprite then - -- adapted from https://github.com/Facepunch/garrysmod/blob/master/garrysmod/gamemodes/sandbox/entities/entities/gmod_lamp.lua - - local lightPos = data.pos_global - local viewNormal = lightPos - EyePos() - local distance = viewNormal:Length() - - render.SetMaterial( matLight ) - local visible = util.PixelVisible(lightPos, 16, data.spritepixvis) - if not visible then return end - - local size = math.Clamp(distance * visible * 2, 64, 512) - - distance = math.Clamp(distance, 32, 800) - local alpha = math.Clamp((1000 - distance) * visible * data.sprite_brightness, 0, 100) - - render.DrawSprite(lightPos, size, size, ColorAlpha(data.color, alpha)) - render.DrawSprite(lightPos, size * 0.4, size * 0.4, Color( 255, 255, 255, alpha )) - end - end - end) - - - ENT:AddHook("SettingChanged", "lamps", function(self, id, val) - if id ~= "lamps-enabled" then return end - - if val and self.lamps == nil then - self:CreateLamps() - self:RunLampUpdate() - elseif not val and self.lamps then - self:RemoveLamps() - end - end) - - ENT:AddHook("PostInitialize", "lamps", function(self) - self:RunLampUpdate() - end) - - ENT:AddHook("ToggleDoor", "lamps", function(self) - self:RunLampUpdate() - end) - - ENT:AddHook("PlayerEnter", "lamps", function(self) - self:RunLampUpdate() - end) - - ENT:AddHook("OnRemove", "lamps", function(self) - self:RemoveLamps() - end) -end - - - --- Light states - -local function ChangeSingleLightState(light_table, state) - local new_state = light_table.states and light_table.states[state] - if not new_state then return end - table.Merge(light_table, new_state) -end - -function ENT:ApplyLightState(state) - self:SetData("light_state", state) - self:CallHook("LightStateChanged", state) - - if SERVER then - self:SendMessage("light_state", {state} ) - else - local ldata = self.light_data - ChangeSingleLightState(ldata.main, state) - ParseLightTable(ldata.main, self, 20) - - for k,v in pairs(ldata.extra) do - ChangeSingleLightState(v, state) - ParseLightTable(v, self, 10) - end - end -end - -if CLIENT then - ENT:OnMessage("light_state", function(self, data, ply) - self:ApplyLightState(data[1]) - end) -end - - --- Debug Lamps (a way for developers to set up the projected lights) - -if SERVER then - - util.AddNetworkString("TARDIS-DebugLampsToggled") - cvars.AddChangeCallback("tardis2_debug_lamps", function() - TARDIS.debug_lamps_enabled = GetConVar("tardis2_debug_lamps"):GetBool() - net.Start("TARDIS-DebugLampsToggled") - net.WriteBool(TARDIS.debug_lamps_enabled) - net.Broadcast() - -- It was required to manually code networking for this convar - -- AddChangeCallback doesn't callback client convars with FCVAR_REPLICATED - -- Details: https://github.com/Facepunch/garrysmod-issues/issues/3740 - end) - - ENT:AddHook("Initialize", "debug_lamps", function(self) - if not TARDIS.debug_lamps_enabled then return end - - local lamps = self.metadata.Interior.Lamps - if not lamps then return end - - self.debug_lamps = {} - - for k,v in pairs(lamps) do - if v then - if not v.color then - v.color = Color(255,255,255) - end - local lamp = MakeLamp(nil, -- creator - v.color.r, v.color.g, v.color.b, - KEY_NONE, -- toggle key - true, -- toggle - v.texture or "effects/flashlight/soft", -- projected texture - "models/maxofs2d/lamp_projector.mdl", -- lamp model - v.fov or 90, - v.distance or 1024, - v.brightness or 3.0, - true, -- enabled - { - Pos = self:LocalToWorld(v.pos or Vector(0,0,0)), - Angle = v.ang or Angle(0,0,0), - } - ) - - lamp:SetUnFreezable(false) - lamp:GetPhysicsObject():EnableGravity(false) - lamp:GetPhysicsObject():EnableMotion(false) - - lamp:SetUseType(SIMPLE_USE) - lamp.Use = function(lamp, ply) - local clr = lamp:GetColor() - local pos = self:WorldToLocal(lamp:GetPos()) - local ang = lamp:GetAngles() - - print("{\n\tcolor = Color(" .. clr.r .. ", " .. clr.g .. ", " .. clr.b .. "),") - print("\ttexture = \"" .. lamp:GetFlashlightTexture() .. "\",") - print("\tfov = " .. lamp:GetLightFOV() .. ",") - print("\tdistance = " .. lamp:GetDistance() .. ",") - print("\tbrightness = " .. lamp:GetBrightness() .. ",") - print("\tpos = Vector(" .. pos.x .. ", " .. pos.y .. ", " .. pos.z .. "),") - print("\tang = Angle(" .. ang.x .. ", " .. ang.y .. ", " .. ang.z .. "),") - print("},") - end - lamp:SetCollisionGroup(COLLISION_GROUP_WORLD) - - lamp.lamp_data = v - - table.insert(self.debug_lamps, lamp) - end - end - end) - - ENT:AddHook("OnRemove", "debug_lamps", function(self) - if not self.debug_lamps then return end - for k,v in pairs(self.debug_lamps) do - if IsValid(v) then - v:Remove() - end - end - end) - - ENT:AddHook("PowerToggled", "debug_lamps", function(self, on) - if not self.debug_lamps then return end - - for k,v in pairs(self.debug_lamps) do - if IsValid(v) and v.lamp_data.nopower ~= true then - v:SetOn(on) - end - end - end) -else - net.Receive("TARDIS-DebugLampsToggled", function() - TARDIS.debug_lamps_enabled = net.ReadBool() - end) -end - --- Round things (light sprites for old default interior) -if CLIENT then - function ENT:AddRoundThing(pos) - self.roundthings[pos]=util.GetPixelVisibleHandle() - end - - ENT:AddHook("Initialize", "lights-roundthings", function(self) - if self.metadata.Interior.RoundThings then - self.roundthingmat=Material("sprites/light_ignorez") - self.roundthings={} - for k,v in pairs(self.metadata.Interior.RoundThings) do - self:AddRoundThing(v) - end - end - end) - - local size=32 - ENT:AddHook("Draw", "lights-roundthings", function(self) - if self.roundthings then - if self:CallHook("ShouldDrawLight")==false then return end - for k,v in pairs(self.roundthings) do - local pos = self:LocalToWorld(k) - local vis = util.PixelVisible(pos, 3, v)*255 - if vis > 0 then - render.SetMaterial(self.roundthingmat) - render.DrawSprite(pos, size, size, Color(255,153,0, vis)) - end - end - end - end) -end - -if CLIENT then - ENT:AddHook("SlowThink", "lights", function(self) - local pos = self:GetPos() - if self.lights_lastpos == pos then return end - if self.lights_lastpos ~= nil then - self:LoadLights() - self:LoadLamps() - self:CreateLamps() - end - self.lights_lastpos = pos - end) -end - --- Base light - -function ENT:GetCustomBaseLightEnabled() - return self:GetData("interior_custom_base_light_enabled", false) -end - -function ENT:GetCustomBaseLightColor() - return self:GetData("interior_custom_base_light_color") -end - -function ENT:GetGetBaseLightColorVector() - return self:GetData("interior_base_light_color_vec") -end - -function ENT:GetCustomBaseLightBrightness() - return self:GetData("interior_custom_base_light_brightness") -end - - -if SERVER then - function ENT:SetCustomBaseLightEnabled(enabled) - self:SetData("interior_custom_base_light_enabled", enabled or false, true) - end - - function ENT:ToggleCustomBaseLightEnabled() - self:SetCustomBaseLightEnabled(not self:GetCustomBaseLightEnabled()) - end - - function ENT:SetCustomBaseLightColor(color) - self:SetData("interior_custom_base_light_color", color, true) - end - - function ENT:SetCustomBaseLightBrightness(brightness) - self:SetData("interior_custom_base_light_brightness", brightness, true) - end -else - function ENT:GetBaseLightColorVector() - return self:GetData("interior_base_light_color_vec", TARDIS.color_white_vector) - end - - function ENT:GetBaseLightColor() - return self:GetBaseLightColorVector():ToColor() - end - - ENT:AddHook("Think", "baselight", function(self) - local lo = self.metadata.Interior.LightOverride - if not lo then return end - - local power = self:GetPower() - - local normalbr = power and lo.basebrightness or lo.nopowerbrightness - local normalcolvec = power and lo.basebrightnessRGB or lo.nopowerbrightnessRGB or TARDIS.color_white_vector - - local customcol = self:GetData("interior_custom_base_light_color") - local custombr = self:GetData("interior_custom_base_light_brightness", normalbr) - - local currentcolvec = self:GetData("interior_base_light_color_vec") - local targetcolvec - if self:GetData("interior_custom_base_light_enabled") and customcol then - targetcolvec = customcol:ToVector() * (custombr or normalbr) - else - targetcolvec = normalcolvec * normalbr - end - - if currentcolvec == targetcolvec then - return - elseif not currentcolvec then - self:SetData("interior_base_light_color_vec", targetcolvec) - return - end - - local savedtargetcolvec = self:GetData("interior_base_light_target_color_vec") - - if savedtargetcolvec ~= targetcolvec then - self:SetData("interior_base_light_target_color_vec", targetcolvec) - self:SetData("interior_base_light_previous_color_vec", currentcolvec) - self:SetData("interior_base_light_transition_fraction", 0) - end - - local prevcolvec = self:GetData("interior_base_light_previous_color_vec", currentcolvec) - local fraction = self:GetData("interior_base_light_transition_fraction", 0) - fraction = math.min(fraction + (FrameTime() * self.metadata.Interior.LightOverride.transitionspeed), 1) - - local colvec = LerpVector(fraction, prevcolvec, targetcolvec) - - self:SetData("interior_base_light_color_vec", colvec) - self:SetData("interior_base_light_transition_fraction", fraction) - end) -end \ No newline at end of file diff --git a/lua/entities/gmod_tardis_interior/modules/sh_lighting.lua b/lua/entities/gmod_tardis_interior/modules/sh_lighting.lua new file mode 100644 index 000000000..2b9da52b9 --- /dev/null +++ b/lua/entities/gmod_tardis_interior/modules/sh_lighting.lua @@ -0,0 +1,2 @@ +-- Loading folder with teleport-related features +ENT:LoadFolder("modules/lighting") diff --git a/lua/entities/gmod_tardis_interior/shared.lua b/lua/entities/gmod_tardis_interior/shared.lua index 08cf4d336..08dca2bc6 100644 --- a/lua/entities/gmod_tardis_interior/shared.lua +++ b/lua/entities/gmod_tardis_interior/shared.lua @@ -105,4 +105,21 @@ function ENT:LoadFolder(folder,addonly,noprefix) end ENT:LoadFolder("modules/libraries") -ENT:LoadFolder("modules") \ No newline at end of file + +if SERVER then + function ENT:CallClientHook(name, ...) + self:SendMessage("client_hook", {name, ...}) + end + function ENT:CallClientCommonHook(name, ...) + self:SendMessage("client_common_hook", {name, ...}) + end +else + ENT:OnMessage("client_hook", function(self, data, ply) + self:CallHook(unpack(data)) + end) + ENT:OnMessage("client_common_hook", function(self, data, ply) + self:CallCommonHook(unpack(data)) + end) +end + +ENT:LoadFolder("modules") diff --git a/lua/matproxy/matproxy_tardis.lua b/lua/matproxy/matproxy_tardis.lua index 41b851f8c..d86ac1091 100644 --- a/lua/matproxy/matproxy_tardis.lua +++ b/lua/matproxy/matproxy_tardis.lua @@ -1,12 +1,26 @@ matproxy.Add({ - name = "TARDIS_State", + name = "TARDIS_State_Texture", init = function(self, mat, values) self.Texture = values.resulttexturevar self.FrameNo = values.resultframevar - self.Textures = table.Copy(values.textures) - self.FrameRates = table.Copy(values.framerates) + self.Textures = {} + self.FrameRates = {} + + for k,v in pairs(values.textures) do + if values.textures[v] then + v = values.textures[v] + end + if istable(v) then + local texture = table.GetKeys(v)[1] + self.Textures[k] = texture + self.FrameRates[k] = v[texture] + else + self.Textures[k] = v + self.FrameRates[k] = 0 + end + end self.AnimateTextures = {} self.FrameDurations = {} @@ -20,8 +34,8 @@ matproxy.Add({ end end - self.next_frame_update = RealTime() - self.last_frame_update = RealTime() + self.next_update = RealTime() + self.last_update = RealTime() self.current_frame = 0 end, @@ -30,59 +44,41 @@ matproxy.Add({ local ext = ent.exterior if not IsValid(ext) then return end - local function get_base_mat_name() - if not ext:GetPower() then - return "off" - elseif ext:GetData("demat_animation") then - return "demat" - elseif ext:GetData("mat_animation") then - return "mat" - elseif ext:GetData("failing-demat") then - return "demat_fail" - elseif ext:GetData("failing-mat") then - return "mat_fail" - elseif ext:GetData("demat-interrupted") then - return "interrupt" - elseif ext:GetHandbrake() then - return "handbrake" - elseif ext:IsTravelling() then - return "travel" - end - - return "idle" - end + local s = ext:GetState() - local m = get_base_mat_name() + if s ~= self.last_state then + self.last_state = s - if ext:GetWarning() then - m = m .. "_warning" - end + if not self.Textures or not self.Textures[s] then return end - if not self.Textures or not self.Textures[m] then return end + if mat:GetTexture(self.Texture):GetName() ~= self.Textures[s] then + mat:SetTexture(self.Texture, self.Textures[s]) + end - if mat:GetTexture(self.Texture):GetName() ~= self.Textures[m] then - mat:SetTexture(self.Texture, self.Textures[m]) + if self.AnimateTextures[s] then + self.anim = true + self.anim_num_frames = mat:GetTexture(self.Texture):GetNumAnimationFrames() + self.anim_frame_rate = self.FrameRates[s] + self.anim_frame_dur = self.FrameDurations[s] + else + self.anim = false + self.current_frame = 0 + mat:SetInt(self.FrameNo, 0) + end end - if self.AnimateTextures[m] then - local num_frames = mat:GetTexture(self.Texture):GetNumAnimationFrames() + if self.anim then local time = RealTime() - if time > self.next_frame_update then - local time_past = time - self.last_frame_update - local frames_past = math.floor(time_past / self.FrameDurations[m]) + if time > self.next_update then + local frames_past = math.floor((time - self.last_update) * self.anim_frame_rate) + self.current_frame = (self.current_frame + frames_past) % self.anim_num_frames - self.current_frame = (self.current_frame + frames_past) % num_frames + self.last_update = time + self.next_update = time + self.anim_frame_dur - self.last_frame_update = time - self.next_frame_update = time + self.FrameDurations[m] + mat:SetInt(self.FrameNo, self.current_frame) end - else - self.current_frame = 0 - end - - if mat:GetInt(self.FrameNo) ~= self.current_frame then - mat:SetInt(self.FrameNo, self.current_frame) end end }) @@ -96,10 +92,16 @@ end local function matproxy_tardis_power_bind(self, mat, ent) if not IsValid(ent) or not IsValid(ent.exterior) or not ent.TardisPart then return end - local var = ent.exterior:GetPower() and self.on_var or self.off_var - if not var then return end + local on = ent.exterior:GetPower() - mat:SetVector(self.ResultTo, mat:GetVector(var)) + if self.last_on ~= on then + self.last_on = on + + local var = on and self.on_var or self.off_var + if not var then return end + + mat:SetVector(self.ResultTo, mat:GetVector(var)) + end end matproxy.Add({ diff --git a/lua/matproxy/matproxy_tardis_default_int.lua b/lua/matproxy/matproxy_tardis_default_int.lua index 860401b60..4d942c856 100644 --- a/lua/matproxy/matproxy_tardis_default_int.lua +++ b/lua/matproxy/matproxy_tardis_default_int.lua @@ -9,13 +9,19 @@ matproxy.Add({ if not IsValid(ent) or not ent.TardisPart then return end local col = ent:GetData("default_int_env_color") or Color(0,200,255) - col = Color(col.r, col.g, col.b):ToVector() + local power = ent.exterior and ent.exterior:GetPower() - if ent.exterior and not ent.exterior:GetPower() then - col = col * 0.1 - end + if self.lastcol ~= col or self.lastpower ~= power then + self.lastcol = col + self.lastpower = power + + col = Color(col.r, col.g, col.b):ToVector() + if not power then + col = col * 0.1 + end - mat:SetVector( self.ResultTo, col); + mat:SetVector(self.ResultTo, col); + end end }) @@ -31,9 +37,12 @@ matproxy.Add({ local col = ent:GetData("default_int_floor_lights_color") or Color(230,230,210) - col = Color(col.r, col.g, col.b):ToVector() + if self.lastcol ~= col then + self.lastcol = col - mat:SetVector( self.ResultTo, col); + col = Color(col.r, col.g, col.b):ToVector() + mat:SetVector(self.ResultTo, col); + end end }) @@ -49,8 +58,12 @@ matproxy.Add({ local col = ent:GetData("default_int_rotor_color") or Color(255,255,255) - col = Color(col.r, col.g, col.b):ToVector() - mat:SetVector( self.ResultTo, col); + if self.lastcol ~= col then + self.lastcol = col + + col = Color(col.r, col.g, col.b):ToVector() + mat:SetVector(self.ResultTo, col) + end end }) @@ -78,7 +91,9 @@ matproxy.Add({ return end - mat:SetFloat(self.ResultTo, 0) + if mat:GetFloat(self.ResultTo) ~= 0 then + mat:SetFloat(self.ResultTo, 0) + end end }) @@ -93,10 +108,15 @@ matproxy.Add({ bind = function(self, mat, ent) if not IsValid(ent) or not IsValid(ent.exterior) or not ent.TardisPart then return end - local var = ent:GetData("default_sonic_charger_active") and self.on_var or self.off_var - if not var then return end + local active = ent:GetData("default_sonic_charger_active") + + if active ~= self.last_active then + self.last_active = active + local var = active and self.on_var or self.off_var + if not var then return end - mat:SetVector(self.ResultTo, mat:GetVector(var)) + mat:SetVector(self.ResultTo, mat:GetVector(var)) + end end, }) @@ -116,10 +136,13 @@ matproxy.Add({ self.off_var3 = values.offvar3 end, bind = function(self, mat, ent) - if not IsValid(ent) or not IsValid(ent.interior) or not ent.TardisPart or ent.ID ~= "default_throttle_lights" then - mat:SetVector(self.ResultTo, mat:GetVector(self.on_var)) - mat:SetVector(self.ResultTo2, mat:GetVector(self.on_var2)) - mat:SetVector(self.ResultTo3, mat:GetVector(self.on_var3)) + if not IsValid(ent) or not ent.TardisPart or not IsValid(ent.interior) or ent.ID ~= "default_throttle_lights" then + if not self.last_on then + self.last_on = true + mat:SetVector(self.ResultTo, mat:GetVector(self.on_var)) + mat:SetVector(self.ResultTo2, mat:GetVector(self.on_var2)) + mat:SetVector(self.ResultTo3, mat:GetVector(self.on_var3)) + end return end @@ -127,14 +150,18 @@ matproxy.Add({ if not IsValid(throttle) then return end local on = throttle:GetOn() - local var = on and self.on_var or self.off_var - local var2 = on and self.on_var2 or self.off_var2 - local var3 = on and self.on_var3 or self.off_var3 - if not var or not var2 or not var3 then return end - - mat:SetVector(self.ResultTo, mat:GetVector(var)) - mat:SetVector(self.ResultTo2, mat:GetVector(var2)) - mat:SetVector(self.ResultTo3, mat:GetVector(var3)) + + if on ~= self.last_on then + self.last_on = on + local var = on and self.on_var or self.off_var + local var2 = on and self.on_var2 or self.off_var2 + local var3 = on and self.on_var3 or self.off_var3 + if not var or not var2 or not var3 then return end + + mat:SetVector(self.ResultTo, mat:GetVector(var)) + mat:SetVector(self.ResultTo2, mat:GetVector(var2)) + mat:SetVector(self.ResultTo3, mat:GetVector(var3)) + end end, }) diff --git a/lua/tardis/interiors/base.lua b/lua/tardis/interiors/base.lua index b65b74778..9d55a338e 100644 --- a/lua/tardis/interiors/base.lua +++ b/lua/tardis/interiors/base.lua @@ -178,9 +178,11 @@ T.Exterior = { } } T.Timings = { - DematInterrupt = 1, + DematAbortState = 1, DematFail = 4, MatFail = 8, + TakeOffState = 0, + ParkingState = 0, } TARDIS:AddInterior(T) diff --git a/lua/tardis/interiors/default.lua b/lua/tardis/interiors/default.lua index 62fdfffd0..de46eec5a 100644 --- a/lua/tardis/interiors/default.lua +++ b/lua/tardis/interiors/default.lua @@ -23,7 +23,7 @@ T.Interior = { Min = Vector(-585.336, -1378.008, -33.179), Max = Vector(892.477, 457.64, 381.653) }, - + ExitBox = { Min = Vector(-659.914, -1364.271, -104.82), Max = Vector(984.983, 514.944, 385.095) @@ -490,48 +490,12 @@ T.Exterior = { } T.Timings = { - DematInterrupt = 3, - DematStartingAnimation = 3, - MatStoppingAnimation = 3.2, + DematAbortState = 3, + TakeOffState = 3, + ParkingState = 3.2, } T.CustomHooks = { - fast_top_bulbs = { - exthooks = { - ["DematStart"] = true, - ["StopMat"] = true, - }, - func = function(ext,int) - if SERVER then return end - if not IsValid(int) then return end - - local time, data - - if ext:GetData("demat") then - time = ext.metadata.Timings.DematStartingAnimation - data = "demat_animation" - else - time = ext.metadata.Timings.MatStoppingAnimation - data = "mat_animation" - end - - int:SetData(data, true) - int:Timer(data, time, function() - int:SetData(data, nil) - end) - end, - }, - fast_top_bulbs_handbrake = { - inthooks = { - ["HandbrakeToggled"] = true, - }, - func = function(ext,int,on) - if CLIENT and on and IsValid(int) and int:GetData("mat_animation") then - int:CancelTimer("mat_animation") - int:SetData("mat_animation", nil) - end - end, - }, screen_disable = { inthooks = { ["ShouldNotDrawScreen"] = true, @@ -563,7 +527,6 @@ T.CustomHooks = { end end, }, - } @@ -623,13 +586,8 @@ T.CustomSettings = { }, lamps = { text = "Interiors.Default.CustomSettings.Lamps", - value_type = "list", - value = false, - options = { - [false] = "Interiors.Default.CustomSettings.Lamps.Off", - ["few"] = "Interiors.Default.CustomSettings.Lamps.Few", - ["many"] = "Interiors.Default.CustomSettings.Lamps.Many", - }, + value_type = "bool", + value = true, }, small_version = { text = "Interiors.Default.CustomSettings.SmallVersion", @@ -653,13 +611,7 @@ T.Templates = { default_lamps = { override = true, condition = function(id, ply, ent) - return (TARDIS:GetCustomSetting(id, "lamps", ply) ~= false) - end, - }, - default_more_lamps = { - override = true, - condition = function(id, ply, ent) - return (TARDIS:GetCustomSetting(id, "lamps", ply) == "many") + return TARDIS:GetCustomSetting(id, "lamps", ply) end, }, default_dynamic_color = { @@ -696,6 +648,14 @@ T.Templates = { return not TARDIS:GetCustomSetting(id, "screens_off", ply) end, }, + default_small_version_lamp_fix= { + override = true, + condition = function(id, ply, ent) + local lamps = TARDIS:GetCustomSetting(id, "lamps", ply) + local small = TARDIS:GetCustomSetting(id, "small_version", ply) + return (lamps and small) + end, + }, } T.TemplatesMergeOrder = { "default_lamps", diff --git a/lua/tardis/interiors/templates/templates_default_interior.lua b/lua/tardis/interiors/templates/templates_default_interior.lua index 7a7dad662..c67499fb5 100644 --- a/lua/tardis/interiors/templates/templates_default_interior.lua +++ b/lua/tardis/interiors/templates/templates_default_interior.lua @@ -1,52 +1,8 @@ -local function generate_lamps(n, l_brightness, l_fov) - local lp = Vector(197, 0, 340) - local la = Angle(86.8, 0, 90) - local up = Vector(0,0,1) - - local v0 = Vector(0,0,0) - local a0 = Angle(0,0,0) - - local ra = 360 / n - - local lamp_positions = {} - for i = 1,n do - lamp_positions[i] = { pos = v0 + lp, ang = a0 + la, } - lp:Rotate(Angle(0,ra,0)) - la:RotateAroundAxis(up, ra) - end - - local lamps = {} - - for i = 1,n do - lamps[i] = { - color = Color(255, 255, 230), - texture = "effects/flashlight/soft", - fov = l_fov, - distance = 290, - brightness = l_brightness, - shadows = false, - pos = lamp_positions[i].pos, - ang = lamp_positions[i].ang, - warn = { - brightness = l_brightness * 0.5, - }, - states = { - ["normal"] = { - enabled = true, - brightness = l_brightness, - }, - ["moving"] = { - enabled = false, - }, - }, - } - end - - return lamps -end - TARDIS:AddInteriorTemplate("default_lamps", { Interior = { + Size = { + Max = Vector(892.477, 457.64, 800) + }, LightOverride = { basebrightness = 0.01, parts = { @@ -60,7 +16,22 @@ TARDIS:AddInteriorTemplate("default_lamps", { default_rings = 0.001, }, }, - Lamps = generate_lamps(5, 0.6, 165), + Lamps = { + { + color = Color(255, 255, 230), + texture = "effects/flashlight/soft", + fov = 170, + distance = 751, + brightness = 5, + pos = Vector(0, 0, 790), + ang = Angle(90, 90, 180), + shadows = false, + states = { + ["normal"] = { enabled = true, }, + ["moving"] = { enabled = false, }, + }, + }, + }, Light={ brightness = 5, warn_brightness = 4, @@ -103,12 +74,6 @@ TARDIS:AddInteriorTemplate("default_lamps", { }, }) -TARDIS:AddInteriorTemplate("default_more_lamps", { - Interior = { - Lamps = generate_lamps(9, 0.5, 150), - }, -}) - TARDIS:AddInteriorTemplate("default_dynamic_color", { CustomHooks = { int_color = { @@ -229,7 +194,15 @@ TARDIS:AddInteriorTemplate("default_color_update", { TARDIS:AddInteriorTemplate("default_small_version", { Interior = { - ExitDistance = 600, + Size = { + Min = Vector(-555.742, -461.072, 0), + Max = Vector(388.574, 371.054, 381.653), + }, + ExitBox = { + Min = Vector(-659.914, -564.271, -50), + Max = Vector(484.983, 514.944, 385.095), + }, + Parts = { default_rotor = { model = "models/molda/toyota_int/rotor_small.mdl", @@ -244,6 +217,14 @@ TARDIS:AddInteriorTemplate("default_small_version", { }, }) +TARDIS:AddInteriorTemplate("default_small_version_lamp_fix", { + Interior = { + Size = { + Max = Vector(484.983, 514.944, 800) + }, + }, +}) + TARDIS:AddInteriorTemplate("default_screens_off", { CustomHooks = { screens_init = { diff --git a/lua/tardis/metadata/sh_versions.lua b/lua/tardis/metadata/sh_versions.lua index 061900f59..c68d8a19f 100644 --- a/lua/tardis/metadata/sh_versions.lua +++ b/lua/tardis/metadata/sh_versions.lua @@ -96,7 +96,13 @@ function TARDIS:SelectSpawnID(id, ent) version = id end - return TARDIS:SelectDoorVersionID(version, ent) + version = TARDIS:SelectDoorVersionID(version, ent) + + if not self.Metadata[version] then + version = TARDIS:SelectDoorVersionID(versions.main, ent) + end + + return version end function TARDIS:GetMainVersionId(int_id) diff --git a/lua/tardis/screens/cl_screenbutton.lua b/lua/tardis/screens/cl_screenbutton.lua index 1c3f5507f..eef30330a 100644 --- a/lua/tardis/screens/cl_screenbutton.lua +++ b/lua/tardis/screens/cl_screenbutton.lua @@ -51,6 +51,8 @@ function TardisScreenButton:new(parent,screen) end sb.ThinkInternal = function() + if not IsValid(parent) then return end + sb.transparency = math.Clamp(sb.transparency, 0, 255) if not sb.is_toggle and sb.on and CurTime() > sb.click_end_time then @@ -58,6 +60,7 @@ function TardisScreenButton:new(parent,screen) sb.frame:SetImage(sb.frame_off) sb.on = false end + if sb.moving.now then sb.moving.move() sb.icon:SetColor(Color(255, 255, 255, sb.transparency)) @@ -66,16 +69,21 @@ function TardisScreenButton:new(parent,screen) sb.clickable = (sb.transparency ~= 0) end - local realpos = { math.Clamp(sb.pos[1], 0, sb.parent:GetWide() - sb.size[1]), - math.Clamp(sb.pos[2], 0, sb.parent:GetTall() - sb.size[2]) } + if sb.lastpos == nil or sb.lastpos[1] ~= sb.pos[1] or sb.lastpos[2] ~= sb.pos[2] then + + local realpos = { math.Clamp(sb.pos[1], 0, sb.parent:GetWide() - sb.size[1]), + math.Clamp(sb.pos[2], 0, sb.parent:GetTall() - sb.size[2]) } + + sb.icon:SetPos(realpos[1], realpos[2]) + sb.frame:SetPos(realpos[1], realpos[2]) + sb.label:SetPos(sb.pos[1], sb.pos[2]) - sb.icon:SetPos(realpos[1], realpos[2]) - sb.frame:SetPos(realpos[1], realpos[2]) - sb.label:SetPos(sb.pos[1], sb.pos[2]) + sb.icon:SetSize(sb.size[1], sb.size[2]) + sb.frame:SetSize(sb.size[1], sb.size[2]) + sb.label:SetSize(sb.size[1], sb.size[2]) - sb.icon:SetSize(sb.size[1], sb.size[2]) - sb.frame:SetSize(sb.size[1], sb.size[2]) - sb.label:SetSize(sb.size[1], sb.size[2]) + sb.lastpos = {sb.pos[1], sb.pos[2]} + end if not sb.moving.now then sb.outside = (sb.pos[1] < 0) or (sb.pos[2] < 0) @@ -247,13 +255,15 @@ function TardisScreenButton:SetIsToggle(is_toggle) end function TardisScreenButton:SetPressed(on) - self.on = on - if on then - self.icon:SetImage(self.icon_on) - self.frame:SetImage(self.frame_on) - else - self.icon:SetImage(self.icon_off) - self.frame:SetImage(self.frame_off) + if self.on ~= on then + self.on = on + if on then + self.icon:SetImage(self.icon_on) + self.frame:SetImage(self.frame_on) + else + self.icon:SetImage(self.icon_off) + self.frame:SetImage(self.frame_off) + end end end function TardisScreenButton:IsPressed() @@ -285,16 +295,16 @@ function TardisScreenButton:SetControl(control) end end -function TardisScreenButton:SetPressedStateData(parent, data) +function TardisScreenButton:SetPressedStateData(ent, data) if istable(data) then self.Think = function() - if not parent._init then return end - self:SetPressed(parent:GetData(data[1]) or parent:GetData(data[2])) + if not ent._init then return end + self:SetPressed(ent:GetData(data[1]) or ent:GetData(data[2])) end else self.Think = function() - if not parent._init then return end - self:SetPressed(parent:GetData(data)) + if not ent._init then return end + self:SetPressed(ent:GetData(data)) end end end diff --git a/materials/models/molda/toyota_int/bulbs.vmt b/materials/models/molda/toyota_int/bulbs.vmt index d724794bd..eda3d243f 100644 --- a/materials/models/molda/toyota_int/bulbs.vmt +++ b/materials/models/molda/toyota_int/bulbs.vmt @@ -34,51 +34,37 @@ offVar "$color2_off" resultVar "$color2" } - TARDIS_State { + TARDIS_State_Texture { resultTextureVar $basetexture resultFrameVar $frame textures { - idle "models/molda/toyota_int/bulbs" - handbrake "models/molda/toyota_int/bulbs" - interrupt "models/molda/toyota_int/bulbs_half" - demat_fail "models/molda/toyota_int/bulbs_warning" - mat_fail "models/molda/toyota_int/bulbs_travel_warning" + dead "off" + off "models/molda/toyota_int/bulbs_off" - travel "models/molda/toyota_int/bulbs_travel" - demat "models/molda/toyota_int/bulbs_travel" - mat "models/molda/toyota_int/bulbs_travel" + idle "models/molda/toyota_int/bulbs" + handbrake "idle" + + travel { "models/molda/toyota_int/bulbs_travel" 10 } + takeoff { "models/molda/toyota_int/bulbs_travel" 55 } + parking { "models/molda/toyota_int/bulbs_travel" 50 } + + demat_abort "models/molda/toyota_int/bulbs_half" + demat_fail { "models/molda/toyota_int/bulbs_warning" 30 } + mat_fail { "models/molda/toyota_int/bulbs_travel_warning" 30 } - idle_warning "models/molda/toyota_int/bulbs_warning" + + off_warning "off" + idle_warning { "models/molda/toyota_int/bulbs_warning" 10 } handbrake_warning "models/molda/toyota_int/bulbs_warning_static" - interrupt_warning "models/molda/toyota_int/bulbs_warning" - demat_fail_warning "models/molda/toyota_int/bulbs_warning" - mat_fail_warning "models/molda/toyota_int/bulbs_travel_warning" - off_warning "models/molda/toyota_int/bulbs_off" - travel_warning "models/molda/toyota_int/bulbs_travel_warning" - demat_warning "models/molda/toyota_int/bulbs_travel_warning" - mat_warning "models/molda/toyota_int/bulbs_travel_warning" - } - frameRates { - idle 0 - handbrake 0 - interrupt 0 - demat_fail 30 - mat_fail 30 - off 0 - travel 10 - demat 55 - mat 50 - - idle_warning 10 - handbrake_warning 0 - interrupt_warning 10 - demat_fail_warning 40 - mat_fail_warning 40 - off_warning 0 - travel_warning 10 - demat_warning 40 - mat_warning 40 + + travel_warning { "models/molda/toyota_int/bulbs_travel_warning" 10 } + takeoff_warning { "models/molda/toyota_int/bulbs_travel_warning" 40 } + parking_warning "takeoff_warning" + + demat_abort_warning "idle_warning" + demat_fail_warning { "models/molda/toyota_int/bulbs_warning" 40 } + mat_fail_warning "takeoff_warning" } } Sine { diff --git a/materials/models/molda/toyota_int/floorlights.vmt b/materials/models/molda/toyota_int/floorlights.vmt index 2aba8f3d1..b873081c0 100644 --- a/materials/models/molda/toyota_int/floorlights.vmt +++ b/materials/models/molda/toyota_int/floorlights.vmt @@ -23,51 +23,37 @@ } - TARDIS_State { + TARDIS_State_Texture { resultTextureVar $basetexture resultFrameVar $frame textures { - idle "models/molda/toyota_int/bulbs" - handbrake "models/molda/toyota_int/bulbs" - interrupt "models/molda/toyota_int/bulbs" - demat_fail "models/molda/toyota_int/bulbs_off" - mat_fail "models/molda/toyota_int/bulbs_warning" + dead "off" + off "models/molda/toyota_int/bulbs_off" - travel "models/molda/toyota_int/bulbs_travel" - demat "models/molda/toyota_int/bulbs_travel" - mat "models/molda/toyota_int/bulbs" + idle "models/molda/toyota_int/bulbs" + handbrake "idle" + + travel { "models/molda/toyota_int/bulbs_travel" 10 } + takeoff "travel" + parking { "models/molda/toyota_int/bulbs" 10 } + + demat_abort "models/molda/toyota_int/bulbs" + demat_fail "off" + mat_fail { "models/molda/toyota_int/bulbs_warning" 18 } - idle_warning "models/molda/toyota_int/bulbs_warning" + + off_warning "off" + idle_warning { "models/molda/toyota_int/bulbs_warning" 10 } handbrake_warning "models/molda/toyota_int/bulbs_warning" - interrupt_warning "models/molda/toyota_int/bulbs_warning" - demat_fail_warning "models/molda/toyota_int/bulbs_travel_warning" - mat_fail_warning "models/molda/toyota_int/bulbs_warning" - off_warning "models/molda/toyota_int/bulbs_off" - travel_warning "models/molda/toyota_int/bulbs_travel_warning" - demat_warning "models/molda/toyota_int/bulbs_travel_warning" - mat_warning "models/molda/toyota_int/bulbs_warning" - } - frameRates { - idle 0 - handbrake 0 - interrupt 0 - demat_fail 0 - mat_fail 18 - off 0 - travel 10 - demat 10 - mat 10 - - idle_warning 10 - handbrake_warning 0 - interrupt_warning 10 - demat_fail_warning 20 - mat_fail_warning 30 - off_warning 0 - travel_warning 10 - demat_warning 10 - mat_warning 10 + + travel_warning { "models/molda/toyota_int/bulbs_travel_warning" 10 } + takeoff_warning "travel_warning" + parking_warning "idle_warning" + + demat_abort_warning "idle_warning" + demat_fail_warning { "models/molda/toyota_int/bulbs_travel_warning" 20 } + mat_fail_warning { "models/molda/toyota_int/bulbs_warning" 30 } } } diff --git a/materials/models/molda/toyota_int/pipes2.vmt b/materials/models/molda/toyota_int/pipes2.vmt index 92e673240..e10062faa 100644 --- a/materials/models/molda/toyota_int/pipes2.vmt +++ b/materials/models/molda/toyota_int/pipes2.vmt @@ -4,9 +4,18 @@ "$surfaceprop" "Metal" "$envmap" "models/molda/toyota_int/environment" - "$envmaptint" "[0.3 0.3 0.3]" + "$envmaptint" "[0.1 0.1 0.2]" "$nodecal" "1" "$nocull" "0" + $envmaptint_on "[0.1 0.1 0.2]" + $envmaptint_off "[0.04 0.04 0.09]" + Proxies { + TARDIS_Power { + onVar "$envmaptint_on" + offVar "$envmaptint_off" + resultVar "$envmaptint" + } + } } diff --git a/materials/models/molda/toyota_int/toplights.vmt b/materials/models/molda/toyota_int/toplights.vmt index 9b0774570..760bbea8e 100644 --- a/materials/models/molda/toyota_int/toplights.vmt +++ b/materials/models/molda/toyota_int/toplights.vmt @@ -30,51 +30,37 @@ resultVar "$color2" } - TARDIS_State { + TARDIS_State_Texture { resultTextureVar $basetexture resultFrameVar $frame textures { - idle "models/molda/toyota_int/bulbs" - handbrake "models/molda/toyota_int/bulbs" - interrupt "models/molda/toyota_int/bulbs" - demat_fail "models/molda/toyota_int/bulbs" - mat_fail "models/molda/toyota_int/toplights" - travel "models/molda/toyota_int/toplights" - demat "models/molda/toyota_int/toplights" - mat "models/molda/toyota_int/bulbs" + dead "off" + off "models/molda/toyota_int/toplights_off" + idle "models/molda/toyota_int/bulbs" + handbrake "idle" + + travel { "models/molda/toyota_int/toplights" 10 } + takeoff "travel" + parking "idle" + + demat_abort "idle" + demat_fail "idle" + mat_fail "travel" + - idle_warning "models/molda/toyota_int/bulbs_half" - handbrake_warning "models/molda/toyota_int/bulbs_half" - interrupt_warning "models/molda/toyota_int/bulbs_half" - demat_fail_warning "models/molda/toyota_int/bulbs_half" - mat_fail_warning "models/molda/toyota_int/toplights" - travel_warning "models/molda/toyota_int/toplights" - demat_warning "models/molda/toyota_int/toplights" - mat_warning "models/molda/toyota_int/bulbs" off_warning "models/molda/toyota_int/bulbs_off" - } - frameRates { - idle 0 - handbrake 0 - interrupt 0 - demat_fail 0 - mat_fail 10 - travel 10 - demat 10 - mat 0 - off 0 + idle_warning "models/molda/toyota_int/bulbs_half" + handbrake_warning "idle_warning" + + travel_warning "travel" + takeoff_warning "travel" + parking_warning "idle" - idle_warning 0 - handbrake_warning 0 - interrupt_warning 0 - demat_fail_warning 0 - mat_fail_warning 10 - travel_warning 10 - demat_warning 10 - mat_warning 0 - off_warning 0 + demat_abort_warning "idle_warning" + demat_fail_warning "idle_warning" + mat_fail_warning "travel" } } }