What I want to do is make it so player has to hold down the USE key (and not move their mouse or whatever away from it) for a certain time until a variable gets to a certain amount, then something will be triggered. This is my code so far, not working:
ent_drill
[lua]AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside
AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent.
include('shared.lua')
//
// Money Pallet models/props/cs_assault/MoneyPallet.mdl
// ATM models/props/cs_assault/TicketMachine.mdl
// Banded Money models/props/cs_assault/Money.mdl
// Table models/props/CS_militia/wood_table.mdl
// Getaway Van models/props/de_nuke/truck_nuke.mdl
// Security Camera models/props/cs_assault/camera.mdl
//
function ENT:Initialize()
util.AddNetworkString( "drillsync" )
drilltime = 0
self:SetModel( "models/props/de_nuke/truck_nuke.mdl" )
self:PhysicsInit( SOLID_VPHYSICS ) -- Make us work with physics,
self:SetMoveType( MOVETYPE_VPHYSICS ) -- after all, gmod is a physics
self:SetSolid( SOLID_VPHYSICS ) -- Toolbox
local phys = self:GetPhysicsObject()
if (phys:IsValid()) then
phys:Wake()
end
timer.Create( "DrillUse", 1, 1, function()
if drilltime < 1 then
drilltime = drilltime + 0.25
end
end)
timer.Stop( "DrillUse" )
end
function ENT:Use( activator, caller )
timer.Start("DrillUse")
end
function ENT:Think()
if drilltime > 0.99 then
print("Well done!")
end
net.Start( "drillsync" ) // start writing the net message
net.WriteInt( drilltime, 32 ) // anything under roughly 2^31 - 1
net.Broadcast() // send the message to all connected players
end[/lua]
shared
[lua]ddrilltime = 0
net.Receive( "drillsync", function( int )
ddrilltime = ddrilltime + net.ReadInt(32)
end )[/lua]
cl_init
[lua]concommand.Add("printdrill", function()
print(ddrilltime)
end)[/lua]
Pressing E on it does nothing, no well done, printdrill yields 0. Help?
Move this out of the Initialize function:
[LUA]
util.AddNetworkString( "drillsync" )
[/LUA]
Ent:Use() is only called once, so you can't really detect if the player is still pressing E using that alone.
It gets called as soon as you start pressing though, so you should store the player that used the entity and then in the think function keep checking if the player is still pressing the use key (use [URL="http://wiki.garrysmod.com/page/Player/KeyDown"]Player:KeyDown()[/URL]) and if he is still pressing it increase drilltime by FrameTime().
Don't sync the timer each tick. Only sync the time when the player started and stopped pressing E. Everything in between can be calculated on the clientside.
[lua]function ENT:Use( activator, caller )
timer.Start("DrillUse")
activatorply = activator
end
function ENT:Think()
-- We don't need to think, we are just a prop after all!
if drilltime > 0.99 then
print("Well done!")
end
if activatorply:KeyDown( IN_USE ) then
-- Code
end
net.Start( "drillsync" ) // start writing the net message
net.WriteInt( drilltime, 32 ) // anything under roughly 2^31 - 1
net.Broadcast() // send the message to all connected players
end[/lua]
Would that work?
Although, I don't know what you mean by increasing drilltime by FrameTime(), would it be using built in timers like timer.Simple or timer.Create, or is it a completely different kind of thing?
Nevermind the FrameTime() part.
This could work:
[LUA]function ENT:Use( activator, caller )
net.Start("DrillStartUse") //You need to AddNetworkString this
net.WriteFloat(CurTime())
net.Broadcast()
activatorply = activator
drilltime = 0 //You might want to store this on the entity instead
end
function ENT:Think()
local difference = CurTime()-(self.LastThink or CurTime())
-- We don't need to think, we are just a prop after all!
if drilltime > 0.99 then
print("Well done!")
end
if IsValid(activatorply) && activatorply:KeyDown( IN_USE ) then
drilltime = drilltime + difference
elseif(activatorply) then
activatorply = nil
net.Start("DrillEnd")
net.Broadcast()
end
self.LastThink = CurTime()
end[/LUA]
[QUOTE=syl0r;46129114]Nevermind the FrameTime() part.
This could work:
[LUA]function ENT:Use( activator, caller )
net.Start("DrillStartUse") //You need to AddNetworkString this
net.WriteFloat(CurTime())
net.Broadcast()
activatorply = activator
drilltime = 0 //You might want to store this on the entity instead
end
function ENT:Think()
local difference = CurTime()-(self.LastThink or CurTime())
-- We don't need to think, we are just a prop after all!
if drilltime > 0.99 then
print("Well done!")
end
if IsValid(activatorply) && activatorply:KeyDown( IN_USE ) then
drilltime = drilltime + difference
elseif(activatorply) then
activatorply = nil
net.Start("DrillEnd")
net.Broadcast()
end
self.LastThink = CurTime()
end[/LUA][/QUOTE]
I don't get what I'd do in shared.lua/cl_init.lua. Modified it a bit to match network strings and more printing, not really doing anything...
[QUOTE=RonanZer0;46129170]I don't get what I'd do in shared.lua/cl_init.lua. Modified it a bit to match network strings and more printing, not really doing anything...[/QUOTE]
Does it print 'Well done!' now?
Regarding your questions. That totally depends on what you want to do with the time ddrilltime you had.
Sorry for the bump but I just noticed that [lua]AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside
AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent.
include('shared.lua')
//
// Money Pallet models/props/cs_assault/MoneyPallet.mdl
// ATM models/props/cs_assault/TicketMachine.mdl
// Banded Money models/props/cs_assault/Money.mdl
// Table models/props/CS_militia/wood_table.mdl
// Getaway Van models/props/de_nuke/truck_nuke.mdl
// Security Camera models/props/cs_assault/camera.mdl
// Gate/Drill models/props_c17/gate_door02a.mdl
//
function ENT:Initialize()
util.AddNetworkString( "DrillStartUse" )
util.AddNetworkString( "DrillStartEnd" )
drilltime = 0
self:SetModel( "models/props_c17/gate_door02a.mdl" )
self:PhysicsInit( SOLID_VPHYSICS ) -- Make us work with physics,
self:SetMoveType( MOVETYPE_VPHYSICS ) -- after all, gmod is a physics
self:SetSolid( SOLID_VPHYSICS ) -- Toolbox
local phys = self:GetPhysicsObject()
if (phys:IsValid()) then
phys:Wake()
end
timer.Create( "DrillUse", 1, 1, function()
if drilltime < 1 then
drilltime = drilltime + 0.25
end
end)
timer.Stop( "DrillUse" )
end
function ENT:Use( activator, caller )
net.Start("DrillStartUse") //You need to AddNetworkString this
net.WriteFloat(CurTime())
net.Broadcast()
activatorply = activator
drilltime = 0 //You might want to store this on the entity instead
end
function ENT:Think()
local difference = CurTime()-(self.LastThink or CurTime())
-- We don't need to think, we are just a prop after all!
if drilltime > 0.99 then
print("Well done!")
end
if IsValid(activatorply) && activatorply:KeyDown( IN_USE ) then
drilltime = drilltime + difference
elseif(activatorply) then
activatorply = nil
net.Start("DrillStartEnd")
net.Broadcast()
drilltime = 0
end
self.LastThink = CurTime()
end[/lua]
it prints Well Done when I'm close to it 100% of the time not when I hold use on it
Edit: Seems to increase when I just look at it in use range
Edit: It's as if DrillStartUse is being sent every frame that drilltime/ddrill time = 1
Put a print("debug") in certain lines to find out what exactly is going wrong.
the Use method should only be called once. Start there, if it's called more often you probably have to change your UseType using [URL="http://wiki.garrysmod.com/page/Entity/SetUseType"]ent:SetUseType(SIMPLE_USE)[/URL]
Also, I just found out that there is a way to change the use method to be continuous.
Unfortunately I don't think there is a way built in to detect when the player releases the key...
[URL="http://wiki.garrysmod.com/page/ENTITY/Use"]Ent:Use()[/URL] also comes with a parameter called value. I have no idea what it is exactly and what value it has, but maybe that would be useful for you.
As always there is little documentation on this kind of stuff. Quite pathetic for a game that sole purpose is for coders to create mods for it......
There are many ways you can accomplish Hold to use... I've made systems which use a timer ( on simple use start timer, on -Use destroy timer, if the timer executes then a quick check to verify use is still pressed means the user held the button the entire time... Because -use destroys the timer, and +use starts a new time, it works very well and is EASY to implement.
If you want to show a progress bar, you can simple set up the equations necessary to get the fraction and display on screen...
Here are the time equations:
Delay = X; in seconds == Total Time
StartTime = CurTime( );...
EndTime = StartTime + Delay;
TimeElapsed = CurTime( ) - StartTime;
TimeRemaining = Delay - ( TimeElapsed ); == Delay - ( CurTime( ) - StartTime );
TimeFraction = TimeElapsed / Delay;
Something similar without the bar, but using the equations: [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/vgui/sh_hud_countdown.lua.html[/url]
VGUI Progress bar uses SetFraction, that could work, or you could draw your own... Unfortunately I don't have the example ready yet for that; the draw extensions I added will be out soon ( draw.ProgressBar ), but it is as easy as setting a width or height for the bar at 100% ( with fraction 0-1; clamp it ) such as 250 pixels.. ( MaxWidth * math.Clamp( TimeFraction, 0, 1 ) ); The equations do the rest...
Ok, so... I want to do the absolute opposite. I've been trying to figure out a way to stop 'hold to use' so that it only works once...
[I][B]AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
include("shared.lua")
function ENT:Initialize()
self:SetModel("models/props_wasteland/cargo_container01.mdl")
self:PhysicsInit(SOLID_VPHYSICS)
self:SetMoveType(MOVETYPE_VPHYSICS)
self:SetSolid(SOLID_VPHYSICS)
local phys = self:GetPhysicsObject()
if phys:IsValid() then
[/B][/I][I][B]phys[/B][/I][I][B]:Wake[/B][/I][I][B]()
end
end
function ENT:Use(a , c, SIMPLE_USE)[/B][/I]
local vehicle = ents.Create( "sent_spitfire_p" )
vehicle:SetPos( Vector( 0, 0, 100 ) )
vehicle:Spawn()
end
I also want to make it spawn the entity in, and then delete itself leaving the entity in it's place instead of dropping the spawned entity out fo the air but that's not my priority right now
Sorry, you need to Log In to post a reply to this thread.