• Overheating for a weapon
    3 replies, posted
I'm trying to create a weapon that, well, overheats. So I set a variable called [I]SWEP.Heat[/I] and reset it at 0. Then, I do this: [lua]if self.Heat >= 255 then --Create explosion, destroy the gun return end if self.Owner:KeyDown( IN_ATTACK ) and CurTime() > self.Weapon:GetNextPrimaryFire() then self.Heat = self.Heat + 1 elseif self.Heat > 0 then self.Heat = self.Heat - ( (255-self.Heat)/127 ) if self.Heat < 0 then self.Heat = 0 end if self.Owner:KeyReleased( IN_ATTACK ) and CurTime() > self:GetNextPrimaryFire() then self.Weapon:SetNextPrimaryFire( CurTime() + 2 ) end end end[/lua] But - 1) Apparently SWEP:Think() is affected by.. something, so it doesn't really fit my needs as I need a static length of time to count on. And I assume there's a much better way to do this than a timer... 2) This will mean the "cool down" mechanism won't work if the weapon isn't deployed, which really doesn't fit my needs as that is illogical and makes the weapon lame af 3) I assume there's a better way to do all of this that I'm just not aware of....
Firstly, this part:[lua]if self.Owner:KeyDown( IN_ATTACK ) and CurTime() > self.Weapon:GetNextPrimaryFire() then self.Heat = self.Heat + 1[/lua]should go to PrimaryAttack instead of Think, without the "if" since it naturally works like that anyway. as for the rest, I'm not sure how foolproof this is but conceptually this is how I'd do it: [lua]if self.Heat >= 255 then --Create explosion, destroy the gun return end local lastcool = self.LastCool or CurTime() -- just make sure it's defined, probably best to define self.LastCool in initialize self.LastCool = CurTime() -- for next time local cooltime = CurTime() - lastcool -- I'm going for linear cooldown here. If you want more elaborate cooldown you would need to calculate it based on dectime and self.Heat local cooldownamount = cooltime * 0.2 -- cool down by 0.2/sec self.Heat = math.max(self.Heat - cooldownamount, 0)[/lua] Also note that depending on your plans, you might want to allow the weapon to "cool down" while it's being fired, as long as the fire rate heats it up faster than it cools down. If not, you can just use the same KeyDown test you did before.
The Think hook is affected by how long it takes the render / process the game logic. Use a constant time function (such as CurTime) to calculate the time between ticks for the weapon. So if they put the gun away for 2 minutes, you should multiply all of your modifications by 120 (assuming your calculations are based off seconds). Here is some sample code that might guide you in the right direction: [lua] SWEP.HeatTimer = 0; -- repreents how long they have been shooting SWEP.OverheatMax = 60; -- seconds SWEP.CooldownRatio = (2 / 1); -- 2 seconds of shooting -> 1 second of cooldown SWEP.LastFrameTime = nil; -- when was the last time this code ran? function SWEP:Think() -- figure out the time it has been since the code last ran local frameDelta = CurTime() - (SWEP.LastFrameTime or CurTime()); -- are they shooting? if( self.Owner:KeyDown( IN_ATTACK ) && CurTime() > self.Weapon:GetNextPrimaryFire() )then -- update the variable if not set self.HeatTimer = (self.HeatTimer or 0) + frameDelta; -- is it too hot? if( self.HeatTimer >= self.OverheatMax )then -- EXPLODE end elseif( SWEP.HeatTimer > 0 )then -- they stopped shooting, subtract time SWEP.HeatTimer = math.Clamp( (self.HeatTimer - (frameDelta * self.CooldownRatio)), 0, self.OverheatMax + 10 ); end -- update the variable for when this code last ran SWEP.LastFrameTime = CurTime(); end [/lua]
[QUOTE=zzaacckk;50093296]The Think hook is affected by how long it takes the render / process the game logic. Use a constant time function (such as CurTime) to calculate the time between ticks for the weapon. So if they put the gun away for 2 minutes, you should multiply all of your modifications by 120 (assuming your calculations are based off seconds). Here is some sample code that might guide you in the right direction: [lua] SWEP.HeatTimer = 0; -- repreents how long they have been shooting SWEP.OverheatMax = 60; -- seconds SWEP.CooldownRatio = (2 / 1); -- 2 seconds of shooting -> 1 second of cooldown SWEP.LastFrameTime = nil; -- when was the last time this code ran? function SWEP:Think() -- figure out the time it has been since the code last ran local frameDelta = CurTime() - (SWEP.LastFrameTime or CurTime()); -- are they shooting? if( self.Owner:KeyDown( IN_ATTACK ) && CurTime() > self.Weapon:GetNextPrimaryFire() )then -- update the variable if not set self.HeatTimer = (self.HeatTimer or 0) + frameDelta; -- is it too hot? if( self.HeatTimer >= self.OverheatMax )then -- EXPLODE end elseif( SWEP.HeatTimer > 0 )then -- they stopped shooting, subtract time SWEP.HeatTimer = math.Clamp( (self.HeatTimer - (frameDelta * self.CooldownRatio)), 0, self.OverheatMax + 10 ); end -- update the variable for when this code last ran SWEP.LastFrameTime = CurTime(); end [/lua][/QUOTE] This helped a lot, thanks! There's just 1 thing I didn't quite understand: [lua]SWEP.HeatTimer = math.Clamp( (self.HeatTimer - (frameDelta * self.CooldownRatio)), 0, self.OverheatMax + 10 )[/lua] Why is the [I]+ 10[/I] there?
Sorry, you need to Log In to post a reply to this thread.