I got a crouch-able player working, What it does is if the user lets go of ctrl, a picker test is made to see if the player can stand up. Here is the entire code with unfinished features:
import "Scripts/Functions/ReleaseTableObjects.lua"
--[[
Purpose: A FPS Player that walks, jumps, crouch, and can use and pickup stuff.
This is ment to be a alternative version than the one shipped with the SDK.
Keywords:
#Camera
#Movement
#Water
#KeyInput
#Flashlight
#Use
#Pickup
#Health
#Respawn
#Death
#Life
#Damage
#Hurt
#Kill
#Weapons
]]--
Script.input={}
-- Life
Script.health = 100 --float "Starting Health"
Script.savedhealth=nil
Script.maxHealth = 100
Script.alive=true
Script.bregenghealth=false --bool "Regen. Health"
Script.RegenTimer = 0
Script.RegenWaitTimer = 0
-- Camera
Script.camSmoothing = 4
Script.mouseSensitivity = 15
Script.mouseDifference = Vec2(0,0)
Script.eyeheight=1.30
-- Movement
Script.moveSpeed = 5.0
Script.footstepwalkdelay = 500
Script.footsteprundelay = 300
Script.jumpForce = 8
Script.supressmovement = false --bool "Freeze Player"
Script.allowcrouching = false -- bool "Allow Crouching"
Script.canuncrouch = false
Script.falldamage=true --bool "Fall Damage"
Script.falldamagekills=true --bool "Fall Can Kill"
Script.FallTimer= 0
-- Water
Script.UnderWater= false
-- Respawn
Script.RectangleAlpha = 0
Script.RespawnPoint=nil --entity "Respawn Point"
Script.RespawnPointPosition=Vec3(0,0,0)
Script.RespawnPointRotation=Vec3(0,0,0)
Script.RespawnTimer = 0
Script.RespawnDelay = 1.0 --float "Respawn Time"
-- Use
Script.useDistance = 2
Script.maxcarryweight=80
Script.throwforce = 500 --float "Throw Force"
-- Weapon
Script.weaponfile=""--path "Starting Weapon" "Prefab (*.pfb):pfb|Prefabs"
--Script.weaponfile="Prefabs/Gameplay/VecGun.pfb"
-- Flashlight
Script.useflashlight = false --bool "Flashlight"
Script.flashlighton= false
-- Crosshair + HUD
Script.supresscrosshair=false --bool "Hide Crosshair"
Script.supresshud=false --bool "Hide Health"
function Script:Start()
--Set the type for this object to player
self.entity:SetKeyValue("type","player")
-- If we are not a pivot, then make the editor model invisible.
if (self.entity:GetClass() ~= Object.PivotClass) then --1
System:Print("Player is not a pivot. Making entity invisible.")
material = Material:Create()
material:SetBlendMode(5)--Blend.Invisible
self.entity:SetMaterial(material)
material:Release()
end
self.savedhealth = self.health
-- Draw HUD/Crosshair
self.image={}
self.image.crosshair = Texture:Load("Materials/HUD/crosshair.tex")
self.hudfont = Font:Load("Fonts/Arial.ttf",36)
-- Sounds
self.sound={}--table to store sound in
-- Flashlight (Only if enabled.)
if self.useflashlight then
--self.sound.flashlight=Sound:Load("Sound/Player/flashlight_02_on.wav")
self.sound.flashlight=Sound:Load("Sound/Player/body_punch_03.wav")
end
-- Damage
self.sound.damage={}
self.sound.damage[1]=Sound:Load("Sound/Player/body_punch_03.wav")
self.sound.damage[2]=Sound:Load("Sound/Player/body_punch_04.wav")
self.sound.damage.fall=Sound:Load("Sound/Player/damage_fall_01.wav")
self.playfellsound= false
self.sound.damage.dead=Sound:Load("Sound/Player/death.wav")
self.playdeathsound = false
-- Footsteps
self.sound.footsteps={}
self.sound.footsteps[1] = Sound:Load("Sound/Player/Footsteps/concrete1.wav")
self.sound.footsteps[2] = Sound:Load("Sound/Player/Footsteps/concrete2.wav")
self.sound.footsteps[3] = Sound:Load("Sound/Player/Footsteps/concrete3.wav")
self.sound.footsteps[4] = Sound:Load("Sound/Player/Footsteps/concrete4.wav")
-- Jump and Land
self.sound.footsteps.jump = Sound:Load("Sound/Player/Footsteps/concrete2.wav")
self.sound.footsteps.land = Sound:Load("Sound/Player/Footsteps/concrete4.wav")
-- Use
self.sound.pickup=Sound:Load("Sound/Player/pickup.wav")
self.sound.usedeny=Sound:Load("Sound/Player/use_deny.wav")
-- Water
--self.sound.underwater=Sound:Load("Sound/Player/underwater.wav")
--self.playUnderWatersound= false
-- Ignore pickers from picking us!
self.entity:SetPickMode(0)
-- Physics
self.entity:SetCollisionType(Collision.Character)
self.entity:SetPhysicsMode(Entity.CharacterPhysics)
self.entity:SetGravityMode(true)
self.crouched=false
self.entity:SetMass(10)
if self.entity:GetMass()==0 then Debug:Error("Player mass should be greater than 0.") end
-- Create a camera
local window = Window:GetCurrent()
local context = Context:GetCurrent()
self.camera = Camera:Create()
self.camera:SetFOV(74)
self.camera:SetRange(0.05,1000)
self.camera:SetMultisampleMode((System:GetProperty("multisample","1")))
-- Set the camera's rotation to match the player
self.camRotation = self.entity:GetRotation(true)
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))
-- Tie the mouse position to the camera's rotation
window:SetMousePosition(Math:Round(context:GetWidth()/2), Math:Round(context:GetHeight()/2))
self.camera:SetRotation(self.camRotation)
--Create listener
self.listener = Listener:Create(self.camera)
--#Flashlight
if self.useflashlight then
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(25,15)
self.flashlight:SetShadowMode(Light.Dynamic+Light.Static)
if self.flashlighton==false then
self.flashlight:Hide()
end
end
-- Weapons
self.weapons={}
self.currentweaponindex=-1
self.weaponlowerangle=0
self.weapontag = Pivot:Create(self.camera)
self:LoadWeapon()
end
--This function will be called once per world update
function Script:UpdateWorld()
self:UpdateCamera()
self:UpdateOverlay()
if self.bregenghealth then
self:RegenHealth()
end
self:UpdateUse()
self:Weapon()
self:ListenForKeys()
-- If our health is 0, then we are dead.
if self.health <= 0 then
self:Kill()
-- If we have a respawn point vaild, repspawn the player after a second or so.
self.RespawnTimer = self.RespawnTimer + (Time:GetSpeed() /100)
if self.RespawnTimer > self.RespawnDelay then
self:Respawn()
end
end
end
--This function will be called once per physics update
function Script:UpdatePhysics()
if not self.supressmovement then
self:UpdateMovement()
end
self:UpdatePickupObject()
end
-- #KeyInput
function Script:ListenForKeys()
local window = Window:GetCurrent()
-- If we are in devmode, Show the camera physics models.
if System:GetProperty("dev","0")=="1" then
if window:KeyHit(Key.P) then
physics = not physics
self.camera:SetDebugPhysicsMode(physics)
end
end
--Exit the function early if the player is dead
if self:IsAlive() <= 0 then return end
self:FireWeapon(window)
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
--Toggle the #Flashlight
if self.useflashlight then
if window:KeyHit(Key.F) then
self.sound.flashlight:Play()
if self.flashlight:Hidden() then
self.flashlight:Show()
else
self.flashlight:Hide()
end
end
end
--Throw object if holding one
if self.throwforce > 0 then
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
end
-- Check for crouching
if window:KeyDown(Key.ControlKey) and self.allowcrouching then
self.crouched = true
else
if self.crouched then
self:CanUnCrouch()
if self.canuncrouch then
self.crouched = false
end
end
end
end
-- #Camera
-- Update the camera with mouse look.
function Script:UpdateCamera()
local window = Window:GetCurrent()
local context=Context:GetCurrent()
--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)
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)
self.camera:SetRotation(self.camRotation)
-------------------------------------------
--With smoothing
local playerPos = self.entity:GetPosition()
local newCameraPos = self.camera:GetPosition()
newCameraPos = Vec3(playerPos.x, newCameraPos.y ,playerPos.z)
self.crouchedheight = 1.5
if self.crouched==true then
if newCameraPos.y<playerPos.y + self.crouchedheight then
newCameraPos.y = Math:Curve(playerPos.y + self.crouchedheight, newCameraPos.y, self.camSmoothing)
else
newCameraPos.y = playerPos.y + self.crouchedheight
end
elseif 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
if self:IsAlive() >= 1 and not self.crouched then
self.camera:SetPosition(newCameraPos)
else
deathCameraPos = Vec3(playerPos.x, newCameraPos.y-0.25,playerPos.z)
self.camera:SetPosition(deathCameraPos)
end
--[[
--Not done!
local world = World:GetCurrent()
local waterenabled= world:GetWaterMode()
local height= world:GetWaterHeight()
if waterenabled then
if (self.camera:GetPosition().y < height) then
self.UnderWater = true
else
self.UnderWater = false
end
end
]]--
end
-- Test crouching. If we are undersomething, don't get up.
function Script:CanUnCrouch()
local pickInfo = PickInfo()
local p0 = self.entity:GetPosition()
local p1 = Transform:Point(0,1.6,0,self.entity,nil)
--if self.entity.world:Pick(p0,p1, pickInfo, 0, true, 3 ) then
if self.entity.world:Pick(p0,p1, pickInfo, 0, true, Collision.Prop ) then
--System:Print("NO")
self.canuncrouch = false
else
--System:Print("YES")
self.canuncrouch = true
end
end
-- Change the camera's rotation
function Script:SetCameraRotation(rot)
self.camRotation = rot
end
-- #Movement
-- Update movement
function Script:UpdateMovement()
--Exit the function early if the player is dead
if self:IsAlive() <= 0 then return end
local window = Window:GetCurrent()
--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)
playerMovement.x = self.input[0] * self.moveSpeed
playerMovement.z = self.input[1] * self.moveSpeed
if self.crouched then
playerMovement.x = self.input[0] * self.moveSpeed / 2
playerMovement.z = self.input[1] * self.moveSpeed /2
else
playerMovement.x = self.input[0] * self.moveSpeed
playerMovement.z = self.input[1] * self.moveSpeed
--Update the footstep sounds when walking
self:UpdateFootsteps()
end
--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
-- Check for jumping
local jump = 0
if window:KeyHit(Key.Space) and not self.crouched then
-- If we are not under the water, jump normally.
if not self.UnderWater and self:IsAirborne() == 0 then
jump = self.jumpForce
self.sound.footsteps.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
else
-- self.entity:AddForce(0,5,0)
end
end
--Position camera at correct height and playerPosition
self.entity:SetInput(self.camRotation.y, playerMovement.z, playerMovement.x, jump , self.crouched, 1.0, 0.5, true)
if self.isairborne==true then
if self.entity:GetAirborne()==false then
if self.weapons[self.currentweaponindex]~=nil then
self.weapons[self.currentweaponindex]:BeginLand()
end
--System:Print("Landed! Fell for " ..self.FallTimer)
if self.FallTimer > 1 then -- 0.1001
self.sound.footsteps.land:Play()
end
self.FallTimer = 0
if not self.UnderWater then
--self.camera:EmitSound(self.sound.footsteps.jump,50,1,1,false)
end
end
--System:Print("InAir")
self.FallTimer = self.FallTimer + (Time:GetSpeed() /10)
end
self.isairborne = self.entity:GetAirborne()
-- #Water
-- Handle under water movement
--[[
local world = World:GetCurrent()
local waterenabled= world:GetWaterMode()
if waterenabled then
self:UnderWaterMovement()
end
--]]
end
--[[
-- #Water (Not Done)
function Script:UnderWaterMovement()
if self.UnderWater then
self.entity:SetGravityMode(false)
if not self.playUnderWatersound then
--self.sound.underwater:Play()
self.playUnderWatersound = true
end
else
self.entity:SetGravityMode(true)
self.playUnderWatersound = false
end
end
--]]
-- Don't allow any walking movement
function Script:FreezePlayer()--in
self.supressmovement = true
end
function Script:UnFreezePlayer()--in
self.supressmovement = false
end
--Return whether the player is airborne
function Script:IsAirborne()
return self.entity:GetAirborne() and 1 or 0
end
--Return whether the player is crouching
function Script:IsCrouched()
return self.crouched and 1 or 0
end
--Return whether the player is underwater
function Script:IsUnderWater()
return self.UnderWater and 1 or 0
end
--This function plays footstep sounds in regular intervals as the player walks
function Script:UpdateFootsteps()
if self.UnderWater then return end
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[index]:Play()
end
end
end
end
end
-- #Use + #Pickup
function Script:UpdateUse()
--Exit the function early if the player is dead
if self:IsAlive() <= 0 then return end
local window = Window:GetCurrent()
local context=Context:GetCurrent()
local pickInfo = PickInfo()
--Raycast Pick that is being send from the camera in to the world
self.canUse = false
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, 3 ) then
if self.entity.world:Pick(p0,p1, pickInfo, 0, true, Collision.Prop ) 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 not self.iscarryingEntity and self.carryingEntity == nil then
mass = pickInfo.entity:GetMass()
if mass>0 and mass<=self.maxcarryweight then
self.carryingEntity = pickInfo.entity
self.iscarryingEntity = true
self.carryingobjectcollisiontype = self.carryingEntity:GetCollisionType()
self.carryingEntity:SetCollisionType(Collision.PickedUpProp)
self.sound.pickup:Play()
self.carryrotation = Transform:Rotation(pickInfo.entity:GetQuaternion(true),nil,self.camera)
self.carryposition = Transform:Point(pickInfo.entity:GetPosition(true),nil,self.camera)
end
end
-- If it's just basic geometry, play the deny sound.
local infocollisiontype = pickInfo.entity:GetCollisionType()
local infoscript = pickInfo.entity.script
if infocollisiontype==Collision.Scene and infoscript == nil then
self.sound.usedeny:Play()
end
end
else
self.sound.usedeny:Play()
--self.entity:EmitSound(self.sound.usedeny, 45 / 100, 0.5, 1, false)
end
end
end
if self.carryingEntity == nil then
local p0 = self.camera:GetPosition(true)
local p1 = Transform:Point(0,0,self.useDistance,self.camera,nil)
-- Fixed pickinfo hitting triggers! -reep
--if self.entity.world:Pick(p0,p1, pickInfo, 0, true, 3 ) then
if self.entity.world:Pick(p0,p1, pickInfo, 0, true, Collision.Prop ) then
local collisiontype = pickInfo.entity:GetCollisionType()
if (collisiontype==Collision.Prop or collisiontype==Collision.Character or 10) then
if self:FindUsableEntity(pickInfo.entity)~=nil then
self.canUse=true
else
local mass = pickInfo.entity:GetMass()
-- Has to be atleast 1kg -reep
if mass>1 and mass<=self.maxcarryweight then
self.canUse = true
end
end
end
end
end
end
-- Update the Pickuped item
function Script:UpdatePickupObject()
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
end
function Script:DropEntityCarrying()
self.carryingEntity:SetCollisionType(self.carryingobjectcollisiontype)
self.iscarryingEntity = false
self.carryingEntity = nil
end
-- Find a useable entitiy
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 or entity.script.canuse~=false then
return entity
else
self.sound.usedeny:Play()
--self.entity:EmitSound(self.sound.usedeny, 45 / 100, 0.5, 1, false)
return nil
end
end
end
entity = entity:GetParent()
end
-- If we've got nothing, play the deny use sound.
--self.sound.usedeny:Play()
return nil
end
-- #UI
-- Toggle some of the drawing
function Script:SupressCrosshair()--in
self.supresscrosshair = true
end
function Script:UnSupressCrosshair()--in
self.supresscrosshair = false
end
function Script:SupressHUD()--in
self.supresshud = true
end
function Script:UnSupressHUD()--in
self.supresshud = false
end
function Script:PostRender(context)
-- Open the context
context:SetBlendMode(Blend.Alpha)
context:SetColor(1,1,1,0.8)
-- If we are alive, draw our crosshair
if self:IsAlive() >= 1 and not self.iscarryingEntity then
-- Don't draw if the image is missing or we are hiding it.
if self.image.crosshair and not self.supresscrosshair then
local crossHairX = math.floor((context:GetWidth() - self.image.crosshair:GetWidth()))/2
local crossHairY = math.floor((context:GetHeight() - self.image.crosshair:GetHeight()))/2
context:DrawImage(self.image.crosshair, crossHairX, crossHairY)
end
end
--- DRAW ALL OTHER UI ELEMENTS YOU WISH TO BE UNDER THE OVERLAY BEFORE THIS LINE --
-- Draw a rectangle for damage indication
local x = System:GetProperty("screenwidth","1024")
local y = System:GetProperty("screenheight","768")
if not self.alive then
self.RectangleAlpha = 0.35
end
context:SetColor(1,0,0,self.RectangleAlpha)
context:DrawRect(0,0,x,y)
context:SetColor(1,1,1,1)
--- DRAW ALL OTHER UI ELEMENTS YOU WISH TO BE OVER THE OVERLAY AFTER THIS LINE --
-- If we are alive, draw our health on screen
if self:IsAlive() >= 1 and not self.supresshud then
-- Draw the background
context:SetColor(0,0,0,0.5) -- Color of Background
--context:DrawRect(8,670,140,50)
local RectX = 140
local RectY = 50
context:DrawRect(8, context:GetHeight() - RectY - 8, RectX, RectY)
-- Now the actual display of the numbers.
-- Change color depending on the health.
if self.health >= 100 or self.health > 50 then
context:SetColor(0,1,0,1) -- Green
else
if self.health <= 50 then
context:SetColor(1,1,0,1) -- Yellow
end
if self.health < 20 then
context:SetColor(1,0,0,1) -- Red
end
end
context:SetFont(self.hudfont)
--context:DrawText("+",14,684)
context:DrawText("+",14, context:GetHeight() - 46)
--context:DrawText(self.health,60,678)
context:DrawText(self.health,60,context:GetHeight() - 50)
end
context:SetColor(1,1,1,1)
context:SetBlendMode(1)
end
-- #Health
-- #Respawn
-- #Death
-- #Life
-- #Damage
-- #Hurt
-- #Kill
--Return whether the player is Alive
function Script:IsAlive()
return self.alive and 1 or 0
end
-- Fall and Physics Damage
function Script:Collision(entity,position,normal,speed)
if speed >= 20 and self.FallTimer >= 5.0 then
if self.falldamagekills then
self:Kill()
else
self:TakeDamage(1)
if not self.playfellsound then
self.camera:EmitSound(self.sound.damage.fall,5,1,1,false)
self.playfellsound = true
end
end
else
if not self.falldamage then return end
if speed > 18 then
self:TakeDamage(1)
--local index = math.random(1,4)
--self.sound.damage.fall[index]:Play()
if not self.playfellsound then
self.camera:EmitSound(self.sound.damage.fall,5,1,1,false)
self.playfellsound = true
end
else
self.playfellsound = false
end
end
--System:Print(speed)
end
--Increase health
function Script:GiveHealth(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("GiveHealth")
end
function Script:RegenHealth()
--Exit the function early if the player is dead
if self:IsAlive() <= 0 then return end
if self.health >= self.maxHealth then return end
self.RegenTimer = self.RegenTimer + (Time:GetSpeed() /100)
self.RegenWaitTimer = self.RegenWaitTimer + (Time:GetSpeed() /100)
if self.RegenWaitTimer > 0.5 then
if self.RegenTimer > 0.01 then
--Increase health
self.health = self.health + 1;
--Health can not be more then maximum health
if self.health > self.maxHealth then
self.health = self.maxHealth
end
self.RegenTimer=0
end
end
end
--TakeDamage
function Script:TakeDamage(damage)
if self.health>0 then
--Decrease health
self.health = self.health - damage;
--Stop Timer
self.RegenTimer=0
self.RegenWaitTimer=0
self.component:CallOutputs("OnTakeDamage")
-- Add redness to the overlay!
if (self.RectangleAlpha < 0.35) then
self.RectangleAlpha=self.RectangleAlpha+0.10
self.sound.damage[math.random(#self.sound.damage)]:Play()
end
end
end
-- Life, Death, and Getting Hurt...
function Script:UpdateOverlay()
if self.savedhealth ~= self.health then
if (self.RectangleAlpha ~= 0) then
self.RectangleAlpha=self.RectangleAlpha-.08*Time:GetSpeed()/10 --use getspeed to be fps independant.
end
if self.RectangleAlpha <= 0 then
self.savedhealth = self.health
end
end
end
-- Same as TakeDamage.
function Script:Hurt(damage,distributorOfPain)
self:TakeDamage(damage)
end
function Script:Kill()--in
if self:IsAlive() then
self.health = 0
self.alive = false
self.entity:SetCollisionType(Collision.Prop)
self.entity:SetPhysicsMode(Entity.RigidBodyPhysics)
self.entity:SetGravityMode(false)
self.component:CallOutputs("Kill")
if self.iscarryingEntity then
self:DropEntityCarrying()
end
if self.useflashlight then
self.flashlight:Hide()
end
if not self.playdeathsound then
self.sound.damage.dead:Play()
self.playdeathsound = true
end
end
end
-- Respawn if we have a vaild respawn point.
-- You can also make it reload a save file in this function instead of this.
function Script:Respawn()
if self.RespawnPoint ~= nil then
-- Set the health back to 100, and we are no longer dead.
self.health = 100
self.savedhealth = self.health
self.alive = true
-- Teleport to the respawn point.
local pos = self.RespawnPoint:GetPosition()
local rot = self.RespawnPoint:GetRotation()
self.RespawnPointPosition = pos
self.RespawnPointRotation = rot
self.entity:SetPosition(self.RespawnPointPosition)
self.camRotation = self.RespawnPointRotation
-- Reset other values.
self.entity:SetCollisionType(Collision.Character)
self.entity:SetPhysicsMode(Entity.CharacterPhysics)
self.entity:SetGravityMode(true)
self.RectangleAlpha = 0
self.RespawnTimer = 0
self.playdeathsound = false
self.crouched = false
end
end
function Script:SetNewRespawnPoint(entity)--in
self.RespawnPoint = entity
end
-- #Weapons
function Script:LoadWeapon()
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: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:Weapon()
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)
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)
end
function Script:FireWeapon(window)
-- Listen for Mouse clicks
local fire = false
local fire2 = 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
if window:MouseDown(2) then
fire2=true
else
self.suspendfire=false
end
else
if window:MouseHit(1) then
fire=true
end
if window:MouseHit(2) then
fire2=true
end
end
end
end
--Fire weapon
if self.carryingEntity==nil then
-- Primary
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(1)
end
end
-- Secondary
if fire2 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(2)
end
end
end
end
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: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
function Script:Release()
-- Release Listener
self.listener:Release()
-- Release #Flashlight if we have one.
if self.useflashlight then
self.flashlight:Release()
end
-- Release Tables
ReleaseTableObjects(self.sound)
ReleaseTableObjects(self.image)
-- Release weapons
local k,v
for k,v in pairs(self.weapons) do
v:Release()
end
-- Release Fonts
self.hudfont:Release()
end
Hopes this helps.