Files
Gmod-PropHuntExtended/source_/gamemodes/prophuntextended/gamemode/init.lua
T
Michael Fabian 'Xaymar' Dirks e8454d4d27 Adjust paths to be lowercase
2017-11-24 01:58:31 +01:00

392 lines
13 KiB
Lua

--[[
The MIT License (MIT)
Copyright (c) 2015 Xaymar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--]]
-- ------------------------------------------------------------------------- --
--! Downloadable Lua
-- ------------------------------------------------------------------------- --
-- Shared
AddCSLuaFile("sh_init.lua")
AddCSLuaFile("sh_config.lua")
AddCSLuaFile("player_class/class_default.lua")
AddCSLuaFile("player_class/class_spectator.lua")
AddCSLuaFile("player_class/class_seeker.lua")
AddCSLuaFile("player_class/class_hider.lua")
-- Client-Only
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("client/cl_ui_help.lua")
AddCSLuaFile("client/cl_ui_teamselection.lua")
-- ------------------------------------------------------------------------- --
--! Code
-- ------------------------------------------------------------------------- --
-- Shared
include "sh_init.lua"
-- Server Only
include "compat/compat_tauntpackloader.lua"
include "server/roundmanager.lua"
include "server/states/state_prematch.lua"
include "server/states/state_preround.lua"
include "server/states/state_hide.lua"
include "server/states/state_seek.lua"
include "server/states/state_postround.lua"
include "server/states/state_postmatch.lua"
function GM:Initialize()
print("-------------------------------------------------------------------------")
print("Prop Hunt: Initializing...")
print("Prop Hunt: Registering Networked Messages...")
util.AddNetworkString("PlayerManagerInitialClientSpawn")
util.AddNetworkString("PlayerManagerClientSpawn")
util.AddNetworkString("PlayerSetHull")
util.AddNetworkString("PlayerResetHull")
util.AddNetworkString("PlayerViewOffset")
util.AddNetworkString("PlayerRegisterPropEntity")
util.AddNetworkString("PlayerEnablePropRotation")
util.AddNetworkString("PlayerDisablePropRotation")
print("Prop Hunt: Initializing Gamemode Data...")
self.Data = {}
self.Data.StartTime = CurTime()
print("Prop Hunt: Setting initial RoundManager State...")
self.RoundManager:SetState(StatePreMatch)
print("Prop Hunt: Precaching...")
GAMEMODE.Config.Taunt:Seekers()
GAMEMODE.Config.Taunt:Hiders()
print("Prop Hunt: Complete.")
print("-------------------------------------------------------------------------")
end
function GM:Think()
self.RoundManager:Tick()
end
-- Player Connected
function GM:PlayerConnect(name, ip)
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..name.."' connecting from IP '"..ip.."'.") end
end
-- Player Authenticated
function GM:PlayerAuthed(ply, steamid, uniqueid)
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") authenticated.") end
end
-- Player Disconnected
function GM:PlayerDisconnected(ply)
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") disconnected.") end
end
-- Player Spawn (Initial)
function GM:PlayerInitialSpawn(ply)
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned for the first time, applying defaults...") end
if (!ply.Data) then
-- Initialize Data Structure
ply.Data = {}
ply.Data.Alive = false
ply.Data.AliveTime = 0
ply.Data.RandomWeight = 0 -- Higher means higher chance of becoming Seeker instead of Hider.
end
-- Kill Silently
ply:KillSilent()
-- Show Team Selection Menu
ply:SetTeam(GAMEMODE.Teams.Spectators)
self:ShowTeam(ply)
-- Bot: Auto Assign to Team
if (ply:IsBot()) then
if team.NumPlayers(self.Teams.Hiders) > team.NumPlayers(self.Teams.Seekers) then
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Seekers.") end
ply:SetTeam(self.Teams.Seekers)
else
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Hiders.") end
ply:SetTeam(self.Teams.Hiders)
end
end
-- Notify Player Manager
player_manager.RunClass(ply, "InitialSpawn")
-- Signal Client
net.Start("PlayerManagerInitialClientSpawn");net.Send(ply)
end
-- Player Spawn
function GM:PlayerSpawn(ply)
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned in.") end
-- Player Manager: Assign Player Class
local class = team.GetClass(ply:Team())
if (class) then
if (ply.Data.Alive) then -- Alive Class
player_manager.SetPlayerClass(ply, class[1])
else -- Dead Class (Spectator)
player_manager.SetPlayerClass(ply, class[2])
end
else
player_manager.SetPlayerClass(ply, "Spectator")
end
-- Notify Player Manager
player_manager.OnPlayerSpawn(ply)
player_manager.RunClass(ply, "Spawn")
-- Some hooks are not called
hook.Call("PlayerSetModel", self, ply)
hook.Call("PlayerLoadout", self, ply)
-- Signal Client
net.Start("PlayerManagerClientSpawn");net.Send(ply)
end
-- Player requests Team Change
function GM:PlayerRequestTeam(ply, teamId)
if self:PlayerCanJoinTeam(ply, teamId) then
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") requested to join Team "..team.GetName(teamId)..".") end
if (ply:Team() != teamId) then
ply:KillSilent()
ply:SetTeam(teamId)
if (GetGlobalInt("RoundState", GAMEMODE.States.PreMatch) <= GAMEMODE.States.PreRound) then
ply.Alive = true
ply.AliveTime = CurTime()
end
else
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") attempted to rejoin the Team it is already in.") end
end
end
end
-- ------------------------------------------------------------------------- --
--! Player Manager Binding
-- ------------------------------------------------------------------------- --
function GM:PlayerLoadout(ply) player_manager.RunClass(ply, "Loadout") end
function GM:PlayerDeath(ply, inflictor, attacker)
player_manager.RunClass(ply, "Death", inflictor, attacker)
-- Signal Client Stuff
if IsValid(attacker) then
if attacker:IsPlayer() then
if (attacker == ply) then
net.Start("PlayerKilledSelf")
net.WriteEntity(ply)
net.Broadcast()
else
net.Start("PlayerKilledByPlayer")
net.WriteEntity(ply)
net.WriteString(inflictor:GetName())
net.WriteEntity(attacker)
net.Broadcast()
end
else
net.Start("PlayerKilled")
net.WriteEntity(ply)
net.WriteString(inflictor:GetName())
net.WriteString(attacker:GetClass())
net.Broadcast()
end
else
net.Start("PlayerKilled")
net.WriteEntity(ply)
net.WriteString(inflictor:GetName())
net.WriteString("World")
net.Broadcast()
end
end
function GM:PlayerSilentDeath(ply) player_manager.RunClass(ply, "SilentDeath") end
function GM:PostPlayerDeath(ply)
player_manager.RunClass(ply, "PostDeath")
-- Debug Mode: Respawn after Death
if (GAMEMODE.Config:Debug()) then
ply.Data.Alive = true
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Debug Mode active, Player "..ply:GetName().." was respawned.") end
end
end
function GM:DoPlayerDeath(ply, attacker, dmg) player_manager.RunClass(ply, "DoDeath", attacker, dmg) end
function GM:PlayerDeathThink(ply) return player_manager.RunClass(ply, "DeathThink") end
function GM:CanPlayerSuicide(ply) return player_manager.RunClass(ply, "CanSuicide") end
function GM:PlayerCanPickupWeapon(ply, weapon) return player_manager.RunClass(ply, "CanPickupWeapon", weapon) end
function GM:PlayerCanPickupItem(ply, item) return player_manager.RunClass(ply, "CanPickupItem", item) end
function GM:PlayerUse(ply, ent) return player_manager.RunClass(ply, "Use", ent) end
function GM:AllowPlayerPickup(ply, ent) return player_manager.RunClass(ply, "AllowPickup", ent) end
function GM:PlayerSetModel(ply) return player_manager.RunClass(ply, "SetModel") end
-- Called when an entity takes damage
function GM:EntityTakeDamage(ent, dmg)
local att = dmg:GetAttacker()
if (att) && (att:IsValid()) && (att:IsPlayer()) then
player_manager.RunClass(att, "DamageEntity", ent, att, dmg)
end
end
-- ------------------------------------------------------------------------- --
--! Gamemode Functionality
-- ------------------------------------------------------------------------- --
function GM:SetRound(Round)
SetGlobalInt("Round", Round)
end
function GM:SetRoundState(State)
SetGlobalInt("RoundState", State)
end
function GM:SetRoundTime(Time)
SetGlobalInt("RoundTime", Time)
end
function GM:SetRoundWinner(Winner)
SetGlobalInt("RoundWinner", Winner)
end
function GM:PlayerHullFromEntity(ply, ent)
if (ent) && (ent:IsValid()) then
local hmin, hmax = ent:OBBMins(), ent:OBBMaxs()
local hull = Vector(hmax.x - hmin.x, hmax.y - hmin.y, hmax.z - hmin.z)
if hull.x <= hull.y then
hull.y = hull.x
else
hull.x = hull.y
end
hull:Mul(0.5)
hull:Mul(0.95) -- Reduce size slightly
local hullmin = Vector(-hull.x, -hull.y, 0)
local hullmax = Vector(hull.x, hull.y, hull.z * 2)
ply:SetHull(hullmin, hullmax)
ply:SetHullDuck(hullmin, hullmax)
net.Start("PlayerSetHull")
net.WriteVector(hullmin)
net.WriteVector(hullmax)
net.Send(ply)
return {hullmin, hullmax}
else
ply:ResetHull()
net.Start("PlayerResetHull")
net.Send(ply)
return nil
end
end
function GM:PlayerSetViewOffset(ply, vo, voduck)
ply:SetViewOffset(vo)
ply:SetViewOffsetDucked(voduck)
if ply:Crouching() then
ply:SetCurrentViewOffset(voduck)
else
ply:SetCurrentViewOffset(vo)
end
-- Signal Client
net.Start("PlayerViewOffset")
net.WriteVector(vo)
net.WriteVector(voduck)
net.Send(ply)
end
-- ------------------------------------------------------------------------- --
--! Commands
-- ------------------------------------------------------------------------- --
-- F1/ShowHelp
function GM:ShowHelp(ply)
ply:ConCommand("ph_show_help")
end
-- F2/ShowTeam - Select Team
function GM:ShowTeam(ply)
ply:ConCommand("ph_select_team")
end
function GM:ShowSpare1(ply) player_manager.RunClass(ply, "ShowSpare1") end -- F3/ShowSpare1
function GM:ShowSpare2(ply) player_manager.RunClass(ply, "ShowSpare2") end -- F4/ShowSpare2
-- Debug Command: Print All Players
concommand.Add("ph_debug_printplayers", function(ply, cmd, args, argStr)
if GAMEMODE.Config:DebugLog() then
print ("All Players:")
for i,ply in ipairs(player.GetAll()) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..") - Team "..team.GetName(ply:Team()).. " - Alive "..tostring(ply.Data.Alive))
end
print ("Spectators:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Spectators)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
print ("Seekers:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
print ("Hiders:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Hiders)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
end
end, nil, nil, FCVAR_CLIENTCMD_CAN_EXECUTE + FCVAR_CHEAT)
-- Debug Command: Print All Players
concommand.Add("ph_debug_stats", function(ply, cmd, args, argStr)
if GAMEMODE.Config:DebugLog() then
for i,ply in ipairs(player.GetAll()) do
print(ply:GetName().." (SteamID: "..ply:SteamID()..")")
print(" Team: "..team.GetName(ply:Team()))
print(" Alive: "..tostring(ply.Data.Alive))
print(" AliveTime: "..tostring(ply.Data.AliveTime))
print(" Score: "..tostring(ply.Data.RandomWeight))
end
end
end, nil, nil, FCVAR_CLIENTCMD_CAN_EXECUTE + FCVAR_CHEAT)
-- ------------------------------------------------------------------------- --
--! Network Messages
-- ------------------------------------------------------------------------- --
net.Receive("PlayerEnablePropRotation", function(len, ply)
if (ply:Team() != GAMEMODE.Teams.Hiders) then
return
end
print("Prop Hunt: Enabling Prop Rotation")
ply:SetNWBool("PropRotation", true)
ply.Data.Prop:ApplyRotation(net.ReadAngle())
end)
net.Receive("PlayerDisablePropRotation", function(len, ply)
if (ply:Team() != GAMEMODE.Teams.Hiders) then
return
end
print("Prop Hunt: Disabling Prop Rotation")
ply:SetNWBool("PropRotation", false)
ply.Data.Prop:ApplyRotation(net.ReadAngle())
end)