local PlayerMeta = FindMetaTable( "Player" ) util.AddNetworkString('deathmenu') function PlayerMeta:SendMessage( text, duration, color ) if ( !IsValid( self ) ) then return end local duration = duration or 3 local color = color or color_white umsg.Start( "gms_sendmessage", self ) umsg.String( text ) umsg.Short( duration ) umsg.String( color.r .. "," .. color.g .. "," .. color.b .. "," .. color.a ) umsg.End() end function PlayerMeta:OpenCombiMenu( str ) umsg.Start( "gms_OpenCombiMenu", self ) umsg.String( str ) umsg.End() end function PlayerMeta:DeathMenu( res, wep ) net.Start('deathmenu') net.WriteTable(res) net.WriteTable(wep) net.Send(self) end function PlayerMeta:SendAchievement( text ) umsg.Start( "gms_sendachievement", self ) umsg.String( text ) umsg.End() local sound = CreateSound( self, Sound( "music/hl1_song11.mp3" ) ) sound:Play() timer.Simple( 5.5, function() sound:Stop() end ) end function PlayerMeta:SetSkill( skill, int ) skill = string.Capitalize( skill ) if ( !self.Skills[ skill ] ) then self.Skills[ skill ] = 0 end if ( skill != "Survival" ) then int = math.Clamp( int, 0, 200 ) else self.MaxResources = ( int * 5 ) + 25 end self.Skills[ skill ] = int umsg.Start( "gms_SetSkill", self ) umsg.String( skill ) umsg.Short( self:GetSkill( skill ) ) umsg.End() end function PlayerMeta:GetSkill( skill ) skill = string.Capitalize( skill ) if ( skill == "Survival" ) then self:SetNWInt( skill, self.Skills[skill] ) end return self.Skills[ skill ] or 0 end function PlayerMeta:IncSkill( skill, int ) skill = string.Capitalize( skill ) if ( !self.Skills[ skill ] ) then self:SetSkill( skill, 0 ) end if ( !self.Experience[ skill ] ) then self:SetXP( skill, 0 ) end if ( skill != "Survival" ) then int = math.Clamp( int, 0, 200 ) for id = 1, int do self:IncXP( "Survival", 20 ) end self:SendMessage( string.Replace( skill, "_", " " ) .. " +" .. int, 3, Color( 10, 200, 10, 255 ) ) else self.MaxResources = self.MaxResources + 5 self:SendAchievement( "Level Up!" ) end self.Skills[skill] = self.Skills[skill] + int umsg.Start( "gms_SetSkill", self ) umsg.String( skill ) umsg.Short( self:GetSkill( skill ) ) umsg.End() self:CheckForUnlocks() end function PlayerMeta:DecSkill( skill, int ) skill = string.Capitalize( skill ) self.Skills[skill] = math.max( self.Skills[skill] - int, 0 ) umsg.Start( "gms_SetSkill", self ) umsg.String( skill ) umsg.Short( self:GetSkill( skill ) ) umsg.End() end function PlayerMeta:SetXP( skill, int ) skill = string.Capitalize( skill ) if ( !self.Skills[skill] ) then self:SetSkill( skill, 0 ) end if ( !self.Experience[skill] ) then self.Experience[skill] = 0 end self.Experience[skill] = int umsg.Start( "gms_SetXP", self ) umsg.String( skill ) umsg.Short( self:GetXP( skill ) ) umsg.End() end function PlayerMeta:GetXP( skill ) skill = string.Capitalize( skill ) return self.Experience[skill] or 0 end function PlayerMeta:IncXP( skill, int ) skill = string.Capitalize( skill ) if ( !self.Skills[skill] ) then self.Skills[skill] = 0 end if ( !self.Experience[skill] ) then self.Experience[skill] = 0 end if ( self.Experience[skill] + int >= 100 ) then self.Experience[skill] = 0 self:IncSkill( skill, 1 ) else self.Experience[skill] = self.Experience[skill] + int end umsg.Start( "gms_SetXP", self ) umsg.String( skill ) umsg.Short( self:GetXP( skill ) ) umsg.End() end function PlayerMeta:DecXP( skill, int ) skill = string.Capitalize( skill ) self.Experience[skill] = self.Experience[skill] - int umsg.Start( "gms_SetXP", self ) umsg.String( skill ) umsg.Short( self:GetXP( skill ) ) umsg.End() end function PlayerMeta:SetResource( resource, int ) resource = string.Capitalize( resource ) if ( !self.Resources[resource] ) then self.Resources[resource] = 0 end self.Resources[resource] = int umsg.Start( "gms_SetResource", self ) umsg.String( resource ) umsg.Short( int ) umsg.End() end function PlayerMeta:GetResource( resource ) resource = string.Capitalize( resource ) return self.Resources[ resource ] or 0 end function PlayerMeta:IncResource( resource, int ) resource = string.Capitalize( resource ) if ( !self.Resources[resource] ) then self.Resources[resource] = 0 end local all = self:GetAllResources() local max = self.MaxResources if ( all + int > max ) then self.Resources[resource] = self.Resources[resource] + ( max - all ) self:DropResource( resource, ( all + int ) - max ) self:SendMessage( "You can't carry anymore!", 3, Color( 200, 0, 0, 255 ) ) else self.Resources[resource] = self.Resources[resource] + int end umsg.Start( "gms_SetResource", self ) umsg.String( resource ) umsg.Short( self:GetResource( resource ) ) umsg.End() end function PlayerMeta:DecResource( resource, int ) if ( !self.Resources[resource] ) then self.Resources[resource] = 0 end self.Resources[resource] = self.Resources[resource] - int local r = self.Resources[resource] if ( resource == "Flashlight" and r < 1 ) then self:Flashlight( false ) end if ( resource == "Batteries" ) then local maxPow = 50 if ( r ) then maxPow = math.min( maxPow + r * 50, 500 ) end self.Power = math.min( self.Power, maxPow ) self:UpdateNeeds() end umsg.Start( "gms_SetResource", self ) umsg.String( resource ) umsg.Short( self:GetResource( resource ) ) umsg.End() end function PlayerMeta:GetAllResources() local num = 0 for k, v in pairs( self.Resources ) do num = num + v end return num end function PlayerMeta:CreateBuildingSite( pos, angle, model, class, cost ) local rep = ents.Create( "gms_buildsite" ) rep:SetPos( pos ) rep:SetAngles( angle ) rep.Costs = cost rep:Setup( model, class ) rep:Spawn() rep.Player = self rep.OwnerTable = { Team = self:Team(), SteamID = self:SteamID(), Name = self:Name(), EntIndex = self:EntIndex() } self:SetNetworkedEntity( "Hasbuildingsite", rep ) SPropProtection.PlayerMakePropOwner( self , rep ) return rep end function PlayerMeta:CreateStructureBuildingSite( pos, angle, model, class, cost, name ) local NoDropModels = { "models/props_c17/furniturefireplace001a.mdl", "models/props_c17/factorymachine01.mdl", "models/Gibs/airboat_broken_engine.mdl", "models/props_c17/furniturestove001a.mdl", "models/props_wasteland/controlroom_desk001b.mdl", "models/props_c17/FurnitureFridge001a.mdl", "models/props_lab/reciever_cart.mdl", "models/props_trainstation/trainstation_clock001.mdl" } local rep = ents.Create( "gms_buildsite" ) local str = ":" for k, v in pairs( cost ) do str = str .. "\n" .. string.Replace( k, "_", " " ) .. " ( " .. v .. "x )" end rep:SetAngles( angle ) rep.Costs = cost rep:Setup( model, class ) rep:SetPos( pos ) rep.Name = name rep:SetNWString( "Name", name ) rep:SetNWString( "Resources", str ) rep:Spawn() local cormin, cormax = rep:WorldSpaceAABB() local offset = cormax - cormin if ( model == "models/props_c17/FurnitureFridge001a.mdl" ) then pos = pos + Vector( 0, 0, 10 ) end rep:SetPos( Vector( pos.x, pos.y, pos.z + ( offset.z / 2 ) ) ) if ( !table.HasValue( NoDropModels, model ) ) then rep:DropToGround() end self:SetNWEntity( "Hasbuildingsite", rep ) rep.Player = self rep.OwnerTable = { Team = self:Team(), SteamID = self:SteamID(), Name = self:Name(), EntIndex = self:EntIndex() } SPropProtection.PlayerMakePropOwner( self, rep ) return rep end function PlayerMeta:GetBuildingSite() return self:GetNWEntity( "Hasbuildingsite" ) end function PlayerMeta:DropResource( resource, int ) local nearby = {} for k, v in pairs( ents.FindByClass( "gms_resource*" ) ) do if ( v:GetPos():Distance( self:GetPos() ) < 150 ) then if ( v:GetClass() == "gms_resourcedrop" and v.Type != resource ) then else table.insert( nearby, v ) end end end for id, ent in pairs( nearby ) do if ( !SPropProtection.PlayerCanTouch( self, ent ) ) then continue end if ( ent:GetClass() == "gms_resourcedrop" ) then ent.Amount = ent.Amount + int ent:SetResourceDropInfoInstant( ent.Type, ent.Amount ) return else if ( !ent.Resources ) then ent.Resources = {} end if ( ent.Resources[ resource ] ) then ent.Resources[ resource ] = ent.Resources[ resource ] + int else ent.Resources[ resource ] = int end ent:SetResPackInfo( resource, ent.Resources[ resource ] ) return end end local ent = ents.Create( "gms_resourcedrop" ) ent:SetPos( self:TraceFromEyes( 60 ).HitPos + Vector( 0, 0, 15 ) ) ent:SetAngles( self:GetAngles() ) ent:Spawn() ent:GetPhysicsObject():Wake() ent.Type = resource ent.Amount = int ent:SetResourceDropInfo( ent.Type, ent.Amount ) SPropProtection.PlayerMakePropOwner( self, ent ) end function PlayerMeta:SetFood( int ) if ( int > 1000 ) then int = 1000 end self.Hunger = int self:UpdateNeeds() end function PlayerMeta:SetThirst( int ) if ( int > 1000 ) then int = 1000 end self.Thirst = int self:UpdateNeeds() end function PlayerMeta:Heal( int ) self:SetHealth( math.min( self:Health() + int, self:GetMaxHealth() ) ) end function PlayerMeta:AddUnlock( text ) self.FeatureUnlocks[text] = 1 umsg.Start( "gms_AddUnlock", self ) umsg.String( text ) umsg.End() if ( GMS.FeatureUnlocks[text].OnUnlock ) then GMS.FeatureUnlocks[text].OnUnlock( self ) end end function PlayerMeta:HasUnlock( text ) if ( self.FeatureUnlocks and self.FeatureUnlocks[text] ) then return true end return false end function PlayerMeta:CheckForUnlocks() for k, unlock in pairs( GMS.FeatureUnlocks ) do if ( !self:HasUnlock( k ) ) then local NrReqs = 0 for skill, value in pairs( unlock.Req ) do if ( self:GetSkill( skill ) >= value ) then NrReqs = NrReqs + 1 end end if ( NrReqs == table.Count( unlock.Req ) ) then self:AddUnlock( k ) end end end end function PlayerMeta:TraceFromEyes( dist ) return util.TraceLine( { start = self:GetShootPos(), endpos = self:GetShootPos() + ( self:GetAimVector() * dist ), filter = self } ) end function PlayerMeta:UpdateNeeds() umsg.Start( "gms_setneeds", self ) umsg.Short( self.Sleepiness ) umsg.Short( self.Hunger ) umsg.Short( self.Thirst ) umsg.Short( self.Oxygen ) umsg.Short( self.Power ) umsg.Short( Time ) umsg.End() end function PlayerMeta:PickupResourceEntity( ent ) if ( !SPropProtection.PlayerCanTouch( self, ent ) ) then return end local int = ent.Amount local room = self.MaxResources - self:GetAllResources() if ( room <= 0 ) then self:SendMessage( "You can't carry anymore!", 3, Color( 200, 0, 0, 255 ) ) return end if ( room < int ) then int = room end ent.Amount = ent.Amount - int if ( ent.Amount <= 0 ) then ent:Fadeout() else ent:SetResourceDropInfo( ent.Type, ent.Amount ) end self:IncResource( ent.Type, int ) self:SendMessage( "Picked up " .. string.Replace( ent.Type, "_", " " ) .. " ( " .. int .. "x )", 4, Color( 10, 200, 10, 255 ) ) end function PlayerMeta:PickupResourceEntityPack( ent ) if ( !SPropProtection.PlayerCanTouch( self, ent ) ) then return end if ( table.Count( ent.Resources ) > 0 ) then for res, int in pairs( ent.Resources ) do local room = self.MaxResources - self:GetAllResources() if ( room <= 0 ) then self:SendMessage( "You can't carry anymore!", 3, Color( 200, 0, 0, 255 ) ) return end if ( room < int ) then int = room end ent.Resources[res] = ent.Resources[res] - int ent:SetResPackInfo( res, ent.Resources[res] ) if ( ent.Resources[res] <= 0 ) then ent.Resources[res] = nil end self:IncResource( res, int ) self:SendMessage( "Picked up " .. string.Replace( res, "_", " " ) .. " ( " .. int .. "x )", 4, Color( 10, 200, 10, 255 ) ) end end end function PlayerMeta:MakeLoadingBar( msg ) umsg.Start( "gms_MakeLoadingBar", self ) umsg.String( msg ) umsg.End() end function PlayerMeta:StopLoadingBar() umsg.Start( "gms_StopLoadingBar",self ) umsg.End() end function PlayerMeta:MakeSavingBar( msg ) umsg.Start( "gms_MakeSavingBar", self ) umsg.String( msg ) umsg.End() end function PlayerMeta:StopSavingBar() umsg.Start( "gms_StopSavingBar", self ) umsg.End() end function PlayerMeta:AllSmelt( ResourceTable ) local resourcedata = {} resourcedata.Req = {} resourcedata.Results = {} local AmountReq = 0 for k, v in pairs( ResourceTable.Req ) do if ( self:GetResource( k ) > 0 ) then if ( self:GetResource( k ) <= ResourceTable.Max ) then resourcedata.Req[k] = self:GetResource( k ) AmountReq = AmountReq + self:GetResource( k ) else resourcedata.Req[k] = ResourceTable.Max AmountReq = AmountReq + ResourceTable.Max self:SendMessage( "You can only do " .. tostring( ResourceTable.Max ) .. " " .. string.Replace( k, "_", " " ) .. " at a time.", 3, Color( 200, 0, 0, 255 ) ) end else resourcedata.Req[k] = 1 end end for k, v in pairs( ResourceTable.Results ) do resourcedata.Results[k] = AmountReq end return resourcedata end function PlayerMeta:Sleep() if ( !self:Alive() or self:GetNWBool( "Sleeping" ) or self:GetNWBool( "AFK" ) ) then return end if ( self.Sleepiness > 700 ) then self:SendMessage( "You're not tired enough.", 3, Color( 255, 255, 255, 255 ) ) return end self:SetNWBool( "Sleeping", true ) self:Freeze( true ) -- Check for shelter local tr = util.TraceLine( { start = self:GetShootPos(), endpos = self:GetShootPos() + ( self:GetUp() * 300 ), filter = self } ) self.NeedShelter = false if ( !tr.HitWorld and !tr.HitNonWorld ) then self.NeedShelter = true end self:EmitSound( "stranded/start_sleeping.wav" ) end function PlayerMeta:Wakeup() if ( !self:GetNWBool( "Sleeping" ) ) then return end self:SetNWBool( "Sleeping", false ) self:Freeze( false ) --Check for shelter local trace = {} trace.start = self:GetShootPos() trace.endpos = trace.start + ( self:GetUp() * 300 ) trace.filter = self local tr = util.TraceLine( trace ) if ( self.NeedShelter ) then self:SendMessage( "I should get something to sleep under next time...", 6, Color( 200, 0, 0, 255 ) ) else self:SendMessage( "Ah, nothing like a good nights sleep!", 5, Color( 255, 255, 255, 255 ) ) end end