havenphillip Posted December 19, 2017 Share Posted December 19, 2017 Can't figure out how to make it show rounded numbers. Is this a quick fix or am I way off? I'm guessing using Math:Round() but I don't know how to plug it in. Here's what it looks like and the code I've got so far: Quote Link to comment Share on other sites More sharing options...
reepblue Posted December 19, 2017 Share Posted December 19, 2017 Use a timer system like seen in TriggerDelay.lua Script.delay=1000--int "Delay" Script.activatetime=0 Script.maxHealth = 100 Script.healthRate = 2 -- 2 hp per second.. function Script:Regen() self.activatetime = Time:GetCurrent()+self.delay end function AddHealth(health) self.health = health end function Script:UpdatePhysics() if self.activatetime>0 then if Time:GetCurrent()>self.activatetime then self.activatetime=0 self:AddHealth(self.healthRate) end end end Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
havenphillip Posted December 19, 2017 Author Share Posted December 19, 2017 Awesome I'll try this. Quote Link to comment Share on other sites More sharing options...
reepblue Posted December 19, 2017 Share Posted December 19, 2017 Looking back on it, it's not done, but should get you started. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
macklebee Posted December 19, 2017 Share Posted December 19, 2017 Using Math:Round when drawing the text will round to the nearest whole number: context:DrawText("Health: "..Math:Round(health).."/100",2,2) To display to a specific decimal place: context:DrawText(string.format("Health: %.3f/100",health),2,22) where %.3f will show to the 3rd decimal place; %.2f would show to the 2nd decimal; %.1f would show to the 1st decimal... etc.. 1 Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
havenphillip Posted December 20, 2017 Author Share Posted December 20, 2017 Awesome. I'll try that. I like the trigger delay version but I couldn't' get it to work and I'm a noob at coding so I get easily confused... Quote Link to comment Share on other sites More sharing options...
Josh Posted December 20, 2017 Share Posted December 20, 2017 1 hour ago, havenphillip said: Awesome. I'll try that. I like the trigger delay version but I couldn't' get it to work and I'm a noob at coding so I get easily confused... You have a picture of Data with a beard. I believe in you. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
havenphillip Posted December 20, 2017 Author Share Posted December 20, 2017 15 hours ago, Josh said: You have a picture of Data with a beard. I believe in you. Haha! Thanks. Chicks dig it. I have a lot of fun with Leadwerks and the community is really helpful. The appeal of it was that a noob like me can download it and make my own games and I'm finding that to be the case. I don't get stuck and just give up. Gratuitous feedback: I hope you end up making that Boner 3D program. I'd buy it. I'm learning the coding but I also want a way to make models and rig/animate them and a lot of these programs (looking at you, Blender) are horribly tedious and confusing. Possibly a lot more Leadwerks projects would come to fruition if there were some kind of modeling/rigging/animating program that was easily accessible to somebody like me the way Leadwerks is with the coding aspect. end rant Quote Link to comment Share on other sites More sharing options...
havenphillip Posted December 20, 2017 Author Share Posted December 20, 2017 I got the code working. Works well with the Math:Round() under the PostRender function but now I'm noticing the regen rate changes while I'm walking around. When I spawn in the first crawler attacks me and the health immediately jumps back. But as I walk around it is really slow. What would cause that? I'm using Time:GetCurrent() so maybe it has something to do with the frame rate or something? Quote Link to comment Share on other sites More sharing options...
macklebee Posted December 20, 2017 Share Posted December 20, 2017 Quote now I'm noticing the regen rate changes while I'm walking around. When I spawn in the first crawler attacks me and the health immediately jumps back. But as I walk around it is really slow. What would cause that? I'm using Time:GetCurrent() so maybe it has something to do with the frame rate or something? No, it has to do with the fact that Time:GetCurrent() returns the application time. So the longer the game runs the higher the Time:GetCurrent() value becomes, which inversely lowers the value added to health. You need to do what Reepblue suggested and only add a fixed amount of health after a certain delay has occurred if you want a fixed rate of health increase. Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
Josh Posted December 20, 2017 Share Posted December 20, 2017 You could either add the health in the UpdatePhysics function, which runs at a constant 60 FPS, or you could add a small amount in the UpdateWorld function each frame like this: self.health = self.health + 0.001 * Time:GetSpeed() if self.health > 1 then self.health = 1 end Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
havenphillip Posted December 21, 2017 Author Share Posted December 21, 2017 Cool I got this to work. So far so good: function Script:UpdatePhysics() --Regenerate Health if self.health < self.maxHealth and self.health > 0 then self.healthRegen = 0.01 * (Time:GetSpeed()) self.health = self.health + self.healthRegen end if self.health >= self.maxHealth then self.health = self.maxHealth end if self.health <= 0 then self.health = 0 end Quote Link to comment Share on other sites More sharing options...
Josh Posted December 21, 2017 Share Posted December 21, 2017 If your code is in UpdatePhysics() then you actually should not multiply it by GetSpeed() since this function is called 60 times per second no matter what. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
gamecreator Posted December 21, 2017 Share Posted December 21, 2017 11 minutes ago, Josh said: If your code is in UpdatePhysics() then you actually should not multiply it by GetSpeed() since this function is called 60 times per second no matter what. That's assuming the computer is fast enough to keep up or the scene isn't too heavy, right? It's can't be 100% guaranteed, right? Quote Link to comment Share on other sites More sharing options...
Josh Posted December 21, 2017 Share Posted December 21, 2017 4 minutes ago, gamecreator said: That's assuming the computer is fast enough to keep up or the scene isn't too heavy, right? It's can't be 100% guaranteed, right? Well, if the computer is too slow then it will perform the physics step twice, or more, depending on how much time has passed. But basically yeah it can always be assumed to be running at 60 hz. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
havenphillip Posted December 21, 2017 Author Share Posted December 21, 2017 Oops. Ok. Like this, then? The other thing now is how to turn it into a script.variable so I can adjust it in the side tab. I tried... script.healthRegen = 0.005... local t = self.healthRegen * (Time:GetSpeed())... ...but then my health stayed at 100 no matter what: function Script:UpdateWorld() --Regenerate Health if self.health < self.maxHealth and self.health > 0 then local healthRegen = 0.005 * (Time:GetSpeed()) self.health = self.health + healthRegen end if self.health >= self.maxHealth then self.health = self.maxHealth end if self.health <= 0 then self.health = 0 end Quote Link to comment Share on other sites More sharing options...
AggrorJorn Posted December 21, 2017 Share Posted December 21, 2017 Script.healthRegen = 0.005 --float "Health regen" Quote Link to comment Share on other sites More sharing options...
havenphillip Posted December 21, 2017 Author Share Posted December 21, 2017 That's what makes sense to me, logically. But when I do it that way I take no damage at all. I have: Script.healthRegen = 0.005 -- float "Health Regen Rate" function Script:UpdateWorld() --Regenerate Health if self.health < self.maxHealth and self.health > 0 then local regenRate = self.healthRegen * (Time:GetSpeed()) self.health = self.health + regenRate end if self.health >= self.maxHealth then self.health = self.maxHealth end if self.health <= 0 then self.health = 0 end I tried to get a picture of it. You can see I just got hit and no damage: Quote Link to comment Share on other sites More sharing options...
AggrorJorn Posted December 21, 2017 Share Posted December 21, 2017 Can you post your entire script? Quote Link to comment Share on other sites More sharing options...
Roland Posted December 21, 2017 Share Posted December 21, 2017 Just a little note. if self.health >= self.maxHealth then self.health = self.maxHealth end if self.health <= 0 then self.health = 0 end could be replaced with self.health = Math:Clamp(self.health, 0, self.MaxHealth) 1 Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
havenphillip Posted December 21, 2017 Author Share Posted December 21, 2017 10 minutes ago, AggrorJorn said: Can you post your entire script? That's all it is. It's plugged into the FPSPlayer with the Status Bars from the Workshop. But here's what I have: import "Scripts/Functions/ReleaseTableObjects.lua" Script.health = 100 --int "Health" Script.maxHealth = 100 --float "Max Health" Script.healthRegen = 0.005 --float "Health Regen Rate" Script.stamina = 1000 --float "Stamina" Script.maxStamina = 1000 --float "Max Stamina" Script.mouseSensitivity = 15 --float "Mouse sensitivity" Script.camSmoothing = 2 --float "Cam smoothing" Script.moveSpeed = 2.5 --float "Move Speed" Script.speedMultiplier = 1.5 --float "Run Multiplier" Script.strafeSpeed = 4 --float "Strafe Speed" Script.playerHeight = 1.8 --float "Player Height" Script.jumpForce = 8 --float "Jump Force" Script.flashlighton = false --bool "Flashlight on" Script.useDistance = 3 Script.alive=true Script.eyeheight=1.4 Script.footstepwalkdelay = 500 Script.footsteprundelay = 300 Script.weaponfile=""--path "Weapon" "Prefab (*.pfb):pfb|Prefabs" Script.input={} Script.maxcarryweight=5 Script.throwforce = 500 Script.isairborne=false Script.bloodindex=1 Script.teamid=1--choice "Team" "Neutral,Good,Bad" Script.hurtoffset=Vec3(0) Script.smoothedhurtoffset=Vec3(0) Script.mouseDifference = Vec2(0,0) Script.playerMovement = Vec3(0,0,0) Script.tempJumpForce = 0 Script.IsClimbing = false Script.climbingSpeed = 2 --float "Climbing Speed" function Script:CycleWeapon(direction) local n,weapon local foundindex=false local prevweapon if direction==1 then for n,weapon in pairs(self.weapons) do if foundindex then self:SelectWeapon(n) return end if self.currentweaponindex==n then foundindex=true end end if foundindex then for n,weapon in pairs(self.weapons) do self:SelectWeapon(n) return end end else for n,weapon in pairs(self.weapons) do if prevweapon then if self.currentweaponindex==n then self:SelectWeapon(prevweapon) return end end prevweapon=n end if prevweapon then self:SelectWeapon(prevweapon) end end end function Script:AddWeapon(weapon) if weapon.index==nil then weapon.index=1 end if self.weapons[weapon.index]==nil then self.weapons[weapon.index]=weapon self.weapons[weapon.index].player = self self.weapons[weapon.index].entity:SetParent(self.weapontag) self.weapons[weapon.index].entity:SetPosition(self.weapons[weapon.index].offset) if self.weapons[weapon.index].rotation~=nil then self.weapons[weapon.index].entity:SetPosition(self.weapons[weapon.index].rotation) end self.weapons[weapon.index].entity:Hide() if weapon.index>self.currentweaponindex then self:SelectWeapon(weapon.index) end if self.sound.pickupweapon~=nil then self.sound.pickupweapon:Play() end return true end return false end function Script:SelectWeapon(index) if index~=self.currentweaponindex then if self.weapons[self.currentweaponindex]~=nil then self.weapons[self.currentweaponindex].entity:Hide() end self.currentweaponindex = index if self.weapons[self.currentweaponindex]~=nil then self.weapons[self.currentweaponindex].entity:Show() end self.weaponlowerangle=90 self.suspendfire=false self.weapontag:SetRotation(self.weaponlowerangle,0,0) end end --This function will be called when an entity is loaded in a map. Use this for intitial setup stuff. function Script:Start() self.spawntime = Time:GetCurrent() self.count = 0 self.weapons={} self.currentweaponindex=-1 self.camRotation = self.entity:GetRotation(true) self.weaponlowerangle=0 self.image={} self.image.crosshair = Texture:Load("Materials/HUD/crosshair.tex") self.image.hand = Texture:Load("Materials/HUD/use.tex") self.image.blood={} self.image.blood[1]=Texture:Load("Materials/HUD/blood1.tex") self.image.blood[2]=Texture:Load("Materials/HUD/blood2.tex") self.image.blood[3]=Texture:Load("Materials/HUD/blood3.tex") self.image.blood[4]=Texture:Load("Materials/HUD/blood4.tex") --Load shared sounds self.sound={}--table to store sound in self.sound.flashlight=Sound:Load("Sound/Player/flashlight_02_on.wav") self.sound.damage={} self.sound.damage[1]=Sound:Load("Sound/Impact/body_punch_03.wav") self.sound.damage[2]=Sound:Load("Sound/Impact/body_punch_04.wav") self.sound.pickupweapon=Sound:Load("Sound/Player/pickupammo.wav") self.sound.footsteps={} self.sound.footsteps.concrete={} self.sound.footsteps.concrete.step={} --self.sound.footsteps.concrete.step[1] = Sound:Load("Sound/Footsteps/Concrete/step1.wav") --self.sound.footsteps.concrete.step[2] = Sound:Load("Sound/Footsteps/Concrete/step2.wav") --self.sound.footsteps.concrete.step[3] = Sound:Load("Sound/Footsteps/Concrete/step3.wav") --self.sound.footsteps.concrete.step[4] = Sound:Load("Sound/Footsteps/Concrete/step4.wav") --self.sound.footsteps.concrete.jump = Sound:Load("Sound/Footsteps/Concrete/jump.wav") self.bloodoverlay={} self.entity:SetPickMode(0) --Set the type for this object to player self.entity:SetKeyValue("type","player") local mass = self.entity:GetMass() if self.entity:GetMass()==0 then Debug:Error("Player mass should be greater than 0.") end --Create a camera self.camera = Camera:Create() self.camera:SetFOV(70) self.camera:SetRange(0.05,1000) self.camera:SetMultisampleMode((System:GetProperty("multisample","1"))) --Set the camera's rotation to match the player self.camera:SetRotation(self.entity:GetRotation(true)) --Set the camera position at eye height self.camera:SetPosition(self.entity:GetPosition(true)+Vec3(0,self.eyeheight,0)) --Create listener self.listener = Listener:Create(self.camera) --Add fog to camera self.camera:SetFogMode(true) self.camera:SetFogRange (0,40) self.camera:SetFogColor (0.9,0.9,0.9,0.08) self.camera:SetFogAngle (0, 180) self.camera:SetClearColor(0.721, 0.352, 0,1) --Create flashlight self.flashlight = SpotLight:Create() self.flashlight:SetParent(self.camera,false) self.flashlight:SetPosition(0.2,-0.1,0) self.flashlight:SetRotation(10,-3,0) self.flashlight:SetConeAngles(30,10) self.flashlight:SetShadowMode(Light.Dynamic+Light.Static) if self.flashlighton==false then self.flashlight:Hide() end --Load the default weapon, if one is set self.weapontag = Pivot:Create(self.camera) --Hitbox for bullets self.entity:SetCollisionType(Collision.Character) local hitbox = Model:Box(0.5,1.8,0.5) hitbox:SetPosition(self.entity:GetPosition()) hitbox:Translate(0,0.9,-1) hitbox:SetParent(self.entity,true) hitbox:SetCollisionType(Collision.Prop) hitbox:SetShadowMode(0) --------------------------------------------------------------------------- --We want the player model visible in the editor, but invisible in the game --We can achieve this by creating a material, setting the blend mode to make --it invisible, and applying it to the model. --------------------------------------------------------------------------- local material = Material:Create() material:SetBlendMode(5)--Blend.Invisible self.entity:SetMaterial(material) hitbox:SetMaterial(material) material:Release() self.entity:SetShadowMode(0) local window = Window:GetCurrent() local context = Context:GetCurrent() window:SetMousePosition(Math:Round(context:GetWidth()/2), Math:Round(context:GetHeight()/2)) self.camera:SetRotation(self.camRotation) if self.weaponfile~="" then local prefab = Prefab:Load(self.weaponfile) if prefab~=nil then if prefab.script~=nil then self:AddWeapon(prefab.script) else prefab:Release() end end end end function Script:Release() self.listener:Release() self.flashlight:Release() if self.corpse~=nil then self.corpse:Release() self.corpse=nil end ReleaseTableObjects(self.sound) ReleaseTableObjects(self.image) local k,v for k,v in pairs(self.weapons) do v:Release() end end function Script:Collision(entity,position,normal,speed) if speed>20 then self:Hurt(5) end end function Script:Hurt(damage,distributorOfPain) if self.health>0 then self.sound.damage[math.random(#self.sound.damage)]:Play() self.health = self.health - damage self.hurtoffset = Vec3(math.random(-1,1),math.random(-1,1),0):Normalize()*30 local blood = {} local n=1 blood.texture=self.image.blood[math.random(1,4)] blood.intensity=1 table.insert(self.bloodoverlay,blood) if self.bloodindex>4 then self.bloodindex=1 end if self.health<=0 then self:Kill() end end end function Script:Kill() self.corpse = Pivot:Create() local shape = Shape:Load("Models/Characters/Generic/corpse.phy")--this shape is made from a low-poly CSG sphere, so it will roll around a bit but come to a stop quickly self.corpse:SetShape(shape) if shape~=nil then shape:Release() end self.flashlight:Hide() if self.weapons[self.currentweaponindex]~=nil then self.weapons[self.currentweaponindex]:Hide() end self.corpse:SetMass(5) self.corpse:SetMatrix(self.camera:GetMatrix()) self.camera:SetParent(self.corpse) self.camera:SetPosition(0,0,0) self.camera:SetRotation(0,0,0) self.corpse:SetCollisionType(Collision.Prop) self.corpse:SetSweptCollisionMode(true) self.entity:SetCollisionType(0) self.corpse:SetFriction(10,10) local maxomega=5 self.corpse:SetOmega(Vec3(math.random(-maxomega,maxomega),math.random(-maxomega,maxomega),math.random(-maxomega,maxomega))) local v = self.entity:GetVelocity() if v:Length()>1 then v=v:Normalize() end self.corpse:SetVelocity(Vec3(math.random(-1,1),math.random(-1,1),math.random(-1,1))) --self.entity:SetMass(0) -- Line deleted because game crash if you die self.entity:SetPhysicsMode(Entity.RigidBodyPhysics) end function Script:FindUsableEntity(entity) while entity~=nil do if entity.script then if type(entity.script.Use)=="function" then --If "enable" has not been set, it still won't be "false" so this will pass: if entity.script.enabled~=false then return entity else return nil end end end entity = entity:GetParent() end return nil end function Script:UpdateWorld() --Regenerate Health if self.health < self.maxHealth and self.health > 0 then local regenRate = self.healthRegen * (Time:GetSpeed()) self.health = self.health + regenRate end if self.health >= self.maxHealth then self.health = self.maxHealth end if self.health <= 0 then self.health = 0 end --Put this under post-render function: context:DrawText("Health: "..Math:Round(health).."/100",2,2) local currenttime = Time:GetCurrent() if self.lastweaponhittesttime==nil then self.lastweaponhittesttime=0 end if currenttime - self.lastweaponhittesttime>100 then self.lastweaponhittesttime=currenttime local pickinfo=PickInfo() local p1 = Transform:Point(0,0,0,self.camera,nil) local p2 = Transform:Point(0,0,0.6,self.camera,nil) local pickmode = self.entity:GetPickMode() self.entity:SetPickMode(0) --if self.entity.world:Pick(p1,p2,pickinfo,0.25) then -- self.weaponlowered=true --else -- self.weaponlowered=false --end self.entity:SetPickMode(pickmode) end if self.weaponlowered then self.weaponlowerangle = self.weaponlowerangle + 4 * Time:GetSpeed() else self.weaponlowerangle = self.weaponlowerangle - 4 * Time:GetSpeed() end self.weaponlowerangle = math.max(0,math.min(self.weaponlowerangle,90)) self.weapontag:SetRotation(self.weaponlowerangle,0,0) --Exit the function early if the player is dead if self.health<=0 then return end local window = Window:GetCurrent() local context=Context:GetCurrent() if window:KeyHit(Key.P) then self.camera:SetDebugPhysicsMode(true) end if self.isairborne==true then if self.entity:GetAirborne()==false then if self.weapons[self.currentweaponindex]~=nil then self.weapons[self.currentweaponindex]:BeginLand() end end end self.isairborne = self.entity:GetAirborne() --Mouse look self.currentMousePos = window:GetMousePosition() window:SetMousePosition(Math:Round(context:GetWidth()/2), Math:Round(context:GetHeight()/2)) self.currentMousePos.x = Math:Round(self.currentMousePos.x) self.currentMousePos.y = Math:Round(self.currentMousePos.y) if self.mousezpos==nil then self.mousezpos=0 end if self.currentMousePos.z~=self.mousezpos then if self.weapons[self.currentweaponindex] then if self.weapons[self.currentweaponindex].currentaction==nil then for n=1,math.abs(self.currentMousePos.z-self.mousezpos) do if self.currentMousePos.z>self.mousezpos then self:CycleWeapon(-1) else self:CycleWeapon(1) end end self.mousezpos=self.currentMousePos.z end else self.mousezpos=self.currentMousePos.z end end self.mouseDifference.x = Math:Curve(self.currentMousePos.x - Math:Round(context:GetWidth()/2),self.mouseDifference.x,3) self.mouseDifference.y = Math:Curve(self.currentMousePos.y - Math:Round(context:GetHeight()/2),self.mouseDifference.y,3) self.camRotation.x = Math:Clamp(self.camRotation.x + self.mouseDifference.y / self.mouseSensitivity,-90,90) self.camRotation.y = self.camRotation.y + (self.mouseDifference.x / self.mouseSensitivity) --Adjust the view shake self.hurtoffset.x = Math:Inc(0,self.hurtoffset.x,2*Time:GetSpeed()) self.hurtoffset.y = Math:Inc(0,self.hurtoffset.y,2*Time:GetSpeed()) self.smoothedhurtoffset.x = Math:Curve(self.hurtoffset.x,self.smoothedhurtoffset.x,3) self.smoothedhurtoffset.y = Math:Curve(self.hurtoffset.y,self.smoothedhurtoffset.y,3) --Set the camera angle self.camera:SetRotation(self.camRotation+self.smoothedhurtoffset) --Picking and usage local pickInfo = PickInfo() --Raycast Pick that is being send from the camera in to the world self.canUse = false local fire = false local currentime = Time:GetCurrent() if self.carryingEntity==nil then if self.weapons[self.currentweaponindex]~=nil then if self.weapons[self.currentweaponindex].automatic then if window:MouseDown(1) then fire=true else self.suspendfire=false end else if window:MouseHit(1) then fire=true end end end end --Fire weapon if self.carryingEntity==nil then if fire then if self.suspendfire~=true then if self.weapons[self.currentweaponindex].clipammo==0 and self.weapons[self.currentweaponindex].automatic==true then self.suspendfire=true end self.weapons[self.currentweaponindex]:Fire() end end end --Throw object if holding one if self.carryingEntity then if window:MouseHit(1) then local dir = Transform:Vector(0,0,self.throwforce,self.camera,nil) self.carryingEntity:AddForce(dir) self:DropEntityCarrying() end end if window:KeyHit(Key.R) then if self.weapons[self.currentweaponindex]~=nil then if type(self.weapons[self.currentweaponindex].CanReload)=="function" then if self.weapons[self.currentweaponindex]:CanReload() then self.suspendfire=false self.weapons[self.currentweaponindex]:Reload() end end end end if window:KeyHit(Key.E) then if self.carryingEntity then self:DropEntityCarrying() else local p0 = self.camera:GetPosition(true) local p1 = Transform:Point(0,0,self.useDistance,self.camera,nil) if self.entity.world:Pick(p0,p1, pickInfo, 0, true) then --Looks for any entity in the hierarchy that has a "Use" function local usableentity = self:FindUsableEntity(pickInfo.entity) if usableentity~=nil then --Use the object, whatever it may be usableentity.script:Use(self) else if self.carryingEntity == nil then mass = pickInfo.entity:GetMass() --Pick up object if it isn't too heavy if mass>0 and mass<=self.maxcarryweight then self.carryingEntity = pickInfo.entity self.carryingobjectcollisiontype = self.carryingEntity:GetCollisionType() self.carryingEntity:SetCollisionType(Collision.Debris) self.carryrotation = Transform:Rotation(pickInfo.entity:GetQuaternion(true),nil,self.camera) self.carryposition = Transform:Point(pickInfo.entity:GetPosition(true),nil,self.camera) end end end end end end --The icon that shows that an object can be picked up or can be interacted with if self.carryingEntity == nil then local p0 = self.camera:GetPosition(true) local p1 = Transform:Point(0,0,self.useDistance,self.camera,nil) if self.entity.world:Pick(p0,p1, pickInfo, 0, true) then if self:FindUsableEntity(pickInfo.entity)~=nil then self.canUse=true else local mass = pickInfo.entity:GetMass() if mass>0 and mass<=self.maxcarryweight then self.canUse = true end end end end end function Script:DropEntityCarrying() self.carryingEntity:SetCollisionType(self.carryingobjectcollisiontype) self.carryingEntity = nil end --[[This function plays footstep sounds in regular intervals as the player walks function Script:UpdateFootsteps() if self.lastfootsteptime==nil then self.lastfootsteptime=0 end if self.input[0]~=0 or self.input[1]~=0 then local speed = self.entity:GetVelocity():xz():Length() if self.entity:GetAirborne()==false then if (speed>self.moveSpeed*0.5) then local t = Time:GetCurrent() local repeatdelay = self.footstepwalkdelay if speed>self.moveSpeed * (1+(self.speedMultiplier-1)*0.5) then repeatdelay = self.footsteprundelay end if t-self.lastfootsteptime>repeatdelay then self.lastfootsteptime = t local index = math.random(1,4) self.sound.footsteps.concrete.step[index]:Play() end end end end end]] --This function will be called once per physics update function Script:UpdatePhysics() --Exit the function early if the player is dead if self.health <= 0 then return end local window = Window:GetCurrent() --Fade out the screen blood if self.bloodintensity~=nil then if self.bloodintensity>0 then self.bloodintensity = self.bloodintensity-0.01 self.bloodintensity = math.max(0,self.bloodintensity) end end --Update the footstep sounds when walking --self:UpdateFootsteps() --Toggle the flash light on and off if window:KeyHit(Key.F) then self.sound.flashlight:Play() if self.flashlight:Hidden() then self.flashlight:Show() self.flashlighton = true else self.flashlight:Hide() self.flashlighton = false end end --Apply forces to make the carried object move the way we want if self.carryingEntity then local currentpos = self.carryingEntity:GetPosition(true) local pos = Transform:Point(self.carryposition,self.camera,nil) local rot = Transform:Rotation(self.carryrotation,self.camera,nil) local maxdiff = 0.5 local diff = pos:DistanceToPoint(currentpos) --Drop the carryinItem when the distance between camera and item exceed the pickdistance if diff>1.5 then self:DropEntityCarrying() else if diff>maxdiff then pos = currentpos + (pos-currentpos):Normalize()*maxdiff diff = maxdiff end self.carryingEntity:PhysicsSetPosition(pos.x,pos.y,pos.z,0.25) self.carryingEntity:PhysicsSetRotation(rot,0.5) end end --Player Movement local movex=0 local movez=0 self.input[0]=0 self.input[1]=0 if window:KeyDown(Key.W) then self.input[1]=self.input[1]+1 end if window:KeyDown(Key.S) then self.input[1]=self.input[1]-1 end if window:KeyDown(Key.D) then self.input[0]=self.input[0]+1 end if window:KeyDown(Key.A) then self.input[0]=self.input[0]-1 end local playerMovement = Vec3(0) if self.isClimbing then playerMovement.y = self.input[1] * self.climbingSpeed playerMovement.z = self.input[1] * self.climbingSpeed self.entity:Move(0,playerMovement.y,playerMovement.z/10) else playerMovement.x = self.input[0] * self.moveSpeed playerMovement.z = self.input[1] * self.moveSpeed --This prevents "speed hack" strafing due to lazy programming if self.input[0]~=0 and self.input[1]~=0 then playerMovement = playerMovement * 0.70710678 end --if self.entity:GetAirborne() then -- playerMovement = playerMovement * 0.2 --end --Check for running with shift and when not carrying anything if self.carryingEntity == nil and window:KeyDown(Key.Shift) then if self.stamina > 0 then self.abletorun = true else self.abletorun = false end end if self.notrunning then if self.stamina <= 99 then if self.stamina == 0 then if window:KeyDown(Key.Shift) then self.stamina = self.stamina -1 end end end end if self.stamina < self.maxStamina then self.stamina = self.stamina +1 end if self.stamina == self.maxStamina then self.stamina = self.stamina +0 end if self.abletorun and window:KeyDown(Key.Shift) and window:KeyDown(Key.W) then playerMovement.z = playerMovement.z * self.speedMultiplier self.running=true else self.running=false self.notrunning=true end if self.running then self.stamina = self.stamina - (2%Time:GetCurrent()) end -- Check for jumping local jump = 0 if window:KeyHit(Key.Space) and self:IsAirborne() == 0 then jump = self.jumpForce --self.sound.footsteps.concrete.jump:Play() if self.weapons[self.currentweaponindex]~=nil then self.weapons[self.currentweaponindex]:BeginJump() end --Give the player an extra boost when jumping playerMovement = playerMovement * 1.6 end -- Check for crouching --if App.window:KeyHit(Key.ControlKey) then -- crouched = not crouched --end --With smoothing --Position camera at correct height and playerPosition self.entity:SetInput(self.camRotation.y, playerMovement.z, playerMovement.x, jump , false, 1.0, 0.5, true) end local playerPos = self.entity:GetPosition() local newCameraPos = self.camera:GetPosition() --local playerTempHeight = ((self:IsCrouched() == 1) and crouchHeight or playerHeight) newCameraPos = Vec3(playerPos.x, newCameraPos.y ,playerPos.z) if newCameraPos.y<playerPos.y + self.eyeheight then newCameraPos.y = Math:Curve(playerPos.y + self.eyeheight, newCameraPos.y, self.camSmoothing) else newCameraPos.y = playerPos.y + self.eyeheight end self.camera:SetPosition(newCameraPos) end --Return whether the player is airborne function Script:IsAirborne() return self.entity:GetAirborne() and 1 or 0 end function Script:PostRender(context) context:SetBlendMode(Blend.Alpha) context:SetColor(1,1,1,1) --[[this is if you want to see your ammo on screen if self.weapons[self.currentweaponindex]~=nil then context:DrawText("Ammo: "..self.weapons[self.currentweaponindex].clipammo.."/"..self.weapons[self.currentweaponindex].ammo,context:GetWidth()-100,context:GetHeight()-100) end]] ----------------------------------------------------------------------- --Draw the blood overlay on the screen to indicate damage local k,v for k,v in pairs(self.bloodoverlay) do if v.intensity>0 then context:SetColor(1,1,1,v.intensity*0.5) context:DrawImage(v.texture,0,0,context:GetWidth(),context:GetHeight()) if self.health>0 then v.intensity = v.intensity-0.02 * Time:GetSpeed() end else self.bloodoverlay[k]=nil end end context:SetColor(1,1,1,1) if self.health>0 then if self.canUse==true and self.carryingEntity == nil then local pickUpX = math.floor((context:GetWidth() - self.image.hand:GetWidth()))/2 local pickUpY = math.floor((context:GetHeight() - self.image.hand:GetHeight()))/2 context:SetBlendMode(Blend.Alpha) context:DrawImage(self.image.hand, pickUpX, pickUpY) else if self.carryingEntity==nil then if self.weapons[self.currentweaponindex]~=nil then if self.image.crosshair then local crossHairX = math.floor((context:GetWidth() - self.image.crosshair:GetWidth()))/2 local crossHairY = math.floor((context:GetHeight() - self.image.crosshair:GetHeight()))/2 context:SetBlendMode(Blend.Alpha) context:DrawImage(self.image.crosshair, crossHairX, crossHairY) end end end end end context:SetBlendMode(1) context:SetColor(0,0,0,0.5) local indent=8 local w = 180 local h = 40 end --Return whether the player is crouching function Script:IsAlive() return self.alive and 1 or 0 end --TakeDamage function Script:TakeDamage(damage) --Decrease health self.health = self.health - damage; --Call OnHit output self:OnHit() --If health lower or equal to zero, the player is dead if self.health == 0 then self.alive = false --Call the OnDead output self:OnDead() end end --Increase health function Script:ReceiveHealth(healthPoints)--in --Increase health self.health = self.health + healthPoints; --Health can not be more then maximum health if self.health > self.maxHealth then self.health = self.maxHealth end --Call Health received output self.component:CallOutputs("HealthReceived") end --stamina bar function Script:StaminaBar(staminaPoints) if self.running then self.stamina = self.stamina - 1 end if self.stamina > self.maxStamina then self.stamina = self.maxStamina end end --when health is zero or lower, an output call is made function Script:OnDead()--out --Extra check to make sure that the player is no longer alive if not(self:IsAlive()) then self.component:CallOutputs("Ondead") end end --when the player gets damaged we call this output function Script:OnHit()--out self.component:CallOutputs("OnHit") end function Script:GetInventory() return self.entity:FindChild("PlayerInventory").script end Quote Link to comment Share on other sites More sharing options...
havenphillip Posted December 21, 2017 Author Share Posted December 21, 2017 12 minutes ago, Roland said: Just a little note. if self.health >= self.maxHealth then self.health = self.maxHealth end if self.health <= 0 then self.health = 0 end could be replaced with self.health = Math:Clamp(self.health, 0, self.MaxHealth) Nice! That worked. I was wondering what clamp meant. Quote Link to comment Share on other sites More sharing options...
havenphillip Posted December 21, 2017 Author Share Posted December 21, 2017 Ok I figured out if I do it like this it works: local healthRegen = 0.001 * (Time:GetSpeed()) * self.healthRegen So here's everything I added to the FPSPlayer to get health regen. Thanks, ya'll: Script.healthRegen = 10 --float "Health Regen Rate" function Script:UpdateWorld() --Regenerate Health if self.health < self.maxHealth and self.health > 0 then local healthRegen = 0.001 * (Time:GetSpeed()) * self.healthRegen self.health = self.health + healthRegen end self.health = Math:Clamp(self.health, 0, self.maxHealth) Quote Link to comment Share on other sites More sharing options...
AggrorJorn Posted December 22, 2017 Share Posted December 22, 2017 Little note: those parenthesis around the Time:GetSpeed() are not needed. Quote Link to comment Share on other sites More sharing options...
havenphillip Posted December 22, 2017 Author Share Posted December 22, 2017 Sweet. Fixed. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.