----------------------------
-- CakeScript (March 29, 2008)
-- by LuaBanana
--
-- Alpha Version
-- init.lua 
----------------------------
-- 
-- Copyright (c) 2007-2008 Robo
--
-- Permission is not granted, and is explicitly disallowed, regardless of
-- fees or charge, to any person obtaining a copy of this software and
-- associated documentation files (the "Software"), to use it in any
-- manner, including without limitation the rights to use, copy, modify,
-- merge, publish, distribute, sublicense, and/or sell copies of the Software. 
-- 
----------------------------

-- Set up the gamemode
DeriveGamemode( "sandbox" );
GM.Name = "CakeScript - SSTRP  V2";

-- Define the global variables.
CAKE = {};
CAKESCRIPT_RUNNING = true;
models = {};

/* ANIMATION HAND FIXING CODE
AnimationsAdjustment = 0;
AnimationSequence = 0;
*/

-- Server Includes
include("shared.lua");
include("player_shared.lua");
include("chat.lua");
include("chatcmds.lua");
include("concmd.lua");
include("util.lua");
include("daynight.lua");
include("admin.lua");
include("player_data.lua");
include("rp_data.lua");
include("doors.lua");
include("animations.lua");
include("items.lua");
include("plugins.lua");
include("resources.lua");
include("think.lua");
include("search.lua");
include("Loading.lua");
include("GMcommands.lua");
include("music.lua");
include("doors.lua");
include("propSaving.lua");
--include("stats.lua");
--include("dynamicFactions.lua");

-- Client Includes
AddCSLuaFile("cl_init.lua");
AddCSLuaFile("shared.lua");
AddCSLuaFile("cl_hud.lua");
AddCSLuaFile("player_shared.lua");
AddCSLuaFile("cl_binds.lua");
AddCSLuaFile("cl_charactercreate.lua");
AddCSLuaFile("cl_playermenu.lua");
AddCSLuaFile("cl_chat.lua");
AddCSLuaFile("cl_search.lua");
AddCSLuaFile("cl_adminMenu.lua");
AddCSLuaFile("cl_radioMenu.lua");
AddCSLuaFile("cl_settings.lua");
AddCSLuaFile("cl_paperDoll.lua");


--AddCSLuaFile("hudTest.lua");
-- should make these con cmds auto complete
--AddCSLuaFile("admin.lua");
--AddCSLuaFile("concmd.lua");

-- Initialize the gamemode
function GM:Initialize()

	-- Run Initialization Functions
	CAKE.InitPlayers(); -- Initialize players on gamemode reload
	CAKE.InitTime(); -- Init Date & Time
	CAKE.CreateTimers();
	--CAKE.LoadDoors(); -- moved to a hook
	
	self.BaseClass:Initialize();
	
	--CAKE.LoadProps();

	CAKE.DayLog("Gamemode Initialized");
end

--[[
local function PlayerCanPickupWeapon( ply, weap )
	if ( CurTime() <= ( ply.UseWeaponSpawn or 0 ) ) then return end
	if ( !ply:KeyDown( IN_USE ) ) then return false end
	local trace = util.QuickTrace( ply:GetShootPos(), ply:GetAimVector() * 8192, ply )
	if ( !trace.Entity || !trace.Entity:IsValid() || trace.Entity != weap ) then
		return false
	end
end
hook.Add( "PlayerCanPickupWeapon", "UseWeapon", PlayerCanPickupWeapon )

local function PlayerSpawn( ply )
	ply.UseWeaponSpawn = CurTime()
end
hook.Add( "PlayerSpawn", "UseWeapon", PlayerSpawn )
]]--

-- Player Initial Spawn
function GM:PlayerInitialSpawn(ply)

	-- spin wheels till they're ready
	-- might help
	--while( tonumber( ply:FormatSteamID() ) == nil ) do
		-- nothing
	--end

	ply:SendLua("CreateClientConVar(\"sv_benchmark_force_start\", 0, false, false)");

	CAKE.DayLog(ply:Name() .. " [" .. ply:SteamID() .. "] spawned for the first time");
	for k, v in pairs(models) do
		umsg.Start("addmodel", ply);
		
			umsg.String(v);
			
		umsg.End();
	end
	
	ply:SetNWInt("chatopen", 0);
	
	CAKE.InitTeams(ply);
	
	if(table.HasValue(SuperAdmins, ply:SteamID())) then ply:SetUserGroup("superadmin"); end
	if(table.HasValue(Admins, ply:SteamID())) then ply:SetUserGroup("admin"); end
	
	--ply:LoadPlayerData();
	
Msg("Calling load on player.\n");
	
	CAKE.LoadPlayerDataFile( ply );
	
	ply.LastOOC = 0;
	
	-- shouldn't happen under new system
	--if(CharTable[ply:FormatSteamID()] == nil) then
	
		--CharTable[ply:FormatSteamID()] = {}
		
	--end
	
	/*
	local PlyCharTable = CharTable[ply:FormatSteamID()]
	
	-- Find the highest Unique ID
	local high = 0;
	
	for k, v in pairs(PlyCharTable) do
	
		k = tonumber(k);
		high = tonumber(high);
		
		if( k != nil and k > high) then 
		
			high = k;
			
		end
		
	end
	
	high = high + 1;
	ply:SetNWString("uid", tostring(high));
	
	ply:SetNWInt("charactercreate", 1)
	ply:SetNWString("steamid", ply:SteamID());

	for k, v in pairs(PlyCharTable) do
	
		if ( tonumber(k) != nil ) then
		
			umsg.Start("ReceiveChar", ply);
				umsg.Long(k);
				umsg.String(v["rpname"]);
				umsg.String(v["info.model"]);
			umsg.End();
		else
		
		end
		
	end
	
	local function delayed_umsg()
		umsg.Start("charactercreate", ply);
		umsg.End();
	end
	*/
	
	-- shouldn't need this with hooking (i hope )
	-- having the client tell the server when its ready from now on
	--timer.Simple(3, delayed_umsg);

	self.BaseClass:PlayerInitialSpawn(ply)
	
	-- some bugs due to chat being setup but neither open nor closed.
	if( CLIENT ) then
		OpenChat();
		CloseChat();
	end

end
--hook.Add("PlayerInitialSpawn", "CakePlayerInitialSpawn", CAKE.PlayerInitialSpawn );

function NotifyAll_Console(text)
	for k, v in pairs(player.GetAll()) do
		v:PrintMessage(HUD_PRINTCONSOLE, text)
	end
end

function GM:CanTool(ply, tr, toolmode)

	if( !ply:IsSuperAdmin() and ( CAKE.IsDoor(tr.Entity) or tr.Entity:IsPlayer() ) ) then return false; end
	if( !ply:IsSuperAdmin() and tr.Entity:GetClass() == "prop_ragdoll" and tr.Entity:GetNWInt("playerragdoll") == 1 ) then return false; end
	NotifyAll_Console(ply:Name() .. " used " .. toolmode .. " on " .. tr.Entity:GetClass());
	CAKE.DayLog(ply:Nick() .. " [" .. ply:SteamID() .. "] used " .. toolmode .. " on " .. tr.Entity:GetClass());
	
	return true;
end

DecayingRagdolls = {}

function GM:PlayerSpawn(ply)

	if( CLIENT ) then
		OpenChat();
		CloseChat();
	end

	CAKE.DayLog(ply:Name() .. " [" .. ply:SteamID() .. "] spawned");

	ply:StripWeapons();
	
	self.BaseClass:PlayerSpawn(ply)
	

	
	ply:SetNWFloat("conscious", 100);
	ply:SetNWInt("ko", 0);
	ply:SetNWInt("ragdoll", 0);
	
	ply:SetDefaultVars();
	if (ply:GetNWInt("flaggedmi") == 1) then
		ply:ConCommand("say /mi")
	end
	
	
	
	-- reset their paper doll's damage
	umsg.Start("resetDamage", ply);
	umsg.End();

end
--hook.Add("PlayerSpawn", "CakePlayerSpawn", CAKE.PlayerSpawn);


function GM:KeyPress( ply, code )

	if( code == IN_SPEED or code == IN_RUN ) then
		ply:SetNWInt("lastjump", CurTime() );
	end

	if( code == IN_JUMP ) then
		ply:SetNWFloat( "sprint", math.Clamp( ply:GetNWInt( "sprint" ) - 5, 0, 100) );
		ply:SetNWInt("lastjump", CurTime() );
	end

end

-- Called whenever an entity takes damage
function GM:EntityTakeDamage( ent, inflictor, attacker, amount, dmginfo )

	if( ent:IsPlayer() ) then
	
		ent:SetNWInt("lasthurt", CurTime() );
	
	end

end


-- Use this to set duck speed correctly. Seems the engine uses the walk speed for duck speed, so change it here.
-- This is the same as editing the hook, but this is more clear to me.
function GM:SetupMove( ply, move )

	if ( not ply:IsValid() or not ply:IsConnected() or not ply:Alive() or ply:GetNWInt( "ko" ) == 1 ) then
		return;
	end

	local vel = ply:GetVelocity():Length();
	
	-- Sprint speeds.
	if ( ply:KeyDown(IN_SPEED) and vel > 10 and ply:GetNWInt("tiedup") == 0 and ply:GetNWFloat("sprint") > 1 and ply:GetActiveWeapon() != "weapon_support_1" ) then
		
			--move:SetMaxClientSpeed( 320 );
			ply:SetRunSpeed( 320 );
			ply:SetNWFloat( "sprint", math.Clamp( ply:GetNWFloat( "sprint" ) - 0.15, 0, 100 ) );

	elseif( ply:KeyDown(IN_DUCK) ) then
	
		-- ply:SetCrouchedWalkSpeed doesn't seem to do anything
	
		-- ducking
		if ( ply:GetNWInt("tiedup") == 1 ) then
			ply:SetWalkSpeed( 110 );
			ply:SetRunSpeed( 110 );
			return;
		else
			ply:SetWalkSpeed( 140 );
			ply:SetRunSpeed( 140 );
			return;
		end
	
	else
	
		-- Must be walking
		if ( ply:GetNWInt("tiedup") == 1 ) then
			ply:SetWalkSpeed( 100 );
			ply:SetRunSpeed( 100 );
			return;
		else
			ply:SetWalkSpeed( 110 );
			ply:SetRunSpeed( 110 );
			return;
		end
	
	end
	
end


function GM:PlayerSetModel(ply)

	if(Teams[ply:Team()] != nil) then
	
		if(Teams[ply:Team()]["DefaultModel"] == true) then
		
			if(Teams[ply:Team()]["PartialModel"] == true) then
			
				ply:SetModel(Teams[ply:Team()]["DefaultModelPath"] .. string.sub(ply:GetNWString("info.model"), 23, string.len(ply:GetNWString("info.model"))))
			
			else
			
				ply:SetModel(Teams[ply:Team()]["DefaultModelPath"]);
				
			end
			
		else
		
			ply:SetModel(ply:GetNWString("info.model"));
			
		end
		
	else
	
		ply:SetModel("models/player/kleiner.mdl");
		
	end
	
end

function GM:PlayerLoadout(ply)

	if(ply:GetNWInt("charactercreate") != 1) then
	
		if(ply:GetAccField("tooltrust") == 1 or ply:IsAdmin() or ply:IsSuperAdmin()) then ply:Give("gmod_tool"); end
		
		if(Teams[ply:Team()] != nil) then
		
			for k, v in pairs(Teams[ply:Team()]["Weapons"]) do
			
				ply:Give(v);
				
			end
			
			for k, v in pairs(Teams[ply:Team()]["Ammo"]) do
			
				ply:GiveAmmo(v);
				
			end
			
		end

		ply:Give("weapon_physgun");
		ply:Give("weapon_physcannon");
		ply:Give("hands");
		
		ply:SelectWeapon("hands");
		ply:DrawViewModel( false );
		
	end
	
end



function GM:DoPlayerDeath( ply, attacker, dmginfo )
        ply:CreateRagdoll() 
        ply:AddDeaths( 1 )
end

--[[
function GM:PlayerDeathThink(ply)

	ply.nextsecond = ply.nextsecond or CurTime()
	ply.deathtime = ply.deathtime or 120;
	
	if(CurTime() > ply.nextsecond) then
	
		if(ply.deathtime < 120) then
		
			ply.deathtime = ply.deathtime + 1;
			ply.nextsecond = CurTime() + 1;
			ply:SetNWInt("deathmoderemaining", 120 - ply.deathtime);
			
		else
		
			ply.deathtime = nil;
			ply.nextsecond = nil;
			ply:Spawn();
			ply:SetNWInt("deathmode", 0);
			ply:SetNWInt("deathmoderemaining", 0);
			
		end
		
	end
	
end
]]--
