Initial Commit

This commit is contained in:
2026-01-04 18:21:33 -06:00
commit 1d676526fe
133 changed files with 10359 additions and 0 deletions

34
gamemode/cl_init.lua Normal file
View File

@@ -0,0 +1,34 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
include "sh_init.lua";

View File

@@ -0,0 +1,79 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
DEFINE_BASECLASS( "player_default" )
local PLAYER = {}
PLAYER.DisplayName = "Guard"
PLAYER.WalkSpeed = 260
PLAYER.RunSpeed = 325
PLAYER.CrouchedWalkSpeed = 0.4
PLAYER.DuckSpeed = 0.3
PLAYER.UnDuckSpeed = 0.3
PLAYER.JumpPower = 200
PLAYER.CanUseFlashlight = true
PLAYER.MaxHealth = 100
PLAYER.StartHealth = 100
PLAYER.StartArmor = 50
PLAYER.DropWeaponOnDie = true
PLAYER.AvoidPlayers = false
function PLAYER:Spawn()
self.Player:SetPlayerColor(Vector(.6,.9,1));
self.Player:SetWeaponColor(Vector(.6,.9,1));
end
local randomGuardSidearms = {"weapon_jb_deagle","weapon_jb_usp","weapon_jb_fiveseven"};
local randomGuardPrimary = {"weapon_jb_ak47","weapon_jb_aug","weapon_jb_galil","weapon_jb_m4a1","weapon_jb_mac10","weapon_jb_mp5navy","weapon_jb_p90","weapon_jb_scout","weapon_jb_sg552","weapon_jb_ump"};
function PLAYER:Loadout()
self.Player:Give("weapon_jb_fists");
self.Player:Give( table.Random( randomGuardSidearms ) )
self.Player:Give( table.Random( randomGuardPrimary ) );
self.Player:GiveAmmo( 255, "Pistol", true )
self.Player:GiveAmmo( 512, "SMG1", true )
end
function PLAYER:SetupDataTables()
self.Player:NetworkVar( "Bool", 1, "InGuardZone" );
end
util.PrecacheModel( "models/player/police.mdl" )
function PLAYER:SetModel()
self.Player:SetModel( "models/player/police.mdl" )
end
player_manager.RegisterClass( "player_guard", PLAYER, "player_default" )

View File

@@ -0,0 +1,144 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
DEFINE_BASECLASS( "player_default" )
local PLAYER = {}
PLAYER.DisplayName = "Prisoner"
PLAYER.WalkSpeed = 260
PLAYER.RunSpeed = 310
PLAYER.CrouchedWalkSpeed = 0.4
PLAYER.DuckSpeed = 0.3
PLAYER.UnDuckSpeed = 0.3
PLAYER.JumpPower = 200
PLAYER.CanUseFlashlight = false
PLAYER.MaxHealth = 100
PLAYER.StartHealth = 100
PLAYER.StartArmor = 50
PLAYER.DropWeaponOnDie = false
PLAYER.AvoidPlayers = false
function PLAYER:Spawn()
self.Player:SetPlayerColor(Vector(.9,.9,.9));
self.Player:SetWeaponColor(Vector(.9,.9,.9));
self.Player:SetRebel(false);
self.Player:GiveAmmo( 50, "Pistol", true )
self.Player:GiveAmmo( 100, "SMG1", true )
end
local randomSpecialWeapon = {
"weapon_jb_knife",
}
function PLAYER:Loadout()
self.Player:Give("weapon_jb_fists");
if math.random(1,JB.Config.prisonerSpecialChance) == 1 then
self.Player:Give(table.Random(randomSpecialWeapon)); -- give the player a rando waeapon from our table.
end
end
function PLAYER:SetupDataTables()
self.Player:NetworkVar( "Bool", 0, "Rebel" );
self.Player:NetworkVar( "Bool", 1, "InGuardZone" );
end
local prisonerModels = {
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_03.mdl"),
Model("models/player/Group01/female_05.mdl"),
Model("models/player/Group01/male_01.mdl"),
Model("models/player/Group01/male_03.mdl"),
Model("models/player/Group01/female_02.mdl"),
Model("models/player/Group01/female_01.mdl"),
Model("models/player/Group01/female_04.mdl"),
Model("models/player/Group01/female_06.mdl"),
Model("models/player/Group01/male_02.mdl"),
Model("models/player/Group01/male_04.mdl"),
Model("models/player/Group01/male_05.mdl"),
Model("models/player/Group01/male_06.mdl"),
Model("models/player/Group01/male_07.mdl"),
Model("models/player/Group01/male_08.mdl"),
Model("models/player/Group01/male_09.mdl"),
}
function PLAYER:SetModel()
self.Player:SetModel( string.lower(table.Random(prisonerModels)) )
end
player_manager.RegisterClass( "player_prisoner", PLAYER, "player_default" )

View File

@@ -0,0 +1,42 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
DEFINE_BASECLASS( "player_default" )
local PLAYER = {}
PLAYER.DisplayName = "Spectator"
PLAYER.WalkSpeed = 260
PLAYER.RunSpeed = 260
PLAYER.DuckSpeed = 1
player_manager.RegisterClass( "player_spectator", PLAYER, "player_default" )

View File

@@ -0,0 +1,196 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local matPointerBg = Material("jailbreak_excl/pointers/pointer_background.png");
local bubbles = {};
local popModelMatrix = cam.PopModelMatrix
local pushModelMatrix = cam.PushModelMatrix
local pushFilterMag = render.PushFilterMag;
local pushFilterMin = render.PushFilterMin;
local popFilterMag = render.PopFilterMag;
local popFilterMin = render.PopFilterMin;
local setColor = surface.SetDrawColor;
local setMaterial = surface.SetMaterial;
local drawTexturedRect = surface.DrawTexturedRect;
local matrix = Matrix()
local matrixScale = Vector(0, 0, 0)
local matrixTranslation = Vector(0, 0, 0)
local scale=1;
local size = 350;
local x,y,steps,mul;
local selection=0;
local contextEnabled = false;
local color=Color(255,255,255,0);
local color_black = Color(0,0,0,0);
hook.Add("HUDPaintOver","JB.HUDPaintOver.PaintContextMenu",function()
mul=FrameTime()*10;
scale = Lerp(mul,scale,contextEnabled and 1 or 0);
color.a = Lerp(mul,color.a,contextEnabled and 255 or 0)
color_black.a = color.a;
if (color.a < 1) then return end
x,y = ScrW()/2 - ((size + 128)*scale)/2,ScrH()/2 - ((size + 128)*scale)/2;
pushFilterMag( TEXFILTER.ANISOTROPIC )
pushFilterMin( TEXFILTER.ANISOTROPIC )
matrix=Matrix();
matrixTranslation.x = x;
matrixTranslation.y = y;
matrix:SetTranslation( matrixTranslation )
matrixScale.x = scale;
matrixScale.y = scale;
matrix:Scale( matrixScale )
steps = 2 * math.pi / #bubbles;
pushModelMatrix( matrix )
for k,v in pairs(bubbles)do
if not v.ang then v.ang = 0 end;
v.ang= Lerp(mul,v.ang,(math.pi + (k-1)*steps) % (2*math.pi));
x,y= (size + 64)/2 + math.sin(v.ang) * size/2,(size + 64)/2 + math.cos(v.ang) * size/2;
setMaterial(matPointerBg);
if not v.color then v.color = Color(50,50,50,0) end
v.color.a = color.a;
if v.selected then
v.color.r = Lerp(mul,v.color.r,255);
v.color.g = Lerp(mul,v.color.g,255);
v.color.b = Lerp(mul,v.color.b,255);
else
v.color.r = Lerp(mul,v.color.r,180);
v.color.g = Lerp(mul,v.color.g,180);
v.color.b = Lerp(mul,v.color.b,180);
end
setColor(v.color);
drawTexturedRect(x-32,y-32,128,128);
if v.icon then
setMaterial(v.icon);
drawTexturedRect(x+16,y+16,32,32);
end
draw.DrawText(v.text,"JBNormalShadow",x+32,y+64+14,color_black,1);
draw.DrawText(v.text,"JBNormal",x+32,y+64+14,color,1);
end
popModelMatrix()
popFilterMag()
popFilterMin()
end);
local xRel,yRel,ang;
hook.Add("Think","JB.Think.ContextMenuLogic",function()
if (color.a < 250) then return end
steps = 2 * math.pi / #bubbles;
xRel,yRel=(-ScrW()/2 + gui.MouseX()) + (size/2),(-ScrH()/2 + gui.MouseY()) + (size/2);
for k,v in pairs(bubbles)do
x,y= (size + 64)/2 + math.sin(v.ang) * size/2,(size + 64)/2 + math.cos(v.ang) * size/2;
if xRel > x-64 and xRel < x and yRel > y-64 and yRel < y then
v.selected = true;
else
v.selected = false;
end
end
end);
local function addBubble(text,icon,action)
local tab = {}
tab.icon = icon;
tab.text = text;
tab.action = action;
table.insert(bubbles,tab);
end
concommand.Add( "+menu_context",function()
if LocalPlayer().GetWarden and LocalPlayer():GetWarden() then
JB:DebugPrint("Opening context menu")
scale = 0;
color.a = 0;
bubbles = {};
addBubble("Move",Material("jailbreak_excl/pointers/generic.png"),function() RunConsoleCommand("jb_warden_placepointer","generic") end)
addBubble("Attack",Material("jailbreak_excl/pointers/exclamation.png"),function() RunConsoleCommand("jb_warden_placepointer","exclamation") end)
addBubble("Check out",Material("jailbreak_excl/pointers/question.png"),function() RunConsoleCommand("jb_warden_placepointer","question") end)
addBubble("Line up",Material("jailbreak_excl/pointers/line.png"),function() RunConsoleCommand("jb_warden_placepointer","line") end)
addBubble("Avoid",Material("jailbreak_excl/pointers/cross.png"),function() RunConsoleCommand("jb_warden_placepointer","cross") end)
addBubble("None",nil,function() RunConsoleCommand("jb_warden_placepointer","0") end)
gui.EnableScreenClicker(true);
contextEnabled = true;
end
end);
local function closeContext()
if not contextEnabled then return end
gui.EnableScreenClicker(false);
contextEnabled = false;
for k,v in pairs(bubbles)do
if v.selected then
v.action();
JB:DebugPrint("Selected option '"..v.text.."' in context menu.");
end
end
end
concommand.Add( "-menu_context",closeContext);
hook.Add("GUIMouseReleased","JB.GUIMouseReleased.ContextMenuMouse",function(mouse)
if mouse == MOUSE_LEFT and contextEnabled then
closeContext();
end
end);

View File

@@ -0,0 +1,116 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local clientModels = {}
clientModels["weapon_jb_knife"] = ClientsideModel("models/weapons/w_knife_t.mdl");
if IsValid(clientModels["weapon_jb_knife"]) then
clientModels["weapon_jb_knife"]:SetNoDraw(true);
end
local primWeps = {"weapon_jb_weapon_jb_ak47","weapon_jb_awp","weapon_jb_m3","weapon_jb_m4a1","weapon_jb_mp5navy","weapon_jb_scout","weapon_jb_scout_ns","weapon_jb_tmp","weapon_jb_awp","weapon_jb_famas","weapon_jb_galil","weapon_jb_mac10","weapon_jb_p90","weapon_jb_sg552","weapon_jb_ump"};
local secoWeps = {"weapon_jb_deagle","weapon_jb_fiveseven","weapon_jb_glock","weapon_jb_usp"};
local wmeta = FindMetaTable("Weapon");
function wmeta:IsPrimary()
return (table.HasValue(primWeps,self:GetClass()) or table.HasValue(primWeps,weapons.Get(self:GetClass()).Base));
end
function wmeta:IsSecondary()
return (table.HasValue(secoWeps,self:GetClass()) or table.HasValue(secoWeps,weapons.Get(self:GetClass()).Base));
end
function GM:CheckWeaponTable(class,model)
if clientModels[class] then return end
timer.Simple(0,function()
clientModels[class] = ClientsideModel(model,RENDERGROUP_OPAQUE);
if IsValid(clientModels[class]) then
clientModels[class]:SetNoDraw(true);
end
end);
end
hook.Add("PostPlayerDraw","JB.PostPlayerDraw.DrawWeapons",function(p)
local weps = p:GetWeapons();
for k, v in pairs(weps)do
local mdl = clientModels[v:GetClass()];
if IsValid(mdl) and p:GetActiveWeapon() and p:GetActiveWeapon():IsValid() and p:GetActiveWeapon():GetClass() ~= v:GetClass() then
if v:IsSecondary() then
local boneindex = p:LookupBone("ValveBiped.Bip01_R_Thigh")
if boneindex then
local pos, ang = p:GetBonePosition(boneindex)
ang:RotateAroundAxis(ang:Forward(),90)
mdl:SetRenderOrigin(pos+(ang:Right()*4)+(ang:Up()*-4));
mdl:SetRenderAngles(ang);
mdl:DrawModel();
end
elseif v:IsPrimary() then
local boneindex = p:LookupBone("ValveBiped.Bip01_Spine2")
if boneindex then
local pos, ang = p:GetBonePosition(boneindex)
ang:RotateAroundAxis(ang:Forward(),0)
mdl:SetRenderOrigin(pos+(ang:Right()*4)+(ang:Up()*-7)+(ang:Forward()*6));
ang:RotateAroundAxis(ang:Right(),-15)
mdl:SetRenderAngles(ang);
mdl:DrawModel();
end
elseif v:GetClass() == "weapon_jb_knife" and not tobool(JB.Config.knivesAreConcealed) then
local boneindex = p:LookupBone("ValveBiped.Bip01_L_Thigh")
if boneindex then
local pos, ang = p:GetBonePosition(boneindex)
ang:RotateAroundAxis(ang:Forward(),90)
ang:RotateAroundAxis(ang:Right(),-90)
mdl:SetRenderOrigin(pos+(ang:Right()*-4.2)+(ang:Up()*2));
mdl:SetRenderAngles(ang);
mdl:DrawModel();
end
elseif string.Left(v:GetClass(),10) == "weapon_jb_grenade" then
local boneindex = p:LookupBone("ValveBiped.Bip01_L_Thigh")
if boneindex then
local pos, ang = p:GetBonePosition(boneindex)
ang:RotateAroundAxis(ang:Forward(),10)
ang:RotateAroundAxis(ang:Right(),90)
mdl:SetRenderOrigin(pos+(ang:Right()*-6.5)+(ang:Up()*-1));
mdl:SetRenderAngles(ang);
mdl:DrawModel();
end
end
elseif not mdl and IsValid(v) and weapons.Get( v:GetClass( ) ) then
GAMEMODE:CheckWeaponTable( v:GetClass() ,
weapons.Get( v:GetClass( ) ).WorldModel );
end
end
end)

117
gamemode/core/cl_fonts.lua Normal file
View File

@@ -0,0 +1,117 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
surface.CreateFont("JBExtraSmallShadow",{
font = JB.Config.font,
size = 11,
weight = 400,
blursize = 2,
})
surface.CreateFont("JBExtraSmall",{
font = JB.Config.font,
size = 11,
weight = 400
})
surface.CreateFont("JBSmallShadow",{
font = JB.Config.font,
size = 14,
weight =400,
blursize = 2,
})
surface.CreateFont("JBSmall",{
font = JB.Config.font,
size = 14,
weight = 400
})
surface.CreateFont("JBNormalShadow",{
font = JB.Config.font,
size = 18,
blursize = 2,
weight = 400
})
surface.CreateFont("JBNormal",{
font = JB.Config.font,
size = 18,
weight = 400
})
surface.CreateFont("JBLargeShadow",{
font = JB.Config.font,
size = 27,
weight = 400,
blursize = 2
})
surface.CreateFont("JBLarge",{
font = JB.Config.font,
size = 27,
weight = 400
})
surface.CreateFont("JBLargeBold",{
font = JB.Config.font,
size = 27,
weight = 600
})
surface.CreateFont("JBExtraLargeShadow",{
font = JB.Config.font,
size = 41,
weight = 400,
blursize = 2,
})
surface.CreateFont("JBExtraLarge",{
font = JB.Config.font,
size = 41,
weight = 400
})
surface.CreateFont("JBExtraExtraLargeShadow",{
font = JB.Config.font,
size = 64,
weight = 400,
blursize = 2,
})
surface.CreateFont("JBExtraExtraLarge",{
font = JB.Config.font,
size = 64,
weight = 400
})

445
gamemode/core/cl_hud.lua Normal file
View File

@@ -0,0 +1,445 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
/* HINTS FOR THE SPECTATOR HUD (up here for easy access) */
local Hints = {
"To initiate a last request, the last remaining prisoner can press F4 and choose from a number of different requests.",
"The last guard alive may kill all prisoners, unless at the point he becomes last guard there are under three prisoners alive.",
"The warden is the only guard who is allowed to give complicated commands, normal guards may only give simple commands (e.g. 'Move', 'Drop your weapon')",
"At the start of each round, the guards can claim the warden rank from the F4 menu.",
"The warden can hold C to place markers around the map.",
"Jail Break for Garry's Mod was created by Excl. Visit the developer's website at CasualBananas.com!",
"The warden can spawn various items and control certain options via the F4 menu.",
"Markers placed by the warden expire two minutes after being placed.",
"Respect your warden! Insulting your warden or disobeying orders will probably make him have you executed.",
"You are playing the official Jail Break for Garry's Mod, version 7, a complete remake of the gamemode we all have come to love.",
"Guards can run a little bit faster than prisoners. Make sure you only make your escape when nobody is looking!",
};
/* LIBRARIES */
local allPlayers=player.GetAll
local rad=math.rad;
local sin=JB.Util.memoize(math.sin);
local cos=JB.Util.memoize(math.cos);
local clamp=math.Clamp;
local round=math.Round;
local floor=math.floor;
local approach=math.Approach;
local noTexture=draw.NoTexture;
local roundedBox=draw.RoundedBox;
local drawText = draw.DrawText
local teamGetPlayers = team.GetPlayers;
local tableHasValue = table.HasValue;
local inputLookupBinding = input.LookupBinding;
local setDrawColor = surface.SetDrawColor;
local setMaterial = surface.SetMaterial;
local drawTexturedRect = surface.DrawTexturedRect;
local drawTexturedRectRotated = surface.DrawTexturedRectRotated;
local setFont = surface.SetFont;
local getTextSize = surface.GetTextSize;
local drawRect = surface.DrawRect;
local drawSimpleShadowText = JB.Util.drawSimpleShadowText;
/* VARIABLES */
local wardenMarkers = {}
wardenMarkers["generic"] = {text="Move",icon=Material("jailbreak_excl/pointers/generic.png")}
wardenMarkers["exclamation"] = {text="Attack",icon=Material("jailbreak_excl/pointers/exclamation.png")}
wardenMarkers["question"] = {text="Check out",icon=Material("jailbreak_excl/pointers/question.png")}
wardenMarkers["line"] = {text="Line up",icon=Material("jailbreak_excl/pointers/line.png")}
wardenMarkers["cross"] = {text="Avoid",icon=Material("jailbreak_excl/pointers/cross.png")}
local x,y,width,height; -- reusables;
local ply,dt,state,scrW,scrH; --predefined variables for every HUD loop
local yRestricted=-64;
// MATERIALS
local matHealth = Material("materials/jailbreak_excl/hud_health.png");
local matHealthBottom = Material("materials/jailbreak_excl/hud_health_bottom.png");
local matWarden = Material("materials/jailbreak_excl/hud_warden_bar.png");
local matTime = Material("materials/jailbreak_excl/hud_time.png");
local matLR = Material("materials/jailbreak_excl/lastrequest.png");
local matHint = Material("materials/jailbreak_excl/pointers/pointer_background.png");
local matQuestion = Material("materials/jailbreak_excl/pointers/question.png");
local matRestricted = Material("materials/jailbreak_excl/hud_restricted.png")
// COLORS
local color_marker = Color(255,255,255,0);
local color_marker_dark = Color(0,0,0,0);
// WARDEN PANEL
local warden;
vgui.Register("JBHUDWardenFrame",{
Init = function(self)
self:SetSize(256,64);
self:SetPos(ScrW() - self:GetWide() - 16,32);
self.Player = NULL;
self.Avatar = vgui.Create( "AvatarImage", self )
self.Avatar:SetSize( 32,32 )
self.Avatar:SetPos( 13,16 )
end,
SetPlayer = function(self,ply)
if not IsValid(ply) then return end
self.Player = ply
self.Avatar:SetPlayer( ply, 32 )
end,
PaintOver = function(self,w,h)
setDrawColor(JB.Color.white);
setMaterial(matWarden);
drawTexturedRect(0,0,256,64);
if IsValid(self.Player) then
//draw.SimpleText(self.Player:Nick(),"JBNormalShadow",62,h/2,JB.Color.black,0,1);
drawSimpleShadowText(self.Player:Nick(),"JBNormal",62,h/2,JB.Color.white,0,1);
end
end,
},"Panel");
hook.Add("Think","JB.Think.PredictWardenFrame",function()
if IsValid(warden) and (not IsValid(JB:GetWarden()) or warden.Player ~= JB:GetWarden()) then
warden:Remove();
warden=nil;
end
if IsValid(JB:GetWarden()) and not IsValid(warden) then
warden=vgui.Create("JBHUDWardenFrame");
warden:SetPlayer(JB:GetWarden());
notification.AddLegacy(warden.Player:Nick().." is the warden",NOTICE_GENERIC);
end
end);
// UTILITY FUNCTIONS
local r;
local function drawHealth(x,y,w,radius,amt)
for a = amt, amt + 180 * amt / 100 do
r=rad(a)* 2
drawTexturedRectRotated(x / 2 + cos(r) * radius, y / 2 - sin(r) * radius, w,10, a * 2)
end
end
local function convertTime(t)
if t < 0 then
t = 0;
end
local sec = tostring( round(t - floor(t/60)*60));
if string.len(sec) < 2 then
sec = "0"..sec;
end
return (tostring( floor(t/60) ).." : "..sec )
end
// Health and ammo
local healthMemory = 0;
local health = 0;
local wide_hp_1,wide_hp_2,height_hp;
local activeWeapon;
local text_ammo;
local drawAmmoHealth = function()
health= clamp(ply:Health(),0,100);
healthMemory = approach(healthMemory,health,dt*50);
health=tostring(health);
setDrawColor(JB.Color.white);
setMaterial(matHealthBottom);
drawTexturedRect(0,0,256,256);
noTexture();
setDrawColor(JB.Color["#CF1000"]);
drawHealth(256,256,24,86,healthMemory);
setFont("JBExtraLarge");
wide_hp_1,height = getTextSize(health);
setFont("JBSmall");
wide_hp_2 = getTextSize(" %\n HP");
activeWeapon = ply:GetActiveWeapon();
if IsValid(activeWeapon) and activeWeapon:Clip1() ~= -1 and activeWeapon:GetClass() ~= "weapon_gravgun" then
y = 64+32+12;
drawSimpleShadowText(health,"JBExtraLarge",128-(wide_hp_1 + wide_hp_2)/2,y-height/2 - 6,JB.Color["#DCDCDC"],0,0);
drawText(" %\n HP ","JBSmallShadow",128-(wide_hp_1 + wide_hp_2)/2 + wide_hp_1,y-height/2,JB.Color.black,0,0);
drawText(" %\n HP ","JBSmall",128-(wide_hp_1 + wide_hp_2)/2 + wide_hp_1,y-height/2,JB.Color["#DCDCDC"],0,0);
setDrawColor(JB.Color["#DCDCDC"]);
drawRect(128-40,128-2,1 + clamp(79 * (tonumber(ply:GetActiveWeapon():Clip1())/tonumber(ply:GetActiveWeapon().Primary and ply:GetActiveWeapon().Primary.ClipSize or 10)),0,79),4);
y = 128+16;
text_ammo = ply:GetActiveWeapon():Clip1() .. "/" .. ply:GetAmmoCount(ply:GetActiveWeapon():GetPrimaryAmmoType());
drawSimpleShadowText("AMMO","JBExtraSmall",128-40,y,JB.Color["#DCDCDC"],0,1);
drawSimpleShadowText(text_ammo,"JBNormal",128+40,y,JB.Color["#DCDCDC"],2,1);
else
drawSimpleShadowText(health,"JBExtraLarge",128-(wide_hp_1 + wide_hp_2)/2,128-height/2 - 6,JB.Color["#DCDCDC"],0,0);
drawText(" %\n HP ","JBSmallShadow",128-(wide_hp_1 + wide_hp_2)/2 + wide_hp_1,128-height/2,JB.Color.black,0,0);
drawText(" %\n HP ","JBSmall",128-(wide_hp_1 + wide_hp_2)/2 + wide_hp_1,128-height/2,JB.Color["#DCDCDC"],0,0);
end
setDrawColor(JB.Color.white);
setMaterial(matHealth);
drawTexturedRect(0,0,256,256);
end
// Spectator
local specPosScreen,plySpec,players;
local hint;
local color_hint_questionmark = Color(255,255,255,0);
local colorHintMakeZero = false;
local newHint = function()
setFont("JBSmall");
hint=string.Explode("\n",JB.Util.formatLine(Hints[math.random(1,#Hints)],512-(128-16)),false);
colorHintMakeZero=true;
end
newHint();
local drawSpectatorHUD = function()
players=allPlayers();
for i=1, #players do
plySpec=players[i];
if plySpec:Alive() and (plySpec:Team() == TEAM_GUARD or plySpec:Team() == TEAM_PRISONER) then
specPosScreen = (plySpec:EyePos() + Vector(0,0,20)):ToScreen();
x,y=specPosScreen.x,specPosScreen.y;
specPosScreen = nil;
local alpha = 50;
if ply:EyePos():Distance( plySpec:GetPos() ) < 1000 then
alpha = 255;
end
drawSimpleShadowText(plySpec:Nick(),"JBNormal",x,y,Color(255,255,255,alpha),1,1);
local col = table.Copy(JB.Color["#CF1000"]);
col.a = alpha;
roundedBox(2,x - 30,y + 10,60,4,Color(0,0,0,alpha));
roundedBox(0,x - 30 + 1,y + 10 + 1,(60-2)*clamp(plySpec:Health()/100,0,1),2,col);
roundedBox(0,x - 30 + 1,y + 10 + 1,(60-2)*clamp(plySpec:Health()/100,0,1),1,Color(255,255,255,15 * alpha/255));
end
end
//hint
x,y=scrW/2 - 256,scrH-128;
setDrawColor(JB.Color.white);
setMaterial(matHint);
drawTexturedRect(x,y,128,128);
color_hint_questionmark.a = Lerp(colorHintMakeZero and dt*20 or dt*5,color_hint_questionmark.a,colorHintMakeZero and 0 or 255);
if colorHintMakeZero and color_hint_questionmark.a < 1 then
colorHintMakeZero = false;
end
setDrawColor(color_hint_questionmark);
setMaterial(matQuestion);
drawTexturedRect(x+32+16,y+32+16,32,32);
x,y = x+128-8,y+30;
width,height = drawSimpleShadowText("Did you know?","JBNormal",x,y,JB.Color.white,0,0);
y=y+height+2;
for i=1,#hint do
width,height=drawSimpleShadowText(hint[i],"JBSmall",x,y,JB.Color["#eee"],0,0);
y=y+height;
end
end
timer.Create("JB.HUD.NewHint",8,0,newHint);
// TIMER
local drawTimer = function()
y = 32;
if IsValid(warden) then
y = warden.y + warden:GetTall();
end
setDrawColor(JB.Color.white);
setMaterial(matTime);
drawTexturedRect(scrW-16-128,y,128,64);
local timerText = state == STATE_IDLE and "WAITING" or state == STATE_ENDED and "ENDED" or state == STATE_MAPVOTE and "MAPVOTE" or
convertTime(60*(state == STATE_LASTREQUEST and 3 or 10) - (CurTime() - JB.RoundStartTime));
drawSimpleShadowText(timerText,"JBNormal",scrW-16-64,y+32,JB.Color.white,1,1);
end
// LAST REQUEST
local lrGuard,lrPrisoner;
local drawLastRequest = function()
setMaterial(matLR)
setDrawColor(JB.Color.white)
drawTexturedRect(scrW/2 - 256, 4,512,128);
-- unpack from table;
lrGuard,lrPrisoner = unpack(JB.LastRequestPlayers);
-- convert to string
lrGuard = IsValid(lrGuard) and lrGuard:Nick() or "ERROR!";
lrPrisoner = IsValid(lrPrisoner) and lrPrisoner:Nick() or "ERROR!";
drawSimpleShadowText(lrPrisoner,"JBNormal",scrW/2 + 28, 4 + 64,JB.Color.white,0,1);
drawSimpleShadowText(lrGuard,"JBNormal",scrW/2 - 28, 4 + 64,JB.Color.white,2,1);
end
// POINTER
local posMarkerScreen,marker;
local drawWardenPointer = function()
posMarkerScreen = (JB.TRANSMITTER:GetJBWarden_PointerPos()):ToScreen();
x = clamp(posMarkerScreen.x,32,scrW-64);
y = clamp(posMarkerScreen.y,32,scrH-64) - 8;
marker= wardenMarkers[JB.TRANSMITTER:GetJBWarden_PointerType()];
color_marker.a = (posMarkerScreen.x ~= x or posMarkerScreen.y ~= y+8) and 100 or 255;
color_marker_dark.a = color_marker.a;
setMaterial(marker.icon);
setDrawColor(color_marker);
drawTexturedRect(x-16,y-16,32,32);
drawSimpleShadowText(marker.text,"JBNormal",x,y+16,color_marker,1,0);
// note: 64unit = 1.22meters
drawSimpleShadowText(tostring(math.floor(LocalPlayer():EyePos():Distance(JB.TRANSMITTER:GetJBWarden_PointerPos()) * 1.22/64)).."m","JBSmall",x,y+34,color_marker,1,0);
end
// GM HOOK
local hookCall = hook.Call;
JB.Gamemode.HUDPaint = function(gm)
ply = LocalPlayer();
if not IsValid(ply) then return end
scrW,scrH,dt=ScrW(),ScrH(),FrameTime();
state = JB.State;
if ply:Alive() then
drawAmmoHealth(); // alive and well
-- ES support
if ES and ES.NotificationOffset then
ES.NotificationOffset.x = 24
ES.NotificationOffset.y = 232
end
else
drawSpectatorHUD(); // Spectator or dead.
-- ES support
if ES and ES.NotificationOffset then
ES.NotificationOffset.x = 24
ES.NotificationOffset.y = 24
end
end
drawTimer();
if JB.State == STATE_LASTREQUEST and JB.LastRequest ~= "0" then
drawLastRequest();
end
if #teamGetPlayers(TEAM_GUARD) < 1 or #teamGetPlayers(TEAM_PRISONER) < 1 then
drawText("A new round can not start until there is at least one player on both teams.\nWait for somebody to join the empty team.","JBNormalShadow",scrW/2,scrH * .6,JB.Color.black,1,1);
drawText("A new round can not start until there is at least one player on both teams.\nWait for somebody to join the empty team.","JBNormal",scrW/2,scrH * .6,JB.Color.white,1,1);
end
if IsValid(JB.TRANSMITTER) and JB.TRANSMITTER:GetJBWarden_PointerPos() and JB.TRANSMITTER:GetJBWarden_PointerType() and wardenMarkers[JB.TRANSMITTER:GetJBWarden_PointerType()] then
drawWardenPointer();
end
JB.Gamemode:HUDDrawTargetID(); -- not calling hook, we don't want any addons messing with this.
hookCall("HUDPaintOver",JB.Gamemode)
end;
// TARGET ID
local uniqueid,ent,text_x,text_y,text,text_sub,text_wide,text_tall,text_color;
JB.Gamemode.HUDDrawTargetID = function()
if LocalPlayer():GetObserverMode() ~= OBS_MODE_NONE then return end
ent = LocalPlayer():GetEyeTrace().Entity;
if (not IsValid(ent) ) then return end;
text = "ERROR"
text_sub = "Something went terribly wrong!";
if (ent:IsPlayer()) then
text = ent:Nick()
text_sub = ent:GetPos():Distance(LocalPlayer():EyePos()) < 200 and (ent:Health().."% HP"..(ent.GetRebel and ent:GetRebel() and " | Rebel" or ent.GetWarden and ent:GetWarden() and " | Warden" or ""));
text_color = team.GetColor(ent:Team());
elseif (ent:IsWeapon()) then
local tab=weapons.Get(ent:GetClass())
text = tab and tab.PrintName or ent:GetClass();
if( tableHasValue(JB.LastRequestPlayers,LocalPlayer()) and JB.LastRequestTypes[JB.LastRequest] and not JB.LastRequestTypes[JB.LastRequest]:GetCanPickupWeapons() ) then
text_sub = "Can not pick up in LR";
else
local bind = inputLookupBinding("+use");
text_sub = ent:GetPos():Distance(LocalPlayer():EyePos()) > 200 and "" or ((not bind) and "Bind a key to +use to pick up") or ("Press "..bind.." to pick up");
end
text_color = JB.Color.white;
else
return
end
text_x,text_y = scrW/2, scrH *.6;
drawSimpleShadowText(text,"JBNormal",text_x,text_y,text_color,1,1);
if text_sub and text_sub ~= "" then
setFont("JBNormal");
text_wide,text_tall = getTextSize(text);
text_y = text_y + text_tall*.9;
drawSimpleShadowText(text_sub,"JBSmall",text_x,text_y,JB.Color.white,1,1);
end
end
function JB.Gamemode:HUDShouldDraw(element)
return (element ~= "CHudHealth" and element ~= "CHudBattery" and element ~= "CHudAmmo" and element ~= "CHudSecondaryAmmo" and element ~= "CHudMessage" and element ~= "CHudWeapon");
end

View File

@@ -0,0 +1,144 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local timeReceive;
local lrType = "BUG"
net.Receive('JB.LR.GetReady',function()
timeReceive=CurTime();
lrType = net.ReadString();
end);
local _Material = Material( "pp/toytown-top" )
_Material:SetTexture( "$fbtexture", render.GetScreenEffectTexture() )
/* HUD elements */
local drawText = draw.DrawText
local setColor = surface.SetTextColor
local setTextPos = surface.SetTextPos
local popModelMatrix = cam.PopModelMatrix
local pushModelMatrix = cam.PushModelMatrix
local pushFilterMag = render.PushFilterMag;
local pushFilterMin = render.PushFilterMin;
local popFilterMag = render.PopFilterMag;
local popFilterMin = render.PopFilterMin;
local getTextSize = surface.GetTextSize;
local setFont = surface.SetFont;
local sin=JB.Util.memoize(math.sin);
local cos=JB.Util.memoize(math.cos);
local deg2rad=math.rad;
local floor=math.floor;
local matrix = Matrix()
local matrixAngle = Angle(0, 0, 0)
local matrixScale = Vector(0, 0, 0)
local matrixTranslation = Vector(0, 0, 0)
local textWidth, textHeight, rad,textWidthSub,textHeightSub,width,height;
local halvedPi = math.pi/2;
local color=Color(255,255,255,255);
local color_dark=Color(0,0,0,255);
local clamp = math.Clamp;
local scale=1;
local ang = 0;
local text = function( text,sub )
x,y = ScrW()/2,ScrH()/2;
pushFilterMag( TEXFILTER.ANISOTROPIC )
pushFilterMin( TEXFILTER.ANISOTROPIC )
setFont("JBExtraExtraLarge");
textWidth, textHeight = getTextSize( text )
if sub then
setFont("JBNormal");
sub = JB.Util.formatLine(sub,ScrW()*.3)
textWidthSub, textHeightSub = getTextSize( sub );
textHeight=textHeight+textHeightSub;
if textWidthSub > textWidth then
width = textWidthSub;
else
width=textWidth;
end
height=(textHeight+textHeightSub);
else
width=textWidth;
height=textHeight;
end
rad = -deg2rad( ang )
x = x - ( sin( rad + halvedPi ) * width*scale / 2 + sin( rad ) * height*scale / 2 )
y = y - ( cos( rad + halvedPi ) * width*scale / 2 + cos( rad ) * height*scale / 2 )
matrix=Matrix();
matrixAngle.y = ang;
matrix:SetAngles( matrixAngle )
matrixTranslation.x = x;
matrixTranslation.y = y;
matrix:SetTranslation( matrixTranslation )
matrixScale.x = scale;
matrixScale.y = scale;
matrix:Scale( matrixScale )
pushModelMatrix( matrix )
drawText( text,"JBExtraExtraLargeShadow", sub and (width/2 - textWidth/2) or 0,0,color_dark,0);
drawText( text,"JBExtraExtraLarge", sub and (width/2 - textWidth/2) or 0,0,color,0);
if sub then
drawText(sub,"JBNormalShadow",width/2,textHeight,color_dark,1);
drawText(sub,"JBNormal",width/2,textHeight,color,1);
end
popModelMatrix()
popFilterMag()
popFilterMin()
end
local time,xCenter,yCenter;
hook.Add("HUDPaintOver","JB.HUDPaintOver.PaintReadyForLR",function()
if not timeReceive or (CurTime() - timeReceive) > 8 or not JB.LastRequestTypes[lrType] then return end
time=(CurTime() - timeReceive);
if time > 4 then
scale=.2 + (1-(time%1)) * 3
ang=-10 + (1-(time%1)) * 30;
else
scale=1;
ang=0;
end
time=floor(time);
text(time < 4 and JB.LastRequestTypes[lrType].name or time == 7 and "Go!" or tostring(3 - (time-4)), time < 4 and JB.LastRequestTypes[lrType].description);
end);

View File

@@ -0,0 +1,221 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local selectedTab = 0;
local c = 0;
local slots = {}
local slotPos = 1;
local function ArrangeSlots()
slots = {};
c = 0;
for k,v in pairs(LocalPlayer():GetWeapons())do
if v.Slot then
if not slots[v.Slot+1] then
slots[v.Slot+1] = {}
end
slots[v.Slot+1][#slots[v.Slot+1]+1] = v;
if v.Slot == 3 then
c = c+1;
end
end
end
if selectedTab == 4 then
slotPos = (((slotPos-1)%c)+1);
else
slotPos = 1;
end
end
surface.CreateFont("JBWeaponSelectionFont",{
font = JB.Config.font,
size = 28,
})
surface.CreateFont("JBWeaponSelectionFontBlur",{
font = JB.Config.font,
size = 28,
blursize = 2
})
local tabX = {-256,-256,-256,-256};
local matTile = Material("materials/jailbreak_excl/weapon_selection_tile.png");
local mul;
hook.Add("Think","JB.Think.WeaponSelection.Animate",function()
if selectedTab > 0 and LocalPlayer():Alive() and LocalPlayer():Team() < 3 then
mul=FrameTime()*40;
tabX[1] = math.Clamp(Lerp(0.20 * mul,tabX[1],1),-256,0);
tabX[2] = math.Clamp(Lerp(0.18 * mul,tabX[2],1),-256,0);
tabX[3] = math.Clamp(Lerp(0.16 * mul,tabX[3],1),-256,0);
tabX[4] = math.Clamp(Lerp(0.14 * mul,tabX[4],1),-256,0);
else
mul=FrameTime()*40;
tabX[1] = math.Clamp(Lerp(0.40 * mul,tabX[1],-256),-256,0);
tabX[2] = math.Clamp(Lerp(0.39 * mul,tabX[2],-256),-256,0);
tabX[3] = math.Clamp(Lerp(0.38 * mul,tabX[3],-256),-256,0);
tabX[4] = math.Clamp(Lerp(0.37 * mul,tabX[4],-256),-256,0);
end
end);
hook.Add("HUDPaint","JB.HUDPaint.WeaponSelection",function()
if tabX[1] >= -256 and LocalPlayer():Alive() and LocalPlayer():Team() < 3 then
for i=1,4 do
local y = 250 + ((i-1) * 54);
local x = math.Round(tabX[i]);
surface.SetDrawColor(selectedTab == i and JB.Color.white or JB.Color["#888"]);
surface.SetMaterial(matTile);
surface.DrawTexturedRect(x + 0,y,256,64);
if slots[i] and slots[i][1] then
draw.SimpleText(slots[i][1].PrintName or "Invalid","JBWeaponSelectionFontBlur",x + 210,y+(64-40)/2+40/2, JB.Color.black,2,1)
draw.SimpleText(slots[i][1].PrintName or "Invalid","JBWeaponSelectionFont",x + 210,y+(64-40)/2+40/2, selectedTab == i and JB.Color.white or JB.Color["#888"],2,1)
end
draw.SimpleText(i == 1 and "UNARMED" or i == 2 and "PRIMARY" or i == 3 and "SECONDARY" or i == 4 and "OTHER","JBNormal",x + 4,y+(64-40)/2+3,Color(255,255,255,2));
end
end
end)
timer.Create("UpdateSWEPSelectthings",1,0,function()
if selectedTab > 0 then
ArrangeSlots();
end
end)
local nScroll = 1;
function JB.Gamemode:PlayerBindPress(p, bind, pressed)
if not pressed then return false end
if string.find(bind, "invnext") then
if LocalPlayer():Team() > 2 or !LocalPlayer():Alive() then return true end
nScroll = nScroll + 1;
if nScroll > 4 then
nScroll = 1;
end
if selectedTab ~= nScroll then
surface.PlaySound("common/wpn_moveselect.wav");
end
selectedTab = nScroll;
ArrangeSlots();
return true;
elseif string.find(bind, "invprev") then
if LocalPlayer():Team() > 2 or !LocalPlayer():Alive() then return true end
nScroll = nScroll-1;
if nScroll < 1 then
nScroll = 4;
end
if selectedTab ~= nScroll then
surface.PlaySound("common/wpn_moveselect.wav");
end
selectedTab = nScroll;
ArrangeSlots();
return true;
elseif string.find(bind, "slot0") then
selectedTab = 0;
return true
elseif string.find(bind, "slot1") then
if LocalPlayer():Team() > 2 or !LocalPlayer():Alive() then return true end
if selectedTab ~= 1 then
surface.PlaySound("common/wpn_moveselect.wav");
else
selectedTab = 0;
return true;
end
selectedTab = 1;
ArrangeSlots();
return true
elseif string.find(bind, "slot2") then
if LocalPlayer():Team() > 2 or !LocalPlayer():Alive() then return true end
if selectedTab ~= 2 then
surface.PlaySound("common/wpn_moveselect.wav");
else
selectedTab = 0;
return true;
end
selectedTab = 2;
ArrangeSlots();
return true
elseif string.find(bind, "slot3") then
if LocalPlayer():Team() > 2 or !LocalPlayer():Alive() then return true end
if selectedTab ~= 3 then
surface.PlaySound("common/wpn_moveselect.wav");
else
selectedTab = 0;
return true;
end
selectedTab = 3;
ArrangeSlots();
return true
elseif string.find(bind, "slot4") then
if LocalPlayer():Team() > 2 or !LocalPlayer():Alive() then return true end
if selectedTab ~= 4 then
surface.PlaySound("common/wpn_moveselect.wav");
else
selectedTab = 0;
return true;
end
selectedTab = 4;
ArrangeSlots();
return true
elseif string.find(bind, "slot5") then
selectedTab = 0;
return true
elseif string.find(bind, "slot6") then
selectedTab = 0;
return true
elseif string.find(bind, "slot7") then
selectedTab = 0;
return true
elseif string.find(bind, "slot8") then
selectedTab = 0;
return true
elseif string.find(bind, "slot9") then
selectedTab = 0;
return true
elseif string.find(bind, "+attack") then
if LocalPlayer():Team() > 2 then return true end
if selectedTab > 0 and slots[selectedTab] then
if not slots[selectedTab][slotPos] or not IsValid(slots[selectedTab][slotPos]) then return true end
RunConsoleCommand("use",slots[selectedTab][slotPos]:GetClass())
nScroll = selectedTab;
selectedTab = 0;
return true;
end
end
return false
end

68
gamemode/core/cl_logs.lua Normal file
View File

@@ -0,0 +1,68 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
net.Receive("JB.GetLogs",function()
local DamageLog = net.ReadTable();
local printLog=tobool(net.ReadBit());
if printLog then
MsgC(JB.Color.white,[[
##############################
# #
# JAILBREAK 7 LOGS #
# EVENTS SINCE ROUND START #
# #
##############################
Log generated by player ]]..LocalPlayer():Nick().." ("..LocalPlayer():SteamID()..[[)
Log generated at date ]]..os.date()..[[
]]);
MsgC(JB.Color.white,"\n")
for k,v in pairs(DamageLog) do
MsgC(JB.Color.white,"["..v.time.."] ");
local clr=JB.Color.white;
for k,v in pairs(v.message)do
if type(v)=="table" and v.r and v.g and v.b then
clr=v;
elseif type(v)=="string" then
MsgC(clr,v);
end
end
MsgC(clr,"\n");
end
MsgC(JB.Color.white,"\n##############################\n");
end
JB.ThisRound.Logs = DamageLog;
end)

View File

@@ -0,0 +1,277 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local color_text = Color(223,223,223,230);
local matGradient = Material("materials/jailbreak_excl/gradient.png");
local frame;
local slide_cur = 1;
local guide_slides={
Material("jailbreak_excl/guide/slide_1.png"),
Material("jailbreak_excl/guide/slide_2.png"),
Material("jailbreak_excl/guide/slide_3.png"),
Material("jailbreak_excl/guide/slide_4.png"),
}
function JB.MENU_HELP_OPTIONS()
if IsValid(frame) then frame:Remove() end
frame = vgui.Create("JB.Frame");
frame:SetTitle("INFORMATION & OPTIONS");
frame:SetWide(740);
local right = frame:Add("JB.Panel");
local left = frame:Add("JB.Panel");
left:SetWide(math.Round(frame:GetWide() * .25) - 15);
right:SetWide(math.Round(frame:GetWide() * .75) - 15);
local tall = right:GetWide() * .65;
left:SetTall(tall); right:SetTall(tall);
left:SetPos(10,40);
right:SetPos(left:GetWide() + left.x + 10,40);
left.Paint = function() end;
frame:SetTall(math.Round(right:GetTall() + 50))
local btn_guide = left:Add("JB.Button");
btn_guide:SetSize(left:GetWide(),32);
btn_guide:SetText("Guide")
local btn_options = left:Add("JB.Button");
btn_options:SetSize(left:GetWide(),32);
btn_options:SetText("Options")
btn_options.y = 40;
local btn_logs = left:Add("JB.Button");
btn_logs:SetSize(left:GetWide(),32);
btn_logs:SetText("Logs")
btn_logs.y = 80;
local btn_credits = left:Add("JB.Button");
btn_credits:SetSize(left:GetWide(),32);
btn_credits:SetText("About")
btn_credits.y = 120;
btn_guide.OnMouseReleased = function()
JB.Util.iterate(right:GetChildren()):Remove();
slide_cur = 1;
local controls=right:Add("Panel");
controls:SetSize(80*2 + 40,32+80);
controls:SetPos(right:GetWide()/2-controls:GetWide()/2,right:GetTall()-controls:GetTall())
local go_left=controls:Add("JB.Button");
go_left:SetSize(80,32);
go_left:SetText("Previous");
go_left:Dock(LEFT);
local go_right=controls:Add("JB.Button");
go_right:SetSize(80,32);
go_right:SetText("Next");
go_right:Dock(RIGHT);
local slideshow=right:Add("DImage");
slideshow:SetSize(512,128);
slideshow:SetMaterial(guide_slides[1]);
slideshow:SetPos((right:GetWide())/2 - slideshow:GetWide()/2,70)
go_left.OnMouseReleased=function()
slide_cur =slide_cur-1;
if slide_cur <= 1 then
go_left:SetVisible(false);
else
go_left:SetVisible(true);
end
go_right:SetVisible(true);
slideshow:SetMaterial(guide_slides[slide_cur]);
end
go_right.OnMouseReleased=function()
slide_cur =slide_cur+1;
if slide_cur >= #guide_slides-1 then
go_right:SetVisible(false);
else
go_right:SetVisible(true);
end
go_left:SetVisible(true);
slideshow:SetMaterial(guide_slides[slide_cur]);
end
go_left:SetVisible(false);
end
btn_logs.OnMouseReleased = function()
JB.Util.iterate(right:GetChildren()):Remove();
local lbl=Label("Round logs",right);
lbl:SetPos(20,20);
lbl:SetFont("JBLarge");
lbl:SizeToContents();
lbl:SetColor(JB.Color.white);
local scrollPanel = vgui.Create( "DScrollPanel", right )
scrollPanel:SetSize( right:GetWide()-40, right:GetTall()-20-lbl.y-lbl:GetTall()-20 )
scrollPanel:SetPos( 20, lbl.y + lbl:GetTall() + 20 )
LocalPlayer():ConCommand("jb_logs_get");
local logs_old = JB.ThisRound.Logs;
hook.Add("Think","JB.Think._MENU_.CheckChangesToLogs",function()
if not IsValid(scrollPanel) then
hook.Remove("Think","JB.Think._MENU_.CheckChangesToLogs");
return;
end
if logs_old ~= JB.ThisRound.Logs then
hook.Remove("Think","JB.Think._MENU_.CheckChangesToLogs");
local Panels = {};
local pnl;
for k,v in ipairs(JB.ThisRound.Logs)do
if not pnl or not pnl.subject or pnl.subject ~= v.subject then
pnl=vgui.Create("EditablePanel");
table.insert(Panels,pnl);
pnl.Paint = function(self,w,h)
draw.RoundedBox(6,0,0,w,h-10,JB.Color["#111"]);
draw.RoundedBox(4,1,1,w-2,h-10-2,JB.Color["#333"]);
draw.RoundedBox(0,70- (60/2),1,60,h-2-10,JB.Color["#444"])
end
pnl:SetWide(scrollPanel:GetWide());
pnl.subject = v.subject;
end
local textPanel=vgui.Create("Panel",pnl);
textPanel:SetWide(pnl:GetWide());
textPanel.Paint = function(self,w,h)
JB.Util.drawSimpleShadowText(v.time,"JBExtraSmall",10,h/2,JB.Color.white,0,1,1);
JB.Util.drawSimpleShadowText(v.kind,"JBExtraSmall",70,h/2,JB.Color.white,1,1,1);
local clr=JB.Color.white
local x=70+(60/2)+10;
for _,msg in pairs(v.message)do
if type(msg)=="table" and msg.r and msg.g and msg.b then
clr = msg;
elseif type(msg)=="string" then
msg=string.gsub(msg," ?%(STEAM_0:.-%)","");
x=x+JB.Util.drawSimpleShadowText(msg,"JBExtraSmall",x,h/2,clr,0,1,1);
end
end
end
textPanel:SetTall(20);
textPanel:Dock(TOP);
textPanel:DockMargin(0,2,0,2);
end
for k,v in ipairs(Panels)do
v:SetTall(#v:GetChildren() * 24 + 10);
scrollPanel:AddItem(v);
v:Dock(TOP);
end
end
end)
end
btn_options.OnMouseReleased = function()
JB.Util.iterate(right:GetChildren()):Remove();
local lbl=Label("Options",right);
lbl:SetPos(20,20);
lbl:SetFont("JBLarge");
lbl:SizeToContents();
lbl:SetColor(JB.Color.white);
local container=right:Add("Panel");
container:SetSize(right:GetWide()-40,right:GetTall()-lbl:GetTall()-lbl.y-40);
container:SetPos(20,lbl.y+lbl:GetTall()+20);
for k,v in ipairs{
{"jb_cl_option_toggleaim","toggle","Toggle aim (default: Right Mouse)"},
{"jb_cl_option_togglecrouch","toggle","Toggle crouch (default: CTRL)"},
{"jb_cl_option_togglewalk","toggle","Toggle walk (default: ALT)"},
{"jb_cl_option_always_spectate","toggle","Always spawn as spectator after joining"}
} do
local fragment=container:Add("Panel");
fragment:SetSize(container:GetWide(),32);
fragment:SetPos(0,(k-1)*32);
local lbl=Label(v[3],fragment);
lbl:SetFont("JBSmall");
lbl:SizeToContents();
lbl:SetPos(32,fragment:GetTall()/2-lbl:GetTall()/2);
lbl:SetColor(color_text);
local DermaCheckbox = vgui.Create( "DCheckBox",fragment )
DermaCheckbox:SetPos( fragment:GetTall()/2 - DermaCheckbox:GetWide()/2, fragment:GetTall()/2 - DermaCheckbox:GetTall()/2)// Set the position
DermaCheckbox:SetConVar( v[1] )
end
end
btn_credits.OnMouseReleased = function()
local text = [[This is the seventh version of the first Garry's Mod edition of Jail Break.
It is a complete rewrite and shares no code with previous versions, or any unofficial remake of the gamemode.
Jail Break was created by Casual Bananas, a software development company based in The Netherlands. We do much more than just Garry's Mod gamemodes and addons; check out our website at casualbananas.com to find out more about our company and what services we offer.
CREDITS
: Excl (STEAM_0:0:19441588) - Lead developer in charge of Jail Break since version 1
SPECIAL THANKS
: Camamoow - Inciting me to make this new version of Jail Break.
: VTG Community - Bug testing, suggestions and being the first Jail Break 7 server.
Copyright © Casual Bananas 2014 ]];
JB.Util.iterate(right:GetChildren()):Remove();
JB.Util.iterate{Label("About",right)}:SetPos(20,20):SetFont("JBLarge"):SizeToContents():SetColor(JB.Color.white);
JB.Util.iterate{Label(text,right)}:SetPos(20,60):SetColor(color_text):SetFont("JBSmall"):SetSize(right:GetWide() - 40,280):SetWrap(true);
end
/* create the menu */
frame:Center();
frame:MakePopup();
/* open a tab */
btn_guide.OnMouseReleased();
end

View File

@@ -0,0 +1,182 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local color_text = Color(223,223,223,230);
local matGradient = Material("materials/jailbreak_excl/gradient.png");
local frame;
function JB.MENU_LR()
if IsValid(frame) then frame:Remove() end
frame = vgui.Create("JB.Frame");
frame:SetTitle("Last Request");
if (JB.State ~= STATE_PLAYING and JB.State ~= STATE_SETUP and JB.State ~= STATE_LASTREQUEST) or JB.AlivePrisoners() > 1 or JB:AliveGuards() < 1 or not LocalPlayer():Alive() then
local lbl = Label("A last request is a last chance for the prisoner team to win the round if all rebelling attempts failed.\nIt will consist of a small game the prisoner doing the request can play against a guard of his choice.\n\nYou can only start a Last Request if you're the last prisoner alive and the round is in progress.",frame);
lbl:SetFont("JBSmall");
lbl:SetColor(color_text);
lbl:SizeToContents();
lbl:SetPos(15,30+15);
frame:SetSize(lbl:GetWide() + 30,30+15+lbl:GetTall()+15);
else
frame:SetWide(620);
local left = frame:Add("JB.Panel");
left:SetSize(math.Round(frame:GetWide() * .35) - 15,412);
left:SetPos(10,40);
local right = frame:Add("JB.Panel");
right:SetSize(math.Round(frame:GetWide() * .65) - 15,412);
right:SetPos(left:GetWide() + left.x + 10,40);
frame:SetTall(math.Round(right:GetTall() + 50))
-- populate right panel
local lr_selected;
local lbl_LRName = Label("",right);
lbl_LRName:SetPos(20,20);
lbl_LRName:SetFont("JBLarge");
lbl_LRName:SizeToContents();
lbl_LRName:SetColor(color_text);
local lbl_LRDetails = Label("",right);
lbl_LRDetails:SetPos(20,lbl_LRName.y + lbl_LRName:GetTall() + 16);
lbl_LRDetails:SetColor(color_text);
lbl_LRDetails:SetFont("JBSmall");
lbl_LRDetails:SetSize(right:GetWide() - 40,right:GetTall() - lbl_LRDetails.y - 30-30-32);
lbl_LRDetails:SetWrap(true);
lbl_LRDetails:SizeToContents();
local btn_accept = right:Add("JB.Button");
btn_accept:SetSize(right:GetWide() - 60,32);
btn_accept:SetPos(30,right:GetTall() - 30 - btn_accept:GetTall());
btn_accept:SetText("Start Last Request");
btn_accept.OnMouseReleased = (function()
local Menu = DermaMenu()
for k,v in pairs(team.GetPlayers(TEAM_GUARD))do
if not IsValid(v) then continue end
local btn = Menu:AddOption( v:Nick() or "Unknown guard",function()
RunConsoleCommand("jb_lastrequest_start",lr_selected:GetID(),v:EntIndex());
if IsValid(frame) then frame:Remove() end
end)
if v.GetWarden and v:GetWarden() then
btn:SetIcon( "icon16/star.png" )
end
end
Menu:AddSpacer()
Menu:AddOption( "Random guard",function()
local tab = {};
for k,v in ipairs(team.GetPlayers(TEAM_GUARD))do
if v:Alive() then
table.insert(tab,v);
end
end
RunConsoleCommand("jb_lastrequest_start",lr_selected:GetID(),(table.Random(tab)):EntIndex());
if IsValid(frame) then frame:Remove() end
end ):SetIcon( "icon16/lightbulb.png" )
Menu:Open();
end);
btn_accept:SetVisible(false);
--populate left panel
local function selectLR(lr)
if not JB.ValidLR(lr) then return end
btn_accept:SetVisible(true);
lbl_LRName:SetText(lr:GetName());
lbl_LRName:SizeToContents();
lbl_LRDetails:SetPos(20,lbl_LRName.y + lbl_LRName:GetTall() + 16);
lbl_LRDetails:SetSize(right:GetWide() - 40,right:GetTall() - lbl_LRDetails.y - 30-30-32);
lbl_LRDetails:SetText(lr:GetDescription());
lbl_LRDetails:SetWrap(true);
lr_selected = lr;
end
left:DockMargin(0,0,0,0);
for k,v in pairs(JB.LastRequestTypes)do
local pnl = vgui.Create("JB.Panel",left);
pnl:SetTall(26);
pnl:Dock(TOP);
pnl:DockMargin(6,6,6,0);
pnl.a = 80;
pnl.Paint = function(self,w,h)
draw.RoundedBox(4,0,0,w,h,JB.Color["#777"]);
self.a = Lerp(0.1,self.a,self.Hover and 140 or 80);
surface.SetMaterial(matGradient);
surface.SetDrawColor(Color(0,0,0,self.a));
surface.DrawTexturedRectRotated(w/2,h/2,w,h,180);
surface.SetDrawColor(JB.Color.white);
surface.SetMaterial(v:GetIcon());
surface.DrawTexturedRect(5,5,16,16);
draw.SimpleText(v:GetName(),"JBNormal",28,h/2,JB.Color.white,0,1);
end
local dummy = vgui.Create("Panel",pnl);
dummy:SetSize(pnl:GetWide(),pnl:GetTall());
dummy:SetPos(0,0);
dummy.OnMouseReleased = function()
selectLR(v);
end
dummy.OnCursorEntered = function()
pnl.Hover = true;
end
dummy.OnCursorExited=function()
pnl.Hover = false;
end
pnl.PerformLayout = function(self)
dummy:SetSize(self:GetWide(),self:GetTall());
end
end
end
frame:Center();
frame:MakePopup();
end

View File

@@ -0,0 +1,113 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local color_text = Color(223,223,223,230);
local frame;
function JB.MENU_TEAM()
if IsValid(frame) then frame:Remove() end
if timer.Exists("JB.MENU_TEAM.Update") then
timer.Stop("JB.MENU_TEAM.Update");
timer.Remove("JB.MENU_TEAM.Update");
end
frame = vgui.Create("JB.Frame");
frame:SetTitle("Team selection");
frame:SetSize(400,50+15+128+15+32+15+32);
local img = vgui.Create("DImage",frame);
img:SetSize(128,128);
img:SetPos(frame:GetWide()/4 * 3 - 128/2,30+15);
img:SetMaterial("materials/jailbreak_excl/logo_prisoner.png");
local img = vgui.Create("DImage",frame);
img:SetSize(128,128);
img:SetPos(frame:GetWide()/4 * 1 - 128/2,30+15);
img:SetMaterial("materials/jailbreak_excl/logo_guard.png");
local butGuard = vgui.Create("JB.Button",frame);
butGuard:SetSize(math.Round(frame:GetWide()/2 - 15*1.5),32);
butGuard:SetPos(15,frame:GetTall()-15-32-15-32);
butGuard:SetText("Guards ( "..#team.GetPlayers(TEAM_GUARD).." / "..JB:GetGuardsAllowed().." )");
butGuard.OnMouseReleased = function()
if LocalPlayer():Team() == TEAM_GUARD then
frame:Remove()
return;
end
if JB:GetGuardsAllowed() > #team.GetPlayers(TEAM_GUARD) then
RunConsoleCommand("jb_team_select_guard");
frame:Remove();
end
end
local butPrisoner = vgui.Create("JB.Button",frame);
butPrisoner:SetSize(math.Round(frame:GetWide()/2 - 15*1.5),32);
butPrisoner:SetPos(butGuard.x + butGuard:GetWide() + 15,frame:GetTall()-15-32-15-32);
butPrisoner:SetText("Prisoners ( "..#team.GetPlayers(TEAM_PRISONER).." )");
butPrisoner.OnMouseReleased = function()
if LocalPlayer():Team() ~= TEAM_PRISONER then
RunConsoleCommand("jb_team_select_prisoner");
end
frame:Remove();
end
local butSpec = vgui.Create("JB.Button",frame);
butSpec:SetSize(frame:GetWide()-15-15,32);
butSpec:SetPos(15,butPrisoner.y + butPrisoner:GetTall()+15);
butSpec:SetText("Spectate");
butSpec.OnMouseReleased = function()
if LocalPlayer():Team() ~= TEAM_SPECTATOR then
RunConsoleCommand("jb_team_select_spectator");
end
frame:Remove();
end
timer.Create("JB.MENU_TEAM.Update",.5,0,function()
if not IsValid(frame) or not IsValid(butGuard) or not IsValid(butPrisoner) then
if timer.Exists("JB.MENU_TEAM.Update") then
timer.Stop("JB.MENU_TEAM.Update");
timer.Remove("JB.MENU_TEAM.Update");
end
return;
end
butGuard:SetText("Guards ( "..#team.GetPlayers(TEAM_GUARD).." / "..JB:GetGuardsAllowed().." )");
butPrisoner:SetText("Prisoners ( "..#team.GetPlayers(TEAM_PRISONER).." )");
end);
frame:Center();
frame:MakePopup();
end

View File

@@ -0,0 +1,161 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local color_text = Color(230,230,230,200);
local frame;
function JB.MENU_WARDEN()
if IsValid(frame) then frame:Remove() end
if LocalPlayer().GetWarden and LocalPlayer():GetWarden() and tobool(JB.Config.wardenControl) then
frame = vgui.Create("JB.Frame");
frame:SetTitle("Warden controls");
frame:SetWide(320);
local yBottom = 30;
local lbl = Label("Game options",frame);
lbl:SetFont("JBLarge");
lbl:SetColor(JB.Color["#EEE"]);
lbl:SizeToContents();
lbl:SetPos(15,yBottom + 15);
yBottom = lbl.y + lbl:GetTall();
local function addButton(toggle,name,click)
if not toggle then
local btn = frame:Add("JB.Button");
btn:SetPos(15,yBottom+15);
btn:SetSize(frame:GetWide() - 30, 32);
btn:SetText(name);
btn.OnMouseReleased = click;
yBottom = btn.y + btn:GetTall();
else
local lbl = Label(name,frame);
lbl:SetFont("JBNormal");
lbl:SetColor(color_text);
lbl:SizeToContents();
lbl:SetPos(15+8,yBottom+15+32/2 - lbl:GetTall()/2);
local btn = frame:Add("JB.Button");
btn:SetPos(frame:GetWide()-15-64,yBottom+15);
btn:SetSize(64, 32);
btn:SetText(tobool(toggle) == true and "ON" or "OFF");
btn.OnMouseReleased = function()
btn:SetText(btn:GetText() == "OFF" and "ON" or "OFF");
click();
end
yBottom = btn.y + btn:GetTall();
end
end
addButton(tostring(IsValid(JB.TRANSMITTER) and JB.TRANSMITTER:GetJBWarden_PVPDamage()),"Friendlyfire for prisoners",function() RunConsoleCommand("jb_warden_changecontrol","PVP",tostring(not (IsValid(JB.TRANSMITTER) and JB.TRANSMITTER:GetJBWarden_PVPDamage()))) end);
addButton(tostring(IsValid(JB.TRANSMITTER) and JB.TRANSMITTER:GetJBWarden_ItemPickup()),"Item pickup",function() RunConsoleCommand("jb_warden_changecontrol","Pickup",tostring(not (IsValid(JB.TRANSMITTER) and JB.TRANSMITTER:GetJBWarden_ItemPickup()))); end);
yBottom = yBottom+16;
local lbl = Label("Object spawning",frame);
lbl:SetFont("JBLarge");
lbl:SetColor(JB.Color["#EEE"]);
lbl:SizeToContents();
lbl:SetPos(15,yBottom + 15);
yBottom = lbl.y + lbl:GetTall();
addButton(false,"Spawn ammo box",function() RunConsoleCommand("jb_warden_spawn","AmmoBox") end);
addButton(false,"Spawn breakable crate",function() RunConsoleCommand("jb_warden_spawn","Crate") end);
addButton(false,"Spawn blockade",function() RunConsoleCommand("jb_warden_spawn","Blockade") end);
frame:SetTall(yBottom+15);
frame:Center();
frame:MakePopup();
elseif JB.State == STATE_SETUP and not IsValid(JB:GetWarden()) then
frame = vgui.Create("JB.Frame");
frame:SetTitle("Claim warden");
local lbl = Label("Do not claim warden if you don't own a microphone or can't use your microphone.\nDistorted microphone owners and children ('squeekers') are not allowed to claim warden.",frame);
lbl:SetFont("JBSmall");
lbl:SetColor(color_text);
lbl:SizeToContents();
lbl:SetPos(15,30+15);
local btn = frame:Add("JB.Button");
btn:SetSize(math.Round(lbl:GetWide()),32);
btn:SetText("Claim Warden");
btn:SetPos(15,lbl.y + lbl:GetTall() + 15);
btn.OnMouseReleased = function()
RunConsoleCommand("jb_claim_warden");
frame:Remove();
end
frame:SetSize(lbl:GetWide() + 30,btn.y + btn:GetTall() + 15);
local setupTime;
local timeLeft;
frame.Think = function()
setupTime = tonumber(JB.Config.setupTime);
timeLeft = math.ceil(math.Clamp(setupTime - math.abs(CurTime() - JB.RoundStartTime),0,setupTime) );
if timeLeft <= 0 or IsValid(JB:GetWarden()) then
frame:Remove();
JB.MENU_WARDEN();
return;
end
frame:SetTitle("Claim Warden ("..timeLeft.." s)");
end
frame:Center();
frame:MakePopup();
else
frame = vgui.Create("JB.Frame");
frame:SetTitle("Claim warden");
local lbl = Label("You can only claim warden if it's the start of the round and there is no warden yet.",frame);
lbl:SetFont("JBSmall");
lbl:SetColor(color_text);
lbl:SizeToContents();
lbl:SetPos(15,30+15);
frame:SetSize(lbl:GetWide() + 30,30+15+lbl:GetTall()+15);
frame:Center();
frame:MakePopup();
end
end

View File

@@ -0,0 +1,151 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local NoticeMaterial = {}
NoticeMaterial[ NOTIFY_GENERIC ] = Material( "vgui/notices/generic" )
NoticeMaterial[ NOTIFY_ERROR ] = Material( "vgui/notices/error" )
NoticeMaterial[ NOTIFY_UNDO ] = Material( "vgui/notices/undo" )
NoticeMaterial[ NOTIFY_HINT ] = Material( "vgui/notices/hint" )
NoticeMaterial[ NOTIFY_CLEANUP ] = Material( "vgui/notices/cleanup" )
local Notices = {}
local activeNotice = nil;
local function queueNotification(text,type)
table.insert(Notices,{text=text,type=type});
JB:DebugPrint("Notification: "..text);
end
local function createNotice(key)
local pnl = vgui.Create("JBNoticePanel");
pnl.key = key;
pnl.text = Notices[key].text;
local t = Notices[key].type;
pnl.icon = NoticeMaterial[ t ];
pnl.type = t == NOTIFY_GENERIC and "NOTICE" or t == NOTIFY_ERROR and "ERROR" or t == NOTIFY_UNDO and "OBJECTIVE" or t == NOTIFY_HINT and "HINT" or "NOTICE";
activeNotice = pnl;
end
hook.Add("Think","JB.Think.UpdateNotifications", function()
if IsValid(activeNotice) then
activeNotice:Update();
if activeNotice:IsDone() then
table.remove(Notices,activeNotice.key);
activeNotice:Remove();
local key = table.GetFirstKey(Notices);
if key then
createNotice(key);
end
end
elseif table.GetFirstKey(Notices) then
createNotice(table.GetFirstKey(Notices));
end
end)
local state_expand,state_show,state_die = 1,2,3;
local bracket = Material("materials/jailbreak_excl/notify_bracket.png");
local bracket_wide = 16;
local bracket_tall = 64;
vgui.Register("JBNoticePanel",{
Init = function(self)
self.timeStateStart = SysTime();
self.text = "Undefined";
self.icon = NoticeMaterial[ NOTIFY_GENERIC ];
self.type = NOTIFY_GENERIC;
self.state = state_expand;
self.colorText = Color(255,255,255,0);
self.colorBrackets = Color(255,255,255,0);
self.distanceBrackets = 0;
self:SetSize(1,bracket_tall);
end,
Update = function(self)
surface.SetFont("JBLarge");
local wide = surface.GetTextSize(self.text);
local mul=FrameTime() * 60;
if self.state == state_expand then
local distance_max = (wide+16);
self.distanceBrackets = math.Clamp(math.ceil(Lerp(0.05 * mul,self.distanceBrackets,distance_max + 1)), self.distanceBrackets, distance_max);
self.colorBrackets.a = math.Clamp(math.ceil(Lerp(0.1 * mul,self.colorBrackets.a,256)), self.colorBrackets.a, 255);
self.colorText.a = math.Clamp(math.ceil(Lerp(0.05 * mul,self.colorText.a,256)), self.colorText.a, 255);
if self.distanceBrackets >= distance_max and self.colorText.a >= 255 and self.colorBrackets.a >= 255 then
self.state = state_show;
self.timeStateStart = SysTime();
end
elseif self.state == state_show then
if SysTime() > self.timeStateStart + .8 then
self.state = state_die;
self.timeStateStart = SysTime();
end
elseif self.state == state_die then
if self.colorText.a < 100 then
self.distanceBrackets = math.Clamp(math.floor(Lerp(0.15 * mul,self.distanceBrackets,-1)), 0, self.distanceBrackets);
self.colorBrackets.a = math.Clamp(math.floor(Lerp(0.15 * mul,self.colorBrackets.a,-1)), 0, self.colorBrackets.a);
end
self.colorText.a = math.Clamp(math.floor(Lerp(0.2 * mul,self.colorText.a,-1)), 0, self.colorText.a);
end
self:SetWide(self.distanceBrackets + (bracket_wide * 2));
self:SetPos(ScrW()/2 - self:GetWide()/2, ScrH()/10 * 3);
end,
Paint = function(self,w,h)
surface.SetDrawColor(self.colorBrackets);
surface.SetMaterial(bracket);
surface.DrawTexturedRectRotated(w/2 - bracket_wide/2 - self.distanceBrackets/2, h/2, bracket_wide, bracket_tall, 0) -- left bracket
surface.DrawTexturedRectRotated(w/2 + bracket_wide/2 + self.distanceBrackets/2, h/2, bracket_wide, bracket_tall, 180) -- right bracket
draw.SimpleText(self.type,"JBSmall",math.Round(w/2),8,self.colorText,1,0);
draw.SimpleText(self.text,"JBLarge",math.Round(w/2),h/2 + 6, self.colorText,1,1);
end,
IsDone = function(self)
return (self.state == state_die and self.distanceBrackets <= 0 );
end,
},"Panel");
net.Receive("JB.SendNotification",function()
queueNotification(net.ReadString(),NOTIFY_GENERIC);
end);
-- this is what I can "legacy support" :V
function notification.AddProgress() end
function notification.Kill() end
function notification.Die() end
notification.AddLegacy = queueNotification;

View File

@@ -0,0 +1,149 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local NoticeMaterial = {}
NoticeMaterial[ NOTIFY_GENERIC ] = Material( "vgui/notices/generic" )
NoticeMaterial[ NOTIFY_ERROR ] = Material( "vgui/notices/error" )
NoticeMaterial[ NOTIFY_UNDO ] = Material( "vgui/notices/undo" )
NoticeMaterial[ NOTIFY_HINT ] = Material( "vgui/notices/hint" )
NoticeMaterial[ NOTIFY_CLEANUP ] = Material( "vgui/notices/cleanup" )
local Notices = {}
local function createNotice(text,type)
local pnl = vgui.Create("JBQuickNoticePanel");
pnl.text = text;
pnl.type = type;
pnl.index = table.insert(Notices,pnl);
end
local matMiddle = Material("jailbreak_excl/notify_quick_middle.png");
local matEdge = Material("jailbreak_excl/notify_quick_edge.png");
local speed = 300;
local mul;
local fontNotify = "JBSmall";
local state_expand,state_show,state_die = 1,2,3;
vgui.Register("JBQuickNoticePanel",{
Init = function(self)
self.timeStateStart = SysTime();
self.text = "Undefined";
self.type = NOTIFY_GENERIC;
self.state = state_expand;
self.x = ScrW();
self.y = ScrH() * .4
self.xTrack = self.x;
self.yTrack = self.y;
end,
PerformLayout = function(self)
surface.SetFont(fontNotify);
local w = surface.GetTextSize(self.text or "Undefined");
w= math.Clamp(w+26,17,ScrW()/2); -- margin of 8 at each side
self:SetSize(w,32);
end,
Think = function(self)
for k,v in pairs(Notices)do
if v == self then
self.index = k;
end
end
-- commit suicide if we're done.
if self:IsDone() then
for k,v in pairs(Notices)do
if v==self then
table.remove(Notices,k);
break;
end
end
self:Remove();
return;
end
mul=FrameTime()*10
self.yTrack = Lerp(mul,self.yTrack,(ScrH() * .4) + ((self.index-1) * 32));
if self.state == state_expand then
-- increase X position by FrameTime() * speed
self.xTrack = Lerp(mul,self.xTrack,ScrW()-self:GetWide(),FrameTime() * speed);
if self.xTrack <= ScrW() - self:GetWide()+1 then
self.state = state_show;
self.timeStateStart = SysTime();
self.xTrack=(ScrW()-self:GetWide());
end
elseif self.state == state_show then
-- keep the notification where it is, only seet Y position in case an old notification dies.
if SysTime() > self.timeStateStart + 2.6 then
self.state = state_die;
self.timeStateStart = SysTime();
end
elseif self.state == state_die then
self.xTrack = Lerp(mul,self.xTrack,ScrW()+1);
end
self.x = math.Round(self.xTrack);
self.y = math.Round(self.yTrack);
end,
Paint = function(self,w,h)
if not self.text or not self.type or self.text == "" then return end
surface.SetDrawColor(JB.Color.white);
surface.SetMaterial(matEdge);
surface.DrawTexturedRect(0,0,16,32);
surface.SetMaterial(matMiddle);
surface.DrawTexturedRect(16,0,w-16,32);
draw.SimpleText(self.text,fontNotify.."Shadow",18,h/2,JB.Color.black,0,1);
draw.SimpleText(self.text,fontNotify,18,h/2,JB.Color["#EEE"],0,1);
end,
IsDone = function(self)
return (self.state == state_die and self.x >= ScrW() );
end,
},"Panel");
concommand.Add("testnotify",function()
createNotice("nigga wat",NOTIFY_GENERIC)
end);
net.Receive("JB.SendQuickNotification",function()
createNotice(net.ReadString(),NOTIFY_GENERIC);
end);

187
gamemode/core/cl_player.lua Normal file
View File

@@ -0,0 +1,187 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local cvarAlwaysSpectator = CreateClientConVar( "jb_cl_option_always_spectate", "0", true, false )
hook.Add("Initialize","JB.AutomateSpectatorSpawn",function()
if cvarAlwaysSpectator:GetBool() then
RunConsoleCommand("jb_team_select_spectator");
end
end)
function JB.Gamemode:KeyPress( ply, key )
if ( not IsFirstTimePredicted() ) then return end
if ( not IsValid( ply ) or ply ~= LocalPlayer() ) then return end
end
local fovSmooth;
local mulSpeed,angRightSmooth,angUpSmooth = 0,0,0;
local count=0;
function JB.Gamemode:CalcView( ply, pos, ang, fov, nearZ, farZ )
local ragdoll = LocalPlayer():GetRagdollEntity();
if IsValid(ragdoll) and LocalPlayer():GetObserverMode() == OBS_MODE_NONE then
local eyes = ragdoll:GetAttachment( ragdoll:LookupAttachment( "eyes" ) );
if not eyes then return end
local view = {
origin = eyes.Pos,
angles = eyes.Ang,
fov = 90,
};
return view;
end
if not fovSmooth then fovSmooth = fov end
mulSpeed=Lerp(FrameTime()*5,mulSpeed,math.Clamp((math.Clamp(ply:GetVelocity():Length(),ply:GetWalkSpeed(),ply:GetRunSpeed()) - ply:GetWalkSpeed())/(ply:GetRunSpeed() - ply:GetWalkSpeed()),0,1));
if ply:KeyDown(IN_SPEED) then
count=count+(FrameTime()*8)*mulSpeed;
fovSmooth= Lerp(FrameTime()*5,fovSmooth,(fov + mulSpeed * 10 ));
angRightSmooth= -math.abs(math.sin(count)*1);
angUpSmooth= math.sin(count)*1.5;
else
fovSmooth= Lerp(FrameTime()*20,fovSmooth,fov);
angRightSmooth= Lerp(FrameTime()*10,angRightSmooth,0);
angUpSmooth= Lerp(FrameTime()*10,angUpSmooth,0);
mulSpeed=0;
count=0;
end
ang:RotateAroundAxis(ang:Right(),angRightSmooth * 2);
ang:RotateAroundAxis(ang:Up(),angUpSmooth * 2);
return JB.Gamemode.BaseClass.CalcView(self,ply,pos,ang,fovSmooth, nearZ, farZ);
end
hook.Add( "PreDrawHalos", "JB.PreDrawHalos.AddHalos", function()
if JB.LastRequest ~= "0" and JB.LastRequestPlayers then
for k,v in pairs(JB.LastRequestPlayers)do
if not IsValid(v) or LocalPlayer() == v then continue; end
halo.Add({v},team.GetColor(v:Team()),1,1,2,true,true);
end
end
end )
local colorRm = 0;
local approachOne = 1;
local lastHealth = 0;
local ft;
hook.Add( "RenderScreenspaceEffects", "JB.RenderScreenspaceEffects.ProcessHealthEffects", function()
if LocalPlayer():GetObserverMode() == OBS_MODE_NONE then
local ft = FrameTime();
if lastHealth ~= LocalPlayer():Health() then
approachOne = 0;
end
lastHealth = LocalPlayer():Health();
approachOne = Lerp(ft*5,approachOne,1);
colorRm = Lerp(ft/4 * 3,colorRm,(math.Clamp(LocalPlayer():Health(),0,40)/40)*0.8);
local tab = {}
tab[ "$pp_colour_addr" ] = 0
tab[ "$pp_colour_addg" ] = 0
tab[ "$pp_colour_addb" ] = 0
tab[ "$pp_colour_brightness" ] = -.05 + approachOne*.05
tab[ "$pp_colour_contrast" ] = 1.1 - approachOne*.1
tab[ "$pp_colour_colour" ] = 1 - (.8 - colorRm)
tab[ "$pp_colour_mulr" ] = 0
tab[ "$pp_colour_mulg" ] = 0
tab[ "$pp_colour_mulb" ] = 0
DrawColorModify( tab )
end
end)
local cvarCrouchToggle = CreateClientConVar( "jb_cl_option_togglecrouch", "0", true, false )
local cvarWalkToggle = CreateClientConVar( "jb_cl_option_togglewalk", "0", true, false )
local walking = false;
hook.Add("PlayerBindPress", "JB.PlayerBindPress.KeyBinds", function(pl, bind, pressed)
if string.find( bind,"+menu_context" ) then
// see cl_context_menu.lua
elseif string.find( bind,"+menu" ) then
if pressed then
RunConsoleCommand("jb_dropweapon")
end
return true;
elseif string.find( bind,"+use" ) and pressed then
local tr = LocalPlayer():GetEyeTrace();
if tr and IsValid(tr.Entity) and tr.Entity:IsWeapon() then
RunConsoleCommand("jb_pickup");
return true;
end
elseif string.find( bind,"gm_showhelp" ) then
if pressed then
JB.MENU_HELP_OPTIONS();
end
return true;
elseif string.find( bind,"gm_showteam" ) then
if pressed then
JB.MENU_TEAM();
end
return true;
elseif string.find( bind,"gm_showspare2" ) then
if pressed then
if LocalPlayer():Team() == TEAM_PRISONER then
JB.MENU_LR();
elseif LocalPlayer():Team() == TEAM_GUARD then
JB.MENU_WARDEN()
end
end
return true;
elseif string.find( bind,"warden" ) then
return true;
elseif cvarCrouchToggle:GetBool() and pressed and string.find( bind,"duck" ) then
if pl:Crouching() then
pl:ConCommand("-duck");
else
pl:ConCommand("+duck");
end
return true;
elseif cvarWalkToggle:GetBool() and pressed and string.find( bind,"walk" ) then
if walking then
pl:ConCommand("-walk");
else
pl:ConCommand("+walk");
end
walking=!walking;
return true;
elseif string.find(bind,"+voicerecord") and pressed and ((pl:Team() == TEAM_PRISONER and (CurTime() - JB.RoundStartTime) < 30) or (not pl:Alive())) then
JB:DebugPrint("You can't use voice chat - you're dead or the round isn't 30 seconds in yet.");
return true;
end
end)

View File

@@ -0,0 +1,44 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local pmeta = FindMetaTable("Player");
local uniqueid;
local getname = pmeta.Nick;
function pmeta:Nick()
if tobool(JB.Config.prisonerNameChange) and LocalPlayer():Alive() and self:Alive() and self:Team() == TEAM_PRISONER then
uniqueid = self:UniqueID();
return (LocalPlayer():IsAdmin() and "["..getname(self).."] " or "Prisoner ")..(string.Right(uniqueid,string.len(uniqueid)/2));
end
return getname(self);
end

View File

@@ -0,0 +1,530 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
-- Support for admin mods below
(FindMetaTable("Player"))._jbGetRank = function(self)
if ES then -- This server uses ExcLServer
return (self:ESGetRank():GetPower() > 0 and self:ESGetRank():GetPrettyName()) or "";
else -- This server uses an unknown admin mod
return self:GetUserGroup() or ""
end
end
-- Scoreboard
local scoreboard;
local matEdge = Material("materials/jailbreak_excl/scoreboard_edge.png");
local matMiddle = Material("materials/jailbreak_excl/scoreboard_middle.png");
local matAva = Material("materials/jailbreak_excl/scoreboard_avatar.png");
local color_faded = Color(0,0,0,100)
vgui.Register("JBScoreboard.PlayerRow",{
Init = function( self )
self.Avatar = vgui.Create( "AvatarImage", self )
self.Avatar:SetSize( 32,32 )
self.Avatar:SetMouseInputEnabled( false )
self:Dock( TOP )
self:SetHeight(64)
self:DockMargin( 8,0,-24,-12 )
end,
PerformLayout = function(self)
if not IsValid(self.Player) then return end
local w,h = self:GetWide(), self:GetTall();
self.Avatar:SetPos(h/2 - self.Avatar:GetTall()/2, h/2 - self.Avatar:GetTall()/2);
end,
Setup = function( self, pl )
self.Player = pl
self.Avatar:SetPlayer( pl, 32 )
self:Think();
self:PerformLayout();
end,
OnCursorEntered = function(self)
self.hover = true;
end,
OnCursorExited = function(self)
self.hover = false;
end,
Think = function( self )
if ( !IsValid( self.Player ) ) then
self:MakeInvalid()
return
end
if ( !self.Player:Alive() ) then
self:SetZPos( 1000 )
else
self:SetZPos(0);
end
end,
MakeInvalid = function(self)
self:SetZPos(2000);
self:Remove();
end,
Paint = function( self, w, h )
if ( !IsValid( self.Player ) ) then
return
end
--rank
if self.Player:_jbGetRank() ~= "" then
local x = 70;
surface.SetFont("JBExtraSmall")
local w,h = surface.GetTextSize(self.Player:_jbGetRank())
draw.RoundedBoxEx(6,x,2,w+12,h+4,JB.Color.black,true,true,false,false)
draw.RoundedBoxEx(4,x+1,3,w+10,h+4,JB.Color["#222"],true,true,false,false)
draw.SimpleText(self.Player:_jbGetRank(),"JBExtraSmall",x+6,8,white,0,1)
end
surface.SetDrawColor(self.Player:Alive() and JB.Color.white or JB.Color["#AAA"]);
surface.SetMaterial(matEdge);
surface.DrawTexturedRectRotated(w-h/2,h/2,64,64,180);
surface.SetMaterial(matMiddle);
surface.DrawTexturedRectRotated(math.Round(w/2) - 16,h/2,math.Round(w - 64 - 32),64,0);
end,
OnMouseReleased=function(self)
if LocalPlayer():IsAdmin() then
local m = DermaMenu()
m:AddOption( "Force swap", function() RunConsoleCommand("jb_admin_swap",self.Player:SteamID() or "0"); end )
m:AddOption( "Make spectator", function() RunConsoleCommand("jb_admin_swap_spectator",self.Player:SteamID() or "0"); end )
m:AddOption( "Revive", function() RunConsoleCommand("jb_admin_revive",self.Player:SteamID() or "0"); end )
m:Open()
JB:DebugPrint("Opened admin menu.");
else
JB:DebugPrint("Failed to open admin menu. Not an admin.");
end
end,
PaintOver = function(self,w,h)
if ( !IsValid( self.Player ) ) then
return
end
local col = team.GetColor(self.Player:Team());
if not self.Player:Alive() then
col.r = math.Clamp(col.r *.6,0,255);
col.g = math.Clamp(col.g *.6,0,255);
col.b = math.Clamp(col.b *.6,0,255);
end
if self.Player == LocalPlayer() then
local add = math.abs(math.sin(CurTime() * 1) * 50);
col.r = math.Clamp(col.r +add,0,255);
col.g = math.Clamp(col.g +add,0,255);
col.b = math.Clamp(col.b +add,0,255);
end
surface.SetDrawColor(col);
surface.SetMaterial(matAva);
surface.DrawTexturedRectRotated(h/2,h/2,64,64,0);
local white = self.Player:Alive() and JB.Color.white or JB.Color["#BBB"]
--Name
local name=(self.hover and (self.Player:Deaths().." rounds" or "")..(ES and ", "..math.floor(tonumber(self.Player:ESGetNetworkedVariable("playtime",0))/60).." hours playtime" or "")) or self.Player:Nick();
draw.SimpleText(name,"JBSmallShadow",self.Avatar.x + self.Avatar:GetWide() + 16,h/2 - 1,JB.Color.black,0,1);
draw.SimpleText(name,"JBSmall",self.Avatar.x + self.Avatar:GetWide() + 16,h/2 - 1,white,0,1);
--Ping
draw.SimpleText(self.Player:Ping(),"JBSmallShadow",self:GetWide() - 32 - 24,h/2 - 1,JB.Color.black,1,1);
draw.SimpleText(self.Player:Ping(),"JBSmall",self:GetWide() - 32 - 24,h/2 - 1,white,1,1);
--score
surface.SetDrawColor(color_faded)
surface.DrawRect(self:GetWide()-64-42,16,36,32)
local score=self.Player:Frags()..":"..self.Player:Deaths();
draw.SimpleText(score,"JBSmallShadow",self:GetWide() - 64-24,h/2 - 1,JB.Color.black,1,1);
draw.SimpleText(score,"JBSmall",self:GetWide() - 64-24,h/2 - 1,white,1,1);
--status
if self.Player.GetWarden and self.Player:GetWarden() then
draw.SimpleText("Warden","JBLargeBold",self:GetWide()/2 + 26,26,color_faded,1)
elseif self.Player.GetRebel and self.Player:GetRebel() then
draw.SimpleText("Rebel","JBLargeBold",self:GetWide()/2 + 30,26,color_faded,1)
end
end
},"Panel");
vgui.Register("JBScoreboard.PlayerRow.Spectator",{
Init = function( self )
self.Avatar = vgui.Create( "AvatarImage", self )
self.Avatar:SetSize( 32,32 )
self.Avatar:SetMouseInputEnabled( false )
self:SetSize(64,64)
end,
PerformLayout = function(self)
if not IsValid(self.Player) then return end
local w,h = self:GetWide(), self:GetTall();
self.Avatar:SetPos(w/2 - self.Avatar:GetTall()/2, h/2 - self.Avatar:GetTall()/2);
end,
Setup = function( self, pl )
self.Player = pl
self.Avatar:SetPlayer( pl, 32 )
self:Think();
self:PerformLayout();
end,
Think = function( self )
if ( !IsValid( self.Player ) ) then
self:MakeInvalid()
return
end
end,
MakeInvalid = function(self)
self:Remove();
end,
OnCursorEntered = function(self)
if scoreboard.y < 0 then return end
local xSc,ySc = self:LocalToScreen( self:GetWide()/2,self:GetTall()/2 );
self.namePanel = vgui.Create("Panel");
self.namePanel:SetSize(900,24+8);
self.namePanel:NoClipping(false);
self.namePanel.ColorText = Color(255,255,255,0);
self.namePanel.PaintOver = function(this,w,h)
if not IsValid(self.Player) then return end
local w2=math.floor(this.wMv or 0);
surface.SetDrawColor(JB.Color.black);
draw.NoTexture();
surface.DrawPoly{
{x=w/2 - 4, y = h-8},
{x=w/2 + 4, y = h-8},
{x=w/2, y=h}
}
h=h-8;
draw.RoundedBox(2,w/2 -w2/2,0,w2,h,JB.Color.black);
draw.RoundedBox(4,w/2 -w2/2 + 2,2,w2-4,h-4,JB.Color["#111"]);
this.ColorText.a = Lerp(FrameTime()*1,this.ColorText.a,255);
w = JB.Util.drawSimpleShadowText(self.Player:Nick(),"JBSmall",w/2,h/2,this.ColorText,1,1);
this.wMv = Lerp(FrameTime()*18,this.wMv or 8,w + 12);
end
self.namePanel.Think = function(this)
if not IsValid(self) or not self:IsVisible() or not IsValid(scoreboard) or not scoreboard.Expand or not scoreboard:IsVisible() or ( IsValid(this) and not IsValid(self.namePanel) ) then this:Remove(); end
end
self.namePanel:SetPos(xSc - self.namePanel:GetWide()/2,ySc - 44 - self.namePanel:GetTall()/2);
end,
OnCursorExited = function(self)
if IsValid(self.namePanel) then
self.namePanel:Remove();
end
self.namePanel = nil;
end,
PaintOver = function(self,w,h)
if ( !IsValid( self.Player ) ) then
return
end
local col = team.GetColor(self.Player:Team());
if self.Player == LocalPlayer() then
local add = math.abs(math.sin(CurTime() * 1) * 50);
col.r = math.Clamp(col.r +add,0,255);
col.g = math.Clamp(col.g +add,0,255);
col.b = math.Clamp(col.b +add,0,255);
end
surface.SetDrawColor(col);
surface.SetMaterial(matAva);
surface.DrawTexturedRectRotated(w/2,h/2,64,64,0);
end
},"Panel");
local color_text = Color(255,255,255,0);
local color_shadow = Color(0,0,0,0);
local color_hidden = Color(0,0,0,0);
vgui.Register("JBScoreboard",{
Init = function( self )
self.Expand = true;
self.Header = self:Add( "Panel" )
self.Header:Dock( TOP )
self.Header:SetHeight( 100 )
self.Header:DockMargin(0,0,0,20)
self.Footer = self:Add( "Panel" )
self.Footer:Dock( BOTTOM )
self.Name = self.Header:Add( "DLabel" )
self.Name:SetFont( "JBExtraExtraLarge" )
self.Name:SetTextColor( color_text )
self.Name:Dock( TOP )
self.Name:SizeToContents();
self.Name:SetContentAlignment( 5 )
self.Name:SetText("Jail Break 7");
self.Spectators = self.Footer:Add( "DLabel" )
self.Spectators:SetFont("JBNormal");
self.Spectators:SetTextColor( color_text );
self.Spectators:Dock(TOP);
self.Spectators:SetContentAlignment( 5 )
self.Spectators:SetText("Spectators");
self.Spectators:SizeToContents();
self.Spectators:DockMargin(0,3,0,0);
self.ScoresSpectators = self.Footer:Add("Panel");
self.ScoresSpectators:Dock(TOP);
self.ScoresSpectators.Think = function(this)
if not self:IsVisible() then return end
local count=#this:GetChildren()
local perRow=math.floor(this:GetWide()/64);
local rows=math.ceil(count/perRow);
local row_current = 1;
local lastRowCount = count - (perRow*(rows-1));
local x = this:GetWide()/2 - (perRow*64)/2;
local y = 8;
local isFirst= true;
for k,v in ipairs(this:GetChildren())do
if not IsValid(v) then continue end
x=x+64;
if x > perRow*64 then
x=this:GetWide()/2 - (perRow*64)*2;
row_current=row_current+1;
isFirst = true;
y=y+64+4;
end
if row_current == rows and isFirst then
x= this:GetWide()/2 - (lastRowCount*64)/2 + 32;
end
v.x = x - 32;
v.y = y;
isFirst = false;
end
end
self.Host = self.Header:Add( "DLabel" )
self.Host:SetFont("JBNormal");
self.Host:SetTextColor( color_text );
self.Host:Dock(TOP);
self.Host:SetContentAlignment( 5 )
self.Host:SetText("A gamemode by Excl, hosted by "..JB.Config.website);
self.Host:SizeToContents();
self.ScoresGuards = self:Add( "DScrollPanel" )
self.ScoresGuards:Dock( LEFT )
self.ScoresPrisoners = self:Add( "DScrollPanel" )
self.ScoresPrisoners:Dock( RIGHT )
self:SetSize( 700, ScrH() - 200 )
self.y = -self:GetTall();
self.x = ScrW()/2 - self:GetWide()/2;
self.ySmooth = self.y;
end,
PerformLayout = function( self )
self.ScoresGuards:SetWide(self:GetWide()/2 - 8);
self.ScoresPrisoners:SetWide(self:GetWide()/2 - 8);
self.Host:SetWide(self:GetWide());
self.ScoresGuards:PerformLayout();
self.ScoresPrisoners:PerformLayout();
self.ScoresSpectators:SetSize(self.Footer:GetWide(),math.ceil(#self.ScoresSpectators:GetChildren()/(self.ScoresSpectators:GetWide()/64))*64+8*2);
self.Header:SetHeight( self.Name:GetTall()+20 )
local max = 0;
for k,v in pairs(self.Footer:GetChildren())do
if v.y + v:GetTall() > max then
max = v.y + v:GetTall();
end
end
self.Footer:SetHeight(max);
end,
Paint = function( self, w, h )
//DrawToyTown(2,ScrH());
end,
Think = function( self )
local w,h = self:GetWide(),self:GetTall();
if not self.Expand then
if math.floor(self.y) > -h then
color_text.a = Lerp(FrameTime()*12,color_text.a,0);
color_shadow.a = color_text.a * .8;
if math.floor(color_text.a) <= 1 then
self.ySmooth = Lerp(FrameTime()*3,self.ySmooth,-h);
self.y = math.Round(self.ySmooth);
end
self.Name:SetTextColor( color_text )
self.Host:SetTextColor( color_text );
self.Name:SetExpensiveShadow( 2, color_shadow )
self.Host:SetExpensiveShadow( 1, color_shadow )
if #self.ScoresSpectators:GetChildren() <= 0 then
self.Spectators:SetTextColor( color_hidden );
self.Spectators:SetExpensiveShadow( 1, color_hidden )
else
self.Spectators:SetTextColor( color_text );
self.Spectators:SetExpensiveShadow( 1, color_shadow )
end
elseif self:IsVisible() and not self.Expand and math.floor(self.ySmooth) <= -h + 1 then
self:Hide();
color_text.a = 0;
JB:DebugPrint("Scoreboard hidden");
end
return
end
local target = (ScrH()/2 - h/2);
self.ySmooth = Lerp(FrameTime()*10,self.ySmooth,target);
self.y = math.Round(self.ySmooth);
if math.ceil(self.ySmooth) >= target then
color_text.a = Lerp(FrameTime()*2,color_text.a,255);
color_shadow.a = color_text.a * .8;
self.Name:SetTextColor( color_text )
self.Host:SetTextColor( color_text );
if #self.ScoresSpectators:GetChildren() <= 0 then
self.Spectators:SetTextColor( color_hidden );
self.Spectators:SetExpensiveShadow( 1, color_hidden )
else
self.Spectators:SetTextColor( color_text );
self.Spectators:SetExpensiveShadow( 1, color_shadow )
end
self.Name:SetExpensiveShadow( 2, color_shadow )
self.Host:SetExpensiveShadow( 1, color_shadow )
end
for id, pl in pairs( player.GetAll() ) do
if ( IsValid( pl.ScoreEntry ) ) then
if (pl:Team() ~= pl.ScoreEntry.Team or (not IsValid(pl.ScoreEntry.scoreboard)) or pl.ScoreEntry.scoreboard ~= self) then
JB:DebugPrint("Removed invalid score panel");
pl.ScoreEntry:MakeInvalid();
else
continue;
end
end
if pl:Team() == TEAM_GUARD or pl:Team() == TEAM_PRISONER then
pl.ScoreEntry = vgui.Create("JBScoreboard.PlayerRow" );
pl.ScoreEntry:Setup( pl );
if pl:Team() == TEAM_PRISONER then
self.ScoresPrisoners:AddItem( pl.ScoreEntry );
pl.ScoreEntry.scoreboard = self;
pl.ScoreEntry.Team = TEAM_PRISONER;
elseif pl:Team() == TEAM_GUARD then
self.ScoresGuards:AddItem( pl.ScoreEntry );
pl.ScoreEntry.scoreboard = self;
pl.ScoreEntry.Team = TEAM_GUARD;
end
elseif pl:Team() == TEAM_SPECTATOR or pl:Team() == TEAM_UNASSIGNED then
pl.ScoreEntry = self.ScoresSpectators:Add("JBScoreboard.PlayerRow.Spectator");
pl.ScoreEntry:Setup(pl);
pl.ScoreEntry.scoreboard = self;
pl.ScoreEntry.Team = pl:Team();
end
end
end,
},"Panel");
timer.Create("JB.Scoreboard.UpdateLayout",1,0,function()
if IsValid(scoreboard) then
scoreboard:PerformLayout();
end
end);
JB.Gamemode.ScoreboardShow = function()
if ( !IsValid( scoreboard ) ) then
scoreboard = vgui.Create("JBScoreboard");
end
if ( IsValid( scoreboard ) ) then
scoreboard.Expand = true;
scoreboard:Show()
//scoreboard:MakePopup()
gui.EnableScreenClicker(true);
scoreboard:SetKeyboardInputEnabled( false )
JB:DebugPrint("Scoreboard shown");
end
end
JB.Gamemode.ScoreboardHide = function()
if ( IsValid( scoreboard ) ) then
scoreboard.Expand = false;
gui.EnableScreenClicker(false);
end
end

217
gamemode/core/cl_voice.lua Normal file
View File

@@ -0,0 +1,217 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local PANEL = {}
local PlayerVoicePanels = {}
local matAva = Material("materials/jailbreak_excl/scoreboard_avatar.png");
function PANEL:Init()
self.LabelName = vgui.Create( "DLabel", self )
self.LabelName:SetFont( "JBNormal" )
self.LabelName:Dock( FILL )
self.LabelName:DockMargin( 14, 0, 0, 0 )
self.LabelName:SetTextColor( JB.Color.white )
self.LabelName:SetExpensiveShadow( 2, Color( 0, 0, 0, 200 ) )
self.Avatar = vgui.Create( "AvatarImage", self )
self.Avatar:Dock( LEFT );
self.Avatar:SetSize( 32, 32 )
self.Color = JB.Color["#aaa"];
self:SetSize( 250, 32 + 8 )
self:DockPadding( 4, 4, 4, 4 )
self:DockMargin( 0, 6, 0, 6 )
self:Dock( BOTTOM )
self.SoundLines = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
self:NoClipping(true);
end
function PANEL:Setup( ply )
self.ply = ply
self.LabelName:SetText( ply:Nick() )
self.Avatar:SetPlayer( ply )
self.Color = team.GetColor( ply:Team() )
self.Color.a = 50;
self:InvalidateLayout()
end
local iconWarden=Material("icon16/asterisk_yellow.png");
local matGradient=Material("jailbreak_excl/gradient.png");
function PANEL:Paint( w, h )
if ( !IsValid( self.ply ) ) then return end
draw.RoundedBox( 0, 20, 4, w - 20, h-8, JB.Color.black )
draw.RoundedBox( 0, 21, 5, w-2 - 20, h-10, JB.Color["#111"] )
self.Color.a = 2
surface.SetDrawColor(self.Color);
surface.SetMaterial(matGradient);
surface.DrawTexturedRectRotated(20 + (w-20)/2,h/2,w-2 - 20, h-10,180);
for i=1,60 do
self.Color.a = (30 - (math.sin(math.pi/2 - (i/30 * math.pi)) * 30));
surface.SetDrawColor(self.Color);
surface.DrawRect(w-(3*i),h/2-(self.SoundLines[i]*24/2),1,1+self.SoundLines[i]*24);
end
if self.ply.GetWarden and self.ply:GetWarden() then
surface.SetDrawColor(JB.Color.white);
surface.SetMaterial(iconWarden);
surface.DrawTexturedRect(w - 16 - (h-16)/2, (h-16)/2, 16, 16);
end
end
function PANEL:PaintOver()
if not IsValid(self.ply) or not IsValid(self.Avatar) then return end
local w,h = self.Avatar:GetSize();
local col = team.GetColor(self.ply:Team());
if not self.ply:Alive() then
col.r = math.Clamp(col.r *.6,0,255);
col.g = math.Clamp(col.g *.6,0,255);
col.b = math.Clamp(col.b *.6,0,255);
end
if self.ply == LocalPlayer() then
local add = math.abs(math.sin(CurTime() * 1) * 30);
col.r = math.Clamp(col.r +add,0,255);
col.g = math.Clamp(col.g +add,0,255);
col.b = math.Clamp(col.b +add,0,255);
end
surface.SetDrawColor(col);
surface.SetMaterial(matAva);
surface.DrawTexturedRectRotated(self.Avatar.x + h/2,self.Avatar.y + h/2,64,64,0);
end
function PANEL:Think( )
if ( self.fadeAnim ) then
self.fadeAnim:Run()
end
if not IsValid(self.ply) then return end
if not self.nextLine or self.nextLine <= CurTime() then
self.nextLine = CurTime() + 1/60 -- This will make the effect cap at 60 fps.
local vol = (self.ply == LocalPlayer()) and math.Rand(0,1) or self.ply:VoiceVolume();
table.insert(self.SoundLines,1,Lerp(0.4,self.SoundLines[1],vol));
table.remove(self.SoundLines,61);
end
end
function PANEL:FadeOut( anim, delta, data )
if ( anim.Finished ) then
if ( IsValid( PlayerVoicePanels[ self.ply ] ) ) then
PlayerVoicePanels[ self.ply ]:Remove()
PlayerVoicePanels[ self.ply ] = nil
return
end
return end
self:SetAlpha( 255 - (255 * delta) )
end
derma.DefineControl( "VoiceNotify", "", PANEL, "DPanel" )
function GM:PlayerStartVoice( ply )
if ( !IsValid( g_VoicePanelList ) ) then return end
-- There'd be an exta one if voice_loopback is on, so remove it.
GAMEMODE:PlayerEndVoice( ply )
if ( IsValid( PlayerVoicePanels[ ply ] ) ) then
if ( PlayerVoicePanels[ ply ].fadeAnim ) then
PlayerVoicePanels[ ply ].fadeAnim:Stop()
PlayerVoicePanels[ ply ].fadeAnim = nil
end
PlayerVoicePanels[ ply ]:SetAlpha( 255 )
return;
end
if ( !IsValid( ply ) ) then return end
local pnl = g_VoicePanelList:Add( "VoiceNotify" )
pnl:Setup( ply )
PlayerVoicePanels[ ply ] = pnl
end
timer.Create( "JB.VoiceClean", 10, 0, function()
for k, v in pairs( PlayerVoicePanels ) do
if ( !IsValid( k ) ) then
GAMEMODE:PlayerEndVoice( k )
end
end
end )
timer.Remove("VoiceClean");
function JB.Gamemode:PlayerEndVoice( ply )
if ( IsValid( PlayerVoicePanels[ ply ] ) ) then
if ( PlayerVoicePanels[ ply ].fadeAnim ) then return end
PlayerVoicePanels[ ply ].fadeAnim = Derma_Anim( "FadeOut", PlayerVoicePanels[ ply ], PlayerVoicePanels[ ply ].FadeOut )
PlayerVoicePanels[ ply ].fadeAnim:Start( .1 )
end
end
hook.Add( "InitPostEntity", "JB.InitPostEntity.CreateVoiceVGUI", function()
g_VoicePanelList = vgui.Create( "DPanel" )
g_VoicePanelList:ParentToHUD()
g_VoicePanelList:SetPos( ScrW() - 250, 50 )
g_VoicePanelList:SetSize( 250, ScrH() - 100 )
g_VoicePanelList:SetDrawBackground( false )
end )
hook.Remove("InitPostEntity","CreateVoiceVGUI");

View File

@@ -0,0 +1,60 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
JB.Color = {};
-- just a stupid conveinience function for adding new colors on the fly.
setmetatable(JB.Color,{
__index = function(tbl,key)
if type(key) == "string" and string.Left(key,1) == "#" and (string.len(key) == 4 or string.len(key) == 7) then
local hex = key:gsub("#","");
if string.len(hex) == 3 then
local real = "";
for i=1,3 do
real=real..hex[i]..hex[i];
end
hex=real;
end
local rgb=Color(tonumber("0x"..hex:sub(1,2)), tonumber("0x"..hex:sub(3,4)), tonumber("0x"..hex:sub(5,6)));
tbl[key] = rgb; -- cache result
return rgb;
end
return Color(255,255,0,200);
end
});
JB.Color.black = Color(0,0,0);
JB.Color.white = Color(255,255,255);

View File

@@ -0,0 +1,7 @@
if ES then --ExclServer support
if CLIENT then
hook.Add("ESSupressCustomVoice","JB.SupressESVoice",function()
return true
end)
end
end

View File

@@ -0,0 +1,37 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
JB.Gamemode.PlayerNoClip = function(gm,p)
return p:IsSuperAdmin();
end

View File

@@ -0,0 +1,49 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local pmeta = FindMetaTable("Player");
function pmeta:CanPickupWeapon(entity)
if table.Count(self:GetWeapons()) > 0 then
for k,v in pairs(self:GetWeapons()) do
if v.Slot == entity.Slot or v:GetClass() == entity:GetClass() then
return false
end
end
end
return true;
end
function pmeta:GetWarden()
return (JB:GetWarden() == self);
end

543
gamemode/core/sh_state.lua Normal file
View File

@@ -0,0 +1,543 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
--------------------------------------------------------------------------------------
--
--
-- REGARDING CUSTOM MAPVOTE SYSTEMS:
--
-- _________________________
--
--
-- If you want to code your own mapvote, hook the JailBreakStartMapvote hook,
-- start your own mapvote here. Remember to return true in order to stop the
-- round system for a while, while you run your mapvote.
--
-- _________________________
--
--
-- You might want to use the following functions as well if you're writing a
-- custom mapvote:
--
-- JB:Mapvote_ExtendCurrentMap()
-- JB:Mapvote_StartMapVote()
--
--
--------------------------------------------------------------------------------------
/*
Compatability hooks - implement these in your admin mods
*/
function JB.Gamemode.JailBreakStartMapvote(rounds_passed,extentions_passed) // hook.Add("JailBreakStartMapvote",...) to implement your own mapvote. NOTE: Remember to return true!
return false // return true in your own mapvote function, else there won't be a pause between rounds!
end
/*
State chaining
*/
local chainState;
if SERVER then
local stateTime = 0;
local stateCallback;
hook.Add("Think","JB.Think.StateLogic",function()
if stateTime > 0 and stateTime < CurTime() then
JB:DebugPrint("State chain ended")
stateTime = 0
stateCallback()
end
end)
chainState=function(state,time,callback)
JB:DebugPrint("State chained: "..tostring(state).." ["..tostring(time).." s]["..tostring(callback).."]")
JB.State = state;
stateTime=CurTime()+time;
stateCallback=callback;
end
concommand.Add("testtime",function()
print(stateTime,CurTime(),stateTime<CurTime())
end)
end
/*
Utility functions
*/
local ententionsDone = 0;
function JB:Mapvote_ExtendCurrentMap() // You can call this from your own admin mod/mapvote if you want to extend the current map.
JB.RoundsPassed = 0;
ententionsDone = ententionsDone+1;
chainState(STATE_ENDED,5,function()
JB:NewRound();
end);
end
function JB:Mapvote_StartMapVote() // You can call this from your admin mod/mapvote to initiate a mapvote.
if hook.Call("JailBreakStartMapvote",JB.Gamemode,JB.RoundsPassed,ententionsDone) then
JB.State = STATE_MAPVOTE;
return true;
end
return false;
end
/*
Enums
*/
STATE_IDLE = 1; -- when the map loads, we wait for everyone to join
STATE_SETUP = 2; -- first few seconds of the round, when everyone can still spawn and damage is disabled
STATE_PLAYING = 3; -- normal playing
STATE_LASTREQUEST = 4; -- last request taking place, special rules apply
STATE_ENDED = 5; -- round ended, waiting for next round to start
STATE_MAPVOTE = 6; -- voting for a map, will result in either a new map loading or restarting the current without reloading
/*
Network strings
*/
if SERVER then
util.AddNetworkString("JB.LR.GetReady");
util.AddNetworkString("JB.SendRoundUpdate");
end
/*
Special days
*/
local function resetSpecial()
if SERVER then
game.ConsoleCommand("sv_gravity 600;\n")
game.ConsoleCommand("sv_friction 8;\n")
elseif CLIENT then
end
end
if SERVER then
JB.SpecialDays = {
["Low-Gravity Knife Party"] = function()
game.ConsoleCommand("sv_gravity 200;\n")
game.ConsoleCommand("sv_friction 3;\n")
for k,v in ipairs(team.GetPlayers(TEAM_PRISONER))do
v:SetJumpPower(400)
v:StripWeapons()
v:Give("weapon_jb_knife")
end
for k,v in ipairs(team.GetPlayers(TEAM_GUARD))do
v:SetJumpPower(400)
v:StripWeapons()
v:Give("weapon_jb_knife")
end
for k,v in ipairs(ents.GetAll())do
if IsValid(v) and v.GetClass and string.Left(v:GetClass(),string.len("weapon_jb_")) == "weapon_jb_" and v:GetClass() ~= "weapon_jb_knife" then
v:Remove()
end
end
for k,v in ipairs(ents.FindByClass("func_door"))do
v:Fire("Open",1)
end
for k,v in ipairs(ents.FindByClass("func_door_rotating"))do
v:Fire("Open",1)
end
for k,v in ipairs(ents.FindByClass("func_movelinear"))do
v:Fire("Open",1)
end
end,
["Guns for everyone"] = function()
for k,v in ipairs(team.GetPlayers(TEAM_PRISONER))do
v:Give("weapon_jb_deagle")
v:SelectWeapon("weapon_jb_deagle")
end
for k,v in ipairs(ents.FindByClass("func_door"))do
v:Fire("Open",1)
end
for k,v in ipairs(ents.FindByClass("func_door_rotating"))do
v:Fire("Open",1)
end
for k,v in ipairs(ents.FindByClass("func_movelinear"))do
v:Fire("Open",1)
end
end,
["Super heros"] = function()
for k,v in ipairs(team.GetPlayers(TEAM_PRISONER))do
v:SetRunSpeed(600)
v:SetWalkSpeed(270)
v:SetJumpPower(400)
end
for k,v in ipairs(ents.FindByClass("func_door"))do
v:Fire("Open",1)
end
for k,v in ipairs(ents.FindByClass("func_door_rotating"))do
v:Fire("Open",1)
end
for k,v in ipairs(ents.FindByClass("func_movelinear"))do
v:Fire("Open",1)
end
end,
["Slow guards"] = function()
for k,v in ipairs(team.GetPlayers(TEAM_GUARD))do
v:SetRunSpeed(100)
v:SetWalkSpeed(100)
end
for k,v in ipairs(ents.FindByClass("func_door"))do
v:Fire("Open",1)
end
for k,v in ipairs(ents.FindByClass("func_door_rotating"))do
v:Fire("Open",1)
end
for k,v in ipairs(ents.FindByClass("func_movelinear"))do
v:Fire("Open",1)
end
end
}
end
/*
Round System
*/
JB.ThisRound = {};
local wantStartup = false;
function JB:NewRound(rounds_passed)
rounds_passed = rounds_passed or JB.RoundsPassed;
JB.ThisRound = {};
if SERVER then
game.CleanUpMap();
rounds_passed = rounds_passed + 1;
JB.RoundsPassed = rounds_passed;
JB.RoundStartTime = CurTime();
chainState(STATE_SETUP,tonumber(JB.Config.setupTime),function()
JB:DebugPrint("Setup finished, round started.")
chainState(STATE_PLAYING,(600) - tonumber(JB.Config.setupTime),function()
JB:EndRound();
end);
if not IsValid(JB:GetWarden()) then
JB:DebugPrint("No warden after setup time; Freeday!")
JB:BroadcastNotification("Today is a freeday");
end
end);
if JB.RoundsPassed == 1 then
local count=table.Count(JB.SpecialDays)
local which=math.random(1,count)
count=0;
for k,v in pairs(JB.SpecialDays)do
count=count+1
if count == which then
which=k;
break;
end
end
if JB.SpecialDays[which] then
JB:BroadcastNotification("First round: "..which)
JB.SpecialDays[which]();
JB.ThisRound.IsSpecialRound = true;
end
end
if IsValid(JB.TRANSMITTER) then
JB.TRANSMITTER:SetJBWarden_PVPDamage(false);
JB.TRANSMITTER:SetJBWarden_ItemPickup(false);
JB.TRANSMITTER:SetJBWarden_PointerType("0");
JB.TRANSMITTER:SetJBWarden(NULL);
end
JB:BalanceTeams()
JB.Util.iterate(player.GetAll()):SetRebel(false):Spawn();
timer.Simple(1,function()
JB.Util.iterate(player.GetAll()):Freeze(false);
end)
net.Start("JB.SendRoundUpdate"); net.WriteInt(STATE_SETUP,8); net.WriteInt(rounds_passed,32); net.Broadcast();
elseif CLIENT and IsValid(LocalPlayer()) then
notification.AddLegacy("Round "..rounds_passed,NOTIFY_GENERIC);
LocalPlayer():ConCommand("-voicerecord");
end
hook.Call("JailBreakRoundStart",JB.Gamemode,JB.RoundsPassed);
end
function JB:EndRound(winner)
if JB.ThisRound.IsSpecialRound then
resetSpecial()
end
if SERVER then
if JB.RoundsPassed >= tonumber(JB.Config.roundsPerMap) and JB:Mapvote_StartMapVote() then
return; // Halt the round system; we're running a custom mapvote!
end
chainState(STATE_ENDED,5,function()
JB.Util.iterate(player.GetAll()):Freeze(true);
JB:NewRound();
end);
net.Start("JB.GetLogs");
net.WriteTable(JB.ThisRound and JB.ThisRound.Logs or {});
net.WriteBit(true);
net.Broadcast(p);
net.Start("JB.SendRoundUpdate"); net.WriteInt(STATE_ENDED,8); net.WriteInt(winner or 0, 8); net.Broadcast();
elseif CLIENT then
notification.AddLegacy(winner == TEAM_PRISONER and "Prisoners win" or winner == TEAM_GUARD and "Guards win" or "Draw",NOTIFY_GENERIC);
end
hook.Call("JailBreakRoundEnd",JB.Gamemode,JB.RoundsPassed);
end
if CLIENT then
net.Receive("JB.SendRoundUpdate",function()
local state = net.ReadInt(8);
if state == STATE_ENDED then
JB:EndRound(net.ReadInt(8));
elseif state == STATE_SETUP then
JB:NewRound(net.ReadInt(32));
end
end);
elseif SERVER then
timer.Create("JBRoundEndLogic",1,0,function()
if JB.State == STATE_IDLE and wantStartup then
if #team.GetPlayers(TEAM_GUARD) >= 1 and #team.GetPlayers(TEAM_PRISONER) >= 1 then
JB:DebugPrint("State is currently idle, but people have joined; Starting round 1.")
JB:NewRound();
end
end
if (JB.State ~= STATE_PLAYING and JB.State ~= STATE_SETUP and JB.State ~= STATE_LASTREQUEST) or #team.GetPlayers(TEAM_GUARD) < 1 or #team.GetPlayers(TEAM_PRISONER) < 1 then return end
local count_guard = JB:AliveGuards();
local count_prisoner = JB:AlivePrisoners();
if count_prisoner < 1 and count_guard < 1 then
JB:EndRound(0); -- both win!
elseif count_prisoner < 1 then
JB:EndRound(TEAM_GUARD);
elseif count_guard < 1 then
JB:EndRound(TEAM_PRISONER);
end
end);
end
/*
Transmission Entity
*/
JB.TRANSMITTER = JB.TRANSMITTER or NULL;
hook.Add("InitPostEntity","JB.InitPostEntity.SpawnStateTransmit",function()
if SERVER and not IsValid(JB.TRANSMITTER) then
JB.TRANSMITTER = ents.Create("jb_transmitter_state");
JB.TRANSMITTER:Spawn();
JB.TRANSMITTER:Activate();
chainState(STATE_IDLE,tonumber(JB.Config.joinTime),function()
wantStartup = true; -- request a startup.
end);
elseif CLIENT then
timer.Simple(0,function()
notification.AddLegacy("Welcome to Jail Break 7",NOTIFY_GENERIC);
if JB.State == STATE_IDLE then
notification.AddLegacy("The round will start once everyone had a chance to join",NOTIFY_GENERIC);
elseif JB.State == STATE_PLAYING or JB.State == STATE_LASTREQUEST then
notification.AddLegacy("A round is currently in progress",NOTIFY_GENERIC);
notification.AddLegacy("You will spawn when the current ends",NOTIFY_GENERIC);
elseif JB.State == STATE_MAPVOTE then
notification.AddLegacy("A mapvote is currently in progress",NOTIFY_GENERIC);
end
end);
end
end);
if CLIENT then
hook.Add("OnEntityCreated","JB.OnEntityCreated.SelectTransmitter",function(ent)
if ent:GetClass() == "jb_transmitter_state" and not IsValid(JB.TRANSMITTER) then
JB.TRANSMITTER = ent;
JB:DebugPrint("Transmitter found (OnEntityCreated)");
end
end)
timer.Create("JB.CheckOnStateTransmitter",10,0,function()
if not IsValid(JB.TRANSMITTER) then
JB:DebugPrint("Panic! State Transmitter not found!");
local trans=ents.FindByClass("jb_transmitter_state");
if trans and trans[1] and IsValid(trans[1]) then
JB.TRANSMITTER=trans[1];
JB:DebugPrint("Automatically resolved; Transmitter relocated.");
else
JB:DebugPrint("Failed to locate transmitter - contact a developer!");
end
end
end);
end
/*
Index Callback methods
*/
// State
JB._IndexCallback.State = {
get = function()
return IsValid(JB.TRANSMITTER) and JB.TRANSMITTER.GetJBState and JB.TRANSMITTER:GetJBState() or STATE_IDLE;
end,
set = function(state)
if SERVER and IsValid(JB.TRANSMITTER) then
JB.TRANSMITTER:SetJBState(state or STATE_IDLE);
JB:DebugPrint("State changed to: "..state)
else
Error("Can not set state!")
end
end
}
// Round-related methods.
JB._IndexCallback.RoundsPassed = {
get = function()
return IsValid(JB.TRANSMITTER) and JB.TRANSMITTER.GetJBRoundsPassed and JB.TRANSMITTER:GetJBRoundsPassed() or 0;
end,
set = function(amount)
if SERVER and IsValid(JB.TRANSMITTER) then
JB.TRANSMITTER:SetJBRoundsPassed(amount > 0 and amount or 0);
else
Error("Can not set rounds passed!");
end
end
}
JB._IndexCallback.RoundStartTime = {
get = function()
return IsValid(JB.TRANSMITTER) and JB.TRANSMITTER.GetJBRoundStartTime and JB.TRANSMITTER:GetJBRoundStartTime() or 0;
end,
set = function(amount)
if SERVER and IsValid(JB.TRANSMITTER) then
JB.TRANSMITTER:SetJBRoundStartTime(amount > 0 and amount or 0);
else
Error("Can not set round start time!");
end
end
}
// Last Request-related methods.
JB._IndexCallback.LastRequest = {
get = function()
return (JB.State == STATE_LASTREQUEST) and JB.TRANSMITTER:GetJBLastRequestPicked() or "0";
end,
set = function(tab)
if not IsValid(JB.TRANSMITTER) or not SERVER then return end
if not tab or type(tab) ~= "table" or not tab.type or not JB.ValidLR(JB.LastRequestTypes[tab.type]) or not IsValid(tab.prisoner) or not IsValid(tab.guard) then
JB.TRANSMITTER:SetJBLastRequestPicked("0");
if not pcall(function() JB:DebugPrint("Attempted to select invalid LR: ",tab.type," ",tab.prisoner," ",tab.guard," ",type(tab)); end) then JB:DebugPrint("Unexptected LR sequence abortion!"); end
return
end
JB.TRANSMITTER:SetJBLastRequestPrisoner(tab.prisoner);
JB.TRANSMITTER:SetJBLastRequestGuard(tab.guard);
JB.TRANSMITTER:SetJBLastRequestPicked(tab.type);
chainState(STATE_LASTREQUEST,180,function() JB:EndRound() end)
JB.RoundStartTime = CurTime();
JB:BroadcastNotification(tab.prisoner:Nick().." requested a "..JB.LastRequestTypes[tab.type]:GetName(),{tab.prisoner,tab.guard})
JB:DebugPrint("LR Initiated! ",tab.prisoner," vs ",tab.guard);
local players={tab.guard,tab.prisoner};
JB.Util.iterate (players) : Freeze(true) : StripWeapons() : GodEnable() : SetHealth(100) : SetArmor(0);
if not JB.LastRequestTypes[tab.type].setupCallback(tab.prisoner,tab.guard) then
net.Start("JB.LR.GetReady");
net.WriteString(tab.type);
net.Send(players);
timer.Simple(7,function()
if not JB.Util.isValid(tab.prisoner,tab.guard) then return end
JB.Util.iterate (players) : Freeze(false) : GodDisable();
timer.Simple(.5,function()
if not JB.Util.isValid(tab.prisoner,tab.guard) then return end
JB.LastRequestTypes[tab.type].startCallback(tab.prisoner,tab.guard);
end);
end)
end
end
}
JB._IndexCallback.LastRequestPlayers = {
get = function()
return JB.State == STATE_LASTREQUEST and {JB.TRANSMITTER:GetJBLastRequestGuard() or NULL, JB.TRANSMITTER:GetJBLastRequestPrisoner() or NULL} or {NULL,NULL};
end,
set = function()
Error("Tried to set LR players through invalid methods!");
end
}
/*
Prevent Cleanup
*/
local old_cleanup = game.CleanUpMap;
function game.CleanUpMap(send,tab)
if not tab then tab = {} end
table.insert(tab,"jb_transmitter_state");
old_cleanup(send,tab);
end

View File

@@ -0,0 +1,80 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
JB.LastRequestTypes = {};
local nothing=function() end;
local LR = {};
AccessorFunc(LR,"name","Name",FORCE_STRING);
AccessorFunc(LR,"description","Description",FORCE_STRING);
AccessorFunc(LR,"icon","Icon");
AccessorFunc(LR,"id","ID",FORCE_STRING);
AccessorFunc(LR,"canPickupWeapons","CanPickupWeapons",FORCE_BOOL);
AccessorFunc(LR,"canDropWeapons","CanDropWeapons",FORCE_BOOL)
function JB.CLASS_LR()
local tab = {};
setmetatable(tab,LR);
LR.__index = LR;
tab.startCallback = nothing;
tab.setupCallback = nothing;
tab:SetName("UNDEFINED");
tab:SetDescription("UNDEFINED");
tab:SetIcon(Material("icon16/bug.png"))
tab:SetCanPickupWeapons(false);
tab:SetCanDropWeapons(false);
return tab;
end
function LR:SetStartCallback(fc)
self.startCallback = fc;
end
function LR:SetSetupCallback(fc)
self.setupCallback = fc;
end
function LR:__call()
self:SetID( tostring( util.CRC(self:GetName()) ) );
JB.LastRequestTypes[self:GetID()] = self;
return self:GetID()
end
function JB.ValidLR(lr)
if not lr or not lr.id then
return false;
end
return true;
end

View File

@@ -0,0 +1,95 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
TEAM_GUARD = 2;
TEAM_PRISONER = 1;
JB.Gamemode.CreateTeams = function()
team.SetUp( TEAM_GUARD, "Guards", JB.Color["#0066FF"] )
team.SetUp( TEAM_PRISONER, "Prisoners", JB.Color["#E31100"] )
team.SetSpawnPoint( TEAM_GUARD,"info_player_counterterrorist" );
team.SetSpawnPoint( TEAM_PRISONER,"info_player_terrorist" );
team.SetSpawnPoint( TEAM_SPECTATOR, "worldspawn" )
end
-- Utility functions
function JB:GetGuardsAllowed()
if #team.GetPlayers(TEAM_GUARD) <= 0 then
return 1;
end
return math.ceil((#team.GetPlayers(TEAM_GUARD) + #team.GetPlayers(TEAM_PRISONER)) * (tonumber(JB.Config.guardsAllowed)/100));
end
function JB:BalanceTeams()
if ( #team.GetPlayers(TEAM_GUARD) + #team.GetPlayers(TEAM_PRISONER) ) <= 1 then return end
local balls = {};
if #team.GetPlayers(TEAM_GUARD) > JB:GetGuardsAllowed() then
for i=1, (#team.GetPlayers(TEAM_GUARD) - JB:GetGuardsAllowed()) do
local ply = table.Random(team.GetPlayers(TEAM_GUARD));
if IsValid(ply) then
ply:SetTeam(TEAM_PRISONER);
ply:ChatPrint("You were moved to Prisoners to make the game more fair.");
balls[#balls+1] = ply;
end
end
end
return balls;
end
local count;
function JB:AliveGuards()
count=0;
for _,v in pairs(team.GetPlayers(TEAM_GUARD))do
if v:Alive() then
count = count+1;
end
end
return count;
end
function JB:AlivePrisoners()
count=0;
for _,v in pairs(team.GetPlayers(TEAM_PRISONER))do
if v:Alive() then
count = count+1;
end
end
return count;
end
--Useless gooks
function GM:PlayerJoinTeam() return false end
function GM:PlayerRequestTeam() return false end

View File

@@ -0,0 +1,46 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
function JB:GetWarden()
if not IsValid(JB.TRANSMITTER) then return NULL; end
local warden=JB.TRANSMITTER:GetJBWarden()
if IsValid(warden)
and warden:Team() == TEAM_GUARD
and warden:Alive() then
return warden;
end
return NULL;
end

View File

@@ -0,0 +1,48 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
// Weapon types, used to determine range.
WEAPON_NONE=0;
WEAPON_SMG=1;
WEAPON_RIFLE = 2;
WEAPON_SNIPER=3;
WEAPON_PISTOL=4;
// Quick hack to fix pickup bug.
local oldRegister = weapons.Register;
function weapons.Register(tab,class)
if tab and tab.Primary and tab.Base and tab.Base == "weapon_jb_base" then
tab.Primary.DefaultClip = tab.Primary.ClipSize or 0;
JB:DebugPrint("Registered JailBreak weapon: "..class);
end
return oldRegister(tab,class);
end

View File

@@ -0,0 +1,81 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local reregister = {};
local function reregisterWeapon(old,new)
reregister[old] = new;
end
reregisterWeapon("weapon_ak47","weapon_jb_ak47");
reregisterWeapon("weapon_aug","weapon_jb_m4a1");
reregisterWeapon("weapon_awp","weapon_jb_awp");
reregisterWeapon("weapon_deagle","weapon_jb_deagle");
reregisterWeapon("weapon_elite","weapon_jb_usp");
reregisterWeapon("weapon_famas","weapon_jb_famas");
reregisterWeapon("weapon_fiveseven","weapon_jb_fiveseven");
reregisterWeapon("weapon_g3sg1","weapon_jb_m4a1");
reregisterWeapon("weapon_galil","weapon_jb_galil");
reregisterWeapon("weapon_glock","weapon_jb_glock");
reregisterWeapon("weapon_m249","weapon_jb_scout");
reregisterWeapon("weapon_m3","weapon_jb_scout");
reregisterWeapon("weapon_m4a1","weapon_jb_m4a1");
reregisterWeapon("weapon_mac10","weapon_jb_mac10");
reregisterWeapon("weapon_mp5navy","weapon_jb_mp5navy");
reregisterWeapon("weapon_p228","weapon_jb_fiveseven");
reregisterWeapon("weapon_p90","weapon_jb_p90");
reregisterWeapon("weapon_scout","weapon_jb_scout");
reregisterWeapon("weapon_sg550","weapon_jb_scout");
reregisterWeapon("weapon_sg552","weapon_jb_sg552");
reregisterWeapon("weapon_tmp","weapon_jb_tmp");
reregisterWeapon("weapon_ump45","weapon_jb_ump");
reregisterWeapon("weapon_usp","weapon_jb_usp");
reregisterWeapon("weapon_xm1014","weapon_jb_scout");
reregisterWeapon("weapon_knife","weapon_jb_knife");
reregisterWeapon("weapon_hegrenade","weapon_jb_knife");
reregisterWeapon("weapon_smokegrenade","weapon_jb_knife");
reregisterWeapon("weapon_flashbang","weapon_jb_knife");
hook.Add("Initialize","JB.Initialize.ReplaceCSSWeapons",function()
for k,v in pairs(reregister)do
weapons.Register( {Base = v, IsDropped = true}, string.lower(k), false);
end
end);
if SERVER then
function JB:CheckWeaponReplacements(ply,entity)
if reregister[entity:GetClass()] then
ply:Give(reregister[entity:GetClass()])
return true;
end
return false;
end
end

View File

@@ -0,0 +1,71 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
-- Now with workshop support :)
resource.AddWorkshop("389805614");
--[[ If the workshop fails, the files below will be downloaded from the server :)
resource.AddFile("materials/jailbreak_excl/notify_bracket.png");
resource.AddFile("materials/jailbreak_excl/hud_restricted.png");
resource.AddFile("materials/jailbreak_excl/hud_health.png");
resource.AddFile("materials/jailbreak_excl/hud_health_bottom.png");
resource.AddFile("materials/jailbreak_excl/hud_warden_bar.png");
resource.AddFile("materials/jailbreak_excl/hud_time.png");
resource.AddFile("materials/jailbreak_excl/scoreboard_edge.png");
resource.AddFile("materials/jailbreak_excl/scoreboard_middle.png");
resource.AddFile("materials/jailbreak_excl/scoreboard_avatar.png");
resource.AddFile("materials/jailbreak_excl/weapon_selection_tile.png");
resource.AddFile("materials/jailbreak_excl/button_edge.png");
resource.AddFile("materials/jailbreak_excl/button_middle.png");
resource.AddFile("materials/jailbreak_excl/crosshair.png");
resource.AddFile("materials/jailbreak_excl/gradient.png");
resource.AddFile("materials/jailbreak_excl/lastrequest.png");
resource.AddFile("materials/jailbreak_excl/logo_guard.png")
resource.AddFile("materials/jailbreak_excl/logo_prisoner.png");
resource.AddFile("materials/jailbreak_excl/scope.png");
resource.AddFile("materials/jailbreak_excl/notify_quick_edge.png");
resource.AddFile("materials/jailbreak_excl/notify_quick_middle.png");
resource.AddFile("materials/jailbreak_excl/vgui_close.png");
resource.AddFile("materials/jailbreak_excl/vgui_close_hover.png");
resource.AddFile("materials/jailbreak_excl/guide/slide_1.png");
resource.AddFile("materials/jailbreak_excl/guide/slide_2.png");
resource.AddFile("materials/jailbreak_excl/guide/slide_3.png");
resource.AddFile("materials/jailbreak_excl/guide/slide_4.png");
resource.AddFile("materials/jailbreak_excl/pointers/pointer_background.png");
resource.AddFile("materials/jailbreak_excl/pointers/generic.png")
resource.AddFile("materials/jailbreak_excl/pointers/exclamation.png")
resource.AddFile("materials/jailbreak_excl/pointers/question.png")
resource.AddFile("materials/jailbreak_excl/pointers/line.png")
resource.AddFile("materials/jailbreak_excl/pointers/cross.png")]]

View File

@@ -0,0 +1,50 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
hook.Add( "OnEntityCreated", "JB.OnEntityCreated.InvalidateDefaultWeapons", function( entity )
if string.lower( string.Left( entity:GetClass(), 6 ) ) == "weapon" or entity:IsWeapon() then
timer.Simple( 0, function()
if not IsValid( entity ) then return end
entity.IsDropped = true;
entity.BeingPickedUp = false;
local object = entity:GetPhysicsObject();
if object and IsValid( object ) then
object:EnableGravity( true );
object:EnableMotion( true );
object:Wake();
end
end)
end
end)

247
gamemode/core/sv_logs.lua Normal file
View File

@@ -0,0 +1,247 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local DamageTypes = {}
DamageTypes[DMG_CRUSH] = "crush damage";
DamageTypes[DMG_BULLET] = "bullet damage";
DamageTypes[DMG_BURN] = "fire damage";
DamageTypes[DMG_VEHICLE] = "vehicular damage";
DamageTypes[DMG_FALL] = "fall damage";
DamageTypes[DMG_BLAST] = "explosion damage";
DamageTypes[DMG_DROWN] = "drown damage";
DamageTypes[DMG_POISON] = "poison damage";
local function convertTime(t)
if t < 0 then
t = 0;
end
local sec = tostring( math.Round(t - math.floor(t/60)*60));
if string.len(sec) < 2 then
sec = "0"..sec;
end
return (tostring( math.floor(t/60) )..":"..sec )
end
function JB:DamageLog_AddEntityTakeDamage( p,dmg )
if ( IsValid(p) and p:IsPlayer() and dmg:GetDamage() ~= 0) then
if not JB.ThisRound.Logs then
JB.ThisRound.Logs = {};
end
local message={};
local subject=p;
table.insert(message,team.GetColor(p:Team()));
table.insert(message,p:Nick());
table.insert(message,JB.Color.white);
table.insert(message," ("..p:SteamID()..")")
local damagetype="damage"
for k,v in pairs(DamageTypes)do
if dmg:IsDamageType(k) then
damagetype=v;
break;
end
end
table.insert(message," has taken "..tostring(math.ceil(dmg:GetDamage())).." "..damagetype);
local att = dmg:GetAttacker();
if IsValid(att) and att:IsPlayer() then
table.insert(message," from ");
table.insert(message,team.GetColor(att:Team()));
table.insert(message,att:Nick());
table.insert(message,JB.Color.white);
table.insert(message," ("..att:SteamID()..")")
subject=att;
end
local inf = dmg:GetInflictor();
if IsValid(inf) and not (inf.IsPlayer and inf:IsPlayer()) then
table.insert(message," by a '"..inf:GetClass().."' entity");
end
table.insert(message,JB.Color.white);
table.insert(message,".");
local timerText = (state == STATE_IDLE and "WAITING" or state == STATE_ENDED and "ENDED" or state == STATE_MAPVOTE and "MAPVOTE" or convertTime(60*(state == STATE_LASTREQUEST and 3 or 10) - (CurTime() - JB.RoundStartTime)) );
local log={
kind="DAMAGE",
time=timerText,
message=message,
subject=subject
}
table.insert(JB.ThisRound.Logs,log)
end
end
function JB:DamageLog_AddPlayerDeath(p, weapon, killer)
if not JB.ThisRound.Logs then
JB.ThisRound.Logs = {};
end
local message={};
local subject=p;
table.insert(message,team.GetColor(p:Team()));
table.insert(message,p:Nick());
table.insert(message,JB.Color.white);
table.insert(message," ("..p:SteamID()..")")
if IsValid(killer) and killer:IsPlayer() then
if killer == p then
table.insert(message," has commited suicide")
else
table.insert(message," was killed by ")
table.insert(message,team.GetColor(killer:Team()));
table.insert(message,killer:Nick());
table.insert(message,JB.Color.white);
table.insert(message," ("..killer:SteamID()..")")
subject=killer;
end
else
table.insert(message," has died")
end
table.insert(message,JB.Color.white);
table.insert(message,".");
local timerText = (state == STATE_IDLE and "WAITING" or state == STATE_ENDED and "ENDED" or state == STATE_MAPVOTE and "MAPVOTE" or convertTime(60*(state == STATE_LASTREQUEST and 3 or 10) - (CurTime() - JB.RoundStartTime)) );
local log={
kind="KILL",
time=timerText,
message=message,
subject=subject
}
table.insert(JB.ThisRound.Logs,log)
end
function JB:DamageLog_AddPlayerPickup( p,class )
if not JB.ThisRound.Logs then
JB.ThisRound.Logs = {};
end
local message={};
table.insert(message,team.GetColor(p:Team()));
table.insert(message,p:Nick());
table.insert(message,JB.Color.white);
table.insert(message," ("..p:SteamID()..") has picked up a '"..class.."'.")
local timerText = (state == STATE_IDLE and "WAITING" or state == STATE_ENDED and "ENDED" or state == STATE_MAPVOTE and "MAPVOTE" or convertTime(60*(state == STATE_LASTREQUEST and 3 or 10) - (CurTime() - JB.RoundStartTime)) );
local log={
kind="PICKUP",
time=timerText,
message=message,
subject=p
}
table.insert(JB.ThisRound.Logs,log)
end
function JB:DamageLog_AddPlayerDrop( p,class )
if not JB.ThisRound.Logs then
JB.ThisRound.Logs = {};
end
local message={};
table.insert(message,team.GetColor(p:Team()));
table.insert(message,p:Nick());
table.insert(message,JB.Color.white);
table.insert(message," ("..p:SteamID()..") has dropped a '"..class.."'.")
local timerText = (state == STATE_IDLE and "WAITING" or state == STATE_ENDED and "ENDED" or state == STATE_MAPVOTE and "MAPVOTE" or convertTime(60*(state == STATE_LASTREQUEST and 3 or 10) - (CurTime() - JB.RoundStartTime)) );
local log={
kind="DROP",
time=timerText,
message=message,
subject=p
}
table.insert(JB.ThisRound.Logs,log)
end
util.AddNetworkString("JB.GetLogs");
local getLogs=function(p,cmd,a)
if p.nextLogs and p.nextLogs > CurTime() then return end
if (p:Alive() and not p:IsAdmin()) then
p:PrintMessage(HUD_PRINTCONSOLE,"You can't receive logs while you're alive.");
p:SendQuickNotification("You can't view logs while you're alive!");
return;
end
p.nextLogs = CurTime()+1;
local logs={};
if cmd == "jb_logs_get_damage" then
for k,v in ipairs(JB.ThisRound.Logs or {})do
if v.kind =="DAMAGE" then
table.insert(logs,v);
end
end
elseif cmd == "jb_logs_get_kills" then
for k,v in ipairs(JB.ThisRound.Logs or {})do
if v.kind == "KILL" then
table.insert(logs,v);
end
end
elseif cmd == "jb_logs_get_damagekills" then
for k,v in ipairs(JB.ThisRound.Logs or {})do
if v.kind == "KILL" or v.kind == "DAMAGE" then
table.insert(logs,v);
end
end
else
logs=JB.ThisRound.Logs;
end
net.Start("JB.GetLogs");
net.WriteTable(logs or {});
net.WriteBit(true);
net.Send(p);
end
concommand.Add("jb_logs_get",getLogs);
concommand.Add("jb_logs_get_kills",getLogs);
concommand.Add("jb_logs_get_damage",getLogs);
concommand.Add("jb_logs_get_damagekills",getLogs);

302
gamemode/core/sv_player.lua Normal file
View File

@@ -0,0 +1,302 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
JB.Gamemode.PlayerInitialSpawn = function(gm,ply)
ply:SetTeam(TEAM_PRISONER) -- always spawn as prisoner;
JB:DebugPrint(ply:Nick().." has successfully joined the server.");
end;
JB.Gamemode.PlayerSpawn = function(gm,ply)
if (ply:Team() ~= TEAM_PRISONER and ply:Team() ~= TEAM_GUARD) or
(not ply._jb_forceRespawn and (JB.State == STATE_LASTREQUEST or JB.State == STATE_PLAYING or (JB.State ~= STATE_IDLE and CurTime() - JB.RoundStartTime > 10)))
then
ply:KillSilent();
gm:PlayerSpawnAsSpectator(ply);
return;
end
ply._jb_forceRespawn=false
ply:StripWeapons();
ply:StripAmmo();
gm.BaseClass.PlayerSpawn(gm,ply);
ply.originalRunSpeed = ply:GetRunSpeed();
end;
JB.Gamemode.PlayerDeathThink = function( gm,ply )
if ( ply:KeyPressed( IN_ATTACK ) || ply:KeyPressed( IN_ATTACK2 ) || ply:KeyPressed( IN_JUMP ) ) and ply:GetObserverMode() == OBS_MODE_NONE then
if JB.State == STATE_IDLE then
ply:Spawn();
else
JB.Gamemode:PlayerSpawnAsSpectator(ply)
end
end
end
JB.Gamemode.PlayerCanPickupWeapon = function( gm, ply, entity )
if not ply:Alive() then return false end
if entity:GetClass() == "weapon_physgun" then
return ply:IsSuperAdmin()
end
if not ply:CanPickupWeapon(entity) then return false end
if entity.IsDropped and (not entity.BeingPickedUp or entity.BeingPickedUp ~= ply) then
return false;
end
if JB:CheckWeaponReplacements(ply,entity) then entity:Remove(); return false end
return true
end
JB.Gamemode.PlayerShouldTakeDamage = function(gm,a,b)
if IsValid(a) and IsValid(b) and a:IsPlayer() and b:IsPlayer() and a:Team() == b:Team() and (JB.State == STATE_SETUP or JB.State == STATE_PLAYING or JB.State == STATE_LASTREQUEST) and (not IsValid(JB.TRANSMITTER) or a:Team() ~= TEAM_PRISONER or not JB.TRANSMITTER:GetJBWarden_PVPDamage()) then
return false
end
return true;
end
JB.Gamemode.IsSpawnpointSuitable = function()
return true
end
JB.Gamemode.PlayerDeath = function(gm, victim, weapon, killer)
victim:StripWeapons()
victim:SendNotification("You are muted until the round ends")
if victim.GetWarden and IsValid(JB.TRANSMITTER) and JB.TRANSMITTER:GetJBWarden() == victim:GetWarden() then
JB:BroadcastNotification("The warden has died")
timer.Simple(.5,function()
for k,v in pairs(team.GetPlayers(TEAM_GUARD))do
if v:Alive() and v ~= victim then
JB:BroadcastNotification("Prisoners get freeday");
break;
end
end
end);
end
if IsValid(killer) and killer.IsPlayer and killer:IsPlayer()
and killer:Team() == TEAM_PRISONER and victim:Team() == TEAM_GUARD
and killer.AddRebelStatus
and not killer:GetRebel()
and tonumber(JB.Config.rebelSensitivity) >= 1
and JB.State ~= STATE_LASTREQUEST then
JB:DebugPrint(killer:Nick().. " is now a rebel!!");
killer:AddRebelStatus();
end
if IsValid(killer) and killer.IsPlayer and killer:IsPlayer() and (killer:Team() == TEAM_GUARD or killer:Team() == TEAM_PRISONER) and killer:Alive() then
JB:BroadcastQuickNotification(victim:Nick().." was killed by "..killer:Nick());
else
JB:BroadcastQuickNotification(victim:Nick().." has died");
end
if JB.State == STATE_PLAYING and victim:Team() == TEAM_GUARD and JB:AliveGuards() == 2 and JB:AlivePrisoners() > 3 and not IsValid(JB:GetWarden()) and not JB.ThisRound.notifiedLG and tobool(JB.Config.notifyLG) then
JB.ThisRound.notifiedLG = true;
JB:BroadcastNotification("Last guard kills all");
end
if JB.State == STATE_PLAYING and victim:Team() == TEAM_PRISONER and JB:AlivePrisoners() == 2 and not JB.ThisRound.notifiedLR then
JB.ThisRound.notifiedLR = true;
JB:BroadcastNotification("The last prisoner now select a last request from the menu (F4).");
JB:BroadcastNotification("Custom last requests may only affect the current round!");
end
if JB.State == STATE_LASTREQUEST then
local guard,prisoner = unpack(JB.LastRequestPlayers);
if IsValid(guard) and guard == victim then
JB.LastRequest = "0";
end
end
JB:DamageLog_AddPlayerDeath(victim, weapon, killer)
end
JB.Gamemode.ScalePlayerDamage = function( gm, ply, hitgroup, dmginfo )
if ( hitgroup == HITGROUP_HEAD ) then
dmginfo:ScaleDamage( 3 )
elseif ( hitgroup == HITGROUP_LEFTARM or hitgroup == HITGROUP_RIGHTARM ) then
dmginfo:ScaleDamage( 0.8 )
elseif ( hitgroup == HITGROUP_LEFTLEG or hitgroup == HITGROUP_RIGHTLEG ) then
dmginfo:ScaleDamage( 0.4 )
end
end
JB.Gamemode.GetFallDamage = function() return 0 end
local fallsounds = {
Sound("player/damage1.wav"),
Sound("player/damage2.wav"),
Sound("player/damage3.wav")
};
JB.Gamemode.OnPlayerHitGround = function(gm,ply, in_water, on_floater, speed)
if in_water or speed < 460 or not IsValid(ply) then return end
local damage = math.pow(0.05 * (speed - 420), 1.30)
if on_floater then damage = damage / 2 end
if math.floor(damage) > 0 then
local dmg = DamageInfo()
dmg:SetDamageType(DMG_FALL)
dmg:SetAttacker(game.GetWorld())
dmg:SetInflictor(game.GetWorld())
dmg:SetDamageForce(Vector(0,0,1))
dmg:SetDamage(damage)
ply:TakeDamageInfo(dmg)
if damage > 5 then
sound.Play(table.Random(fallsounds), ply:GetShootPos(), 55 + math.Clamp(damage, 0, 50), 100)
end
end
end
JB.Gamemode.PlayerCanHearPlayersVoice = function( gm, listener, talker )
if (not talker:Alive() )
or (talker:Team() == TEAM_PRISONER and ((CurTime() - JB.RoundStartTime) < 30)) then return false,false; end
if(talker.GetWarden and talker:GetWarden()) then
return true,false;
end
return true,false;
end
JB.Gamemode.EntityTakeDamage = function ( gm, ent, dmg )
JB:DamageLog_AddEntityTakeDamage( ent,dmg )
end
hook.Add("PlayerDisconnected","JB.PlayerDisconnected.CheckDisconnect",function(p)
if JB.State == STATE_LASTREQUEST then
local guard,prisoner = unpack(JB.LastRequestPlayers);
if IsValid(guard) and guard == p then
JB.LastRequest = "0";
end
end
end)
hook.Add("DoPlayerDeath", "JB.DoPlayerDeath.DropWeapon", function(ply)
if IsValid(ply) and IsValid(ply:GetActiveWeapon()) and ply:GetActiveWeapon():GetClass() ~= "jb_fists" then
local wep = ply:GetActiveWeapon();
wep.IsDropped = true;
wep.BeingPickedUp = false;
ply:DropWeapon(wep)
end
end)
hook.Add("EntityTakeDamage", "JB.EntityTakeDamage.WeaponScale", function(ent, d)
local att = d:GetInflictor()
if att:IsPlayer() then
local wep = att:GetActiveWeapon()
if IsValid(wep) and not wep.NoDistance and wep.EffectiveRange then
local dist = ent:GetPos():Distance(att:GetPos())
if dist >= wep.EffectiveRange * 0.5 then
dist = dist - wep.EffectiveRange * 0.5
local mul = math.Clamp(dist / wep.EffectiveRange, 0, 1)
d:ScaleDamage(1 - wep.DamageFallOff * mul)
end
end
end
end)
hook.Add("PlayerHurt", "JB.PlayerHurt.MakeRebel", function(victim, attacker)
if !IsValid(attacker) or !IsValid(victim) or !attacker:IsPlayer() or !victim:IsPlayer() or tonumber(JB.Config.rebelSensitivity) ~= 2 then return end
if attacker:Team() == TEAM_PRISONER and victim:Team() == TEAM_GUARD and attacker.SetRebel
and not attacker:GetRebel()
and JB.State ~= STATE_LASTREQUEST then
attacker:AddRebelStatus();
end
end)
local painSounds = {
"vo/npc/male01/ow01.wav",
"vo/npc/male01/ow02.wav",
"vo/npc/male01/pain01.wav",
"vo/npc/male01/pain02.wav",
"vo/npc/male01/pain03.wav",
"vo/npc/male01/pain04.wav",
"vo/npc/male01/pain05.wav",
"vo/npc/male01/pain06.wav",
"vo/npc/male01/pain07.wav",
"vo/npc/male01/pain08.wav",
"vo/npc/male01/pain09.wav"
}
hook.Add("EntityTakeDamage", "JB.EntityTakeDamage.SayOuch", function(victim)
if IsValid(victim) and victim:IsPlayer() and math.random(1,6) == 1 then
victim:EmitSound(painSounds[math.random(#painSounds)],math.random(100,140),math.random(90,110))
end
end)
concommand.Remove("changeteam");
function JB:BroadcastNotification(text,omit)
net.Start("JB.SendNotification");
net.WriteString(text);
if omit then
net.SendOmit(omit);
return;
end
net.Broadcast();
end
function JB:BroadcastQuickNotification(text)
net.Start("JB.SendQuickNotification");
net.WriteString(text);
net.Broadcast();
end
function JB.Gamemode:AllowPlayerPickup( ply, object )
return (ply:Alive() and (JB.State == STATE_PLAYING or JB.State == STATE_SETUP or JB.State == STATE_LASTREQUEST) and IsValid(JB.TRANSMITTER) and JB.TRANSMITTER:GetJBWarden_ItemPickup());
end
function JB.Gamemode:PlayerUse( ply, ent )
if not ply:Alive() or not (ply:Team() == TEAM_GUARD or ply:Team() == TEAM_PRISONER) then
return false
end
return true
end
JB.Gamemode.ShowHelp = function() end
JB.Gamemode.ShowTeam = function() end
JB.Gamemode.ShowSpare1 = function() end
JB.Gamemode.ShowSpare2 = function() end

View File

@@ -0,0 +1,210 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local undroppableWeapons = {"weapon_physcannon", "weapon_physgun", "gmod_camera", "gmod_tool", "weapon_jb_fists"}
local drop = function( ply, cmd, args )
if (table.HasValue(JB.LastRequestPlayers,ply) and JB.LastRequestTypes[JB.LastRequest] and not JB.LastRequestTypes[JB.LastRequest]:GetCanDropWeapons() ) then return end
JB:DebugPrint(ply:Nick().." dropped his/her weapon");
local weapon = ply:GetActiveWeapon()
for k, v in pairs(undroppableWeapons) do
if IsValid(weapon) then
if v == weapon:GetClass() then return false end
end
end
if IsValid(weapon) then
JB:DamageLog_AddPlayerDrop( ply,weapon:GetClass() )
weapon.IsDropped = true;
weapon.BeingPickedUp = false;
ply:DropWeapon(weapon)
end
end
concommand.Add("jb_dropweapon", drop)
JB.Util.addChatCommand("drop",drop);
local pickup = function(p)
local e = p:GetEyeTrace().Entity
if (table.HasValue(JB.LastRequestPlayers,p) and JB.LastRequestTypes[JB.LastRequest] and not JB.LastRequestTypes[JB.LastRequest]:GetCanPickupWeapons() ) then
return;
end
if IsValid(e) and p:Alive() and p:CanPickupWeapon( e ) then
e.BeingPickedUp = p;
JB:DamageLog_AddPlayerPickup( p,e:GetClass() )
end
end
concommand.Add("jb_pickup",pickup)
JB.Util.addChatCommand("pickup",pickup);
local function teamSwitch(p,cmd)
if !IsValid(p) then return end
if cmd == "jb_team_select_guard" and JB:GetGuardsAllowed() > #team.GetPlayers(TEAM_GUARD) and p:Team() ~= TEAM_GUARD then
p:SetTeam(TEAM_GUARD);
p:KillSilent();
p:SendNotification("Switched to guards");
hook.Call("JailBreakPlayerSwitchTeam",JB.Gamemode,p,p:Team());
p:SetFrags(0);
p:SetDeaths(0);
elseif cmd == "jb_team_select_prisoner" and p:Team() ~= TEAM_PRISONER then
p:SetTeam(TEAM_PRISONER);
p:KillSilent();
p:SendNotification("Switched to prisoners");
hook.Call("JailBreakPlayerSwitchTeam",JB.Gamemode,p,p:Team());
p:SetFrags(0);
p:SetDeaths(0);
elseif cmd == "jb_team_select_spectator" and p:Team() ~= TEAM_SPECTATOR then
p:SetTeam(TEAM_SPECTATOR);
p:Spawn();
p:SendNotification("Switched to spectator mode");
hook.Call("JailBreakPlayerSwitchTeam",JB.Gamemode,p,p:Team());
p:SetFrags(0);
p:SetDeaths(0);
end
end
concommand.Add("jb_team_select_prisoner",teamSwitch);
concommand.Add("jb_team_select_guard",teamSwitch);
concommand.Add("jb_team_select_spectator",teamSwitch);
JB.Util.addChatCommand("guard",function(p)
p:ConCommand("jb_team_select_guard");
end);
JB.Util.addChatCommand("prisoner",function(p)
p:ConCommand("jb_team_select_prisoner");
end);
JB.Util.addChatCommand("spectator",function(p)
p:ConCommand("jb_team_select_spectator");
end);
local teamswap = function(p)
if p:Team() == TEAM_PRISONER then
p:ConCommand("jb_team_select_guard");
else
p:ConCommand("jb_team_select_prisoner");
end
end
JB.Util.addChatCommand("teamswap",teamswap);
JB.Util.addChatCommand("swap",teamswap);
JB.Util.addChatCommand("swapteam",teamswap);
concommand.Add("jb_admin_swap",function(p,c,a)
if not IsValid(p) or not p:IsAdmin() then return end
local steamid = a[1];
if not steamid then return end
for k,v in ipairs(player.GetAll())do
if v:SteamID() == steamid then
if v:Team() == TEAM_GUARD then
v:SetTeam(TEAM_PRISONER);
v:KillSilent();
v:SendNotification("Forced to prisoners");
hook.Call("JailBreakPlayerSwitchTeam",JB.Gamemode,p,p:Team());
else
v:SetTeam(TEAM_GUARD);
v:KillSilent();
v:SendNotification("Forced to guards");
hook.Call("JailBreakPlayerSwitchTeam",JB.Gamemode,p,p:Team());
end
for k,it in ipairs(player.GetAll())do
it:ChatPrint(p:Nick().." has force swapped "..v:Nick()..".");
end
return;
end
end
p:ChatPrint("User not found! " ..steamid)
end)
concommand.Add("jb_admin_swap_spectator",function(p,c,a)
if not IsValid(p) or not p:IsAdmin() then return end
local steamid = a[1];
if not steamid then return end
for k,v in ipairs(player.GetAll())do
if v:SteamID() == steamid then
v:SetTeam(TEAM_SPECTATOR)
v:Kill()
for k,it in ipairs(player.GetAll())do
it:ChatPrint(p:Nick().." has made "..v:Nick().." a spectator.");
end
return;
end
end
p:ChatPrint("User not found! "..steamid)
end)
concommand.Add("jb_admin_revive",function(p,c,a)
if not IsValid(p) or not p:IsAdmin() then return end
local steamid = a[1];
if not steamid then return end
for k,v in ipairs(player.GetAll())do
if v:SteamID() == steamid then
v._jb_forceRespawn=true
v:Spawn()
for k,it in ipairs(player.GetAll())do
it:ChatPrint(p:Nick().." has revived "..v:Nick()..".")
end
return;
end
end
p:ChatPrint("User not found! "..steamid)
end)

View File

@@ -0,0 +1,113 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local pmeta = FindMetaTable("Player")
--[[ PLAYER CLASS SETTING ]]
local oldSetTeam=pmeta.SetTeam;
function pmeta:SetTeam(tm)
player_manager.SetPlayerClass( self, tm == TEAM_GUARD and "player_guard" or tm == TEAM_PRISONER and "player_prisoner" or "player_spectator");
oldSetTeam(self,tm);
end
--[[ PRISONER STATUS ]]
function pmeta:AddRebelStatus()
if self:Team() ~= TEAM_PRISONER or not self:Alive() then
return
end
self:SetRebel(true);
JB:BroadcastNotification(self:Nick().." is rebelling!");
self:SetPlayerColor(Vector(1,0,0));
self:SetWeaponColor(Vector(1,0,0));
end
function pmeta:RemoveRebelStatus()
if not self.SetRebel then
return
end
self:SetRebel(false);
self:SetPlayerColor(Vector(.9,.9,.9));
self:SetWeaponColor(Vector(.9,.9,.9));
end
--[[ WARDEN STATUS ]]
function pmeta:AddWardenStatus()
if self:Team() ~= TEAM_GUARD or not self:Alive() or not IsValid(JB.TRANSMITTER) then
return
end
self:SetModel("models/player/barney.mdl")
self:SetArmor(100)
JB.TRANSMITTER:SetJBWarden(self);
end
function pmeta:RemoveWardenStatus()
if not self:Alive() and IsValid(JB.TRANSMITTER) then return end
self:SetModel("models/player/police.mdl")
JB.TRANSMITTER:SetJBWarden(NULL);
end
function pmeta:SetupHands( ply )
if IsValid(ply) and ply ~= self then return end // we don't need in-eye spectator.
local oldhands = self:GetHands()
if ( IsValid( oldhands ) ) then
oldhands:Remove()
end
local hands = ents.Create( "gmod_hands" )
if ( IsValid( hands ) ) then
hands:DoSetup( self, ply )
hands:Spawn()
end
end
--[[ NOTIFICATIONS ]]
util.AddNetworkString("JB.SendNotification");
function pmeta:SendNotification(text)
net.Start("JB.SendNotification");
net.WriteString(text);
net.Send(self);
end
util.AddNetworkString("JB.SendQuickNotification");
function pmeta:SendQuickNotification(msg)
net.Start("JB.SendQuickNotification");
net.WriteString(msg);
net.Send(self);
end;

View File

@@ -0,0 +1,133 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
JB.Gamemode.PlayerSpawnAsSpectator = function(gm,ply)
ply:StripWeapons();
if ( ply:Team() == TEAM_UNASSIGNED ) then
ply:Spectate( OBS_MODE_FIXED )
return
end
local canspec = {};
for _,v in ipairs(team.GetPlayers(TEAM_GUARD))do
if IsValid(v) and v:Alive() then
table.insert(canspec,v);
end
end
for _,v in ipairs(team.GetPlayers(TEAM_PRISONER))do
if IsValid(v) and v:Alive() then
table.insert(canspec,v);
end
end
local target=(ply.spec and canspec[ply.spec]) or canspec[1];
if target then
ply:SpectateEntity(target);
ply:Spectate( OBS_MODE_CHASE );
else
ply:Spectate( OBS_MODE_ROAMING );
end
end;
local CTRL_NEXT = bit.bor(IN_ATTACK,IN_MOVELEFT,IN_FORWARD);
local CTRL_PREV = bit.bor(IN_ATTACK2,IN_MOVERIGHT,IN_BACK);
local CTRL_CHANGE = bit.bor(IN_DUCK);
hook.Add( "KeyPress", "JB.KeyPress.HandleSpectateControls", function(p,key)
if p:GetObserverMode() ~= OBS_MODE_NONE then
local doNext = tobool(bit.band(key,CTRL_NEXT));
local doPrev = tobool(bit.band(key,CTRL_PREV));
local doChange=tobool(bit.band(key,CTRL_CHANGE));
if doNext or doPrev or doChange then
JB:DebugPrint(p:Nick().. " is using spectator controls. "..tostring(doNext).." "..tostring(doPrev).." "..tostring(doChange));
if not p.spec then p.spec = 1 end
local canspec = {};
for _,v in ipairs(team.GetPlayers(TEAM_GUARD))do
if IsValid(v) and v:Alive() then
table.insert(canspec,v);
end
end
for _,v in ipairs(team.GetPlayers(TEAM_PRISONER))do
if IsValid(v) and v:Alive() then
table.insert(canspec,v);
end
end
local target = (canspec[p.spec] or canspec[1]);
if doChange and p:GetObserverMode() == OBS_MODE_CHASE then
p:Spectate(OBS_MODE_ROAMING);
return;
elseif doChange and p:GetObserverMode() == OBS_MODE_ROAMING and target then
p:Spectate(OBS_MODE_CHASE);
p:SpectateEntity(target)
return;
elseif doChange then
return
end
if p:GetObserverMode() == OBS_MODE_CHASE then
local doNext=tobool(bit.band(key,CTRL_NEXT));
local doPrev=tobool(bit.band(key,CTRL_PREV));
if not canspec or not canspec[1] then
JB.DebugPrint("Nobody alive to spectate.")
return
end
local old=p.spec;
if doNext then
p.spec = p.spec+1;
if p.spec > #canspec then
p.spec = 0;
end
elseif doPrev then
p.spec = p.spec-1;
if p.spec < 1 then
p.spec = #canspec;
end
end
target = canspec[p.spec];
if IsValid(target) then
p:SpectateEntity(target);
end
end
end
end
end)

View File

@@ -0,0 +1,50 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
function JB:CanLastRequest()
return JB:AliveGuards() >= 1 and JB:AlivePrisoners() == 1 and (JB.State == STATE_PLAYING or (JB.State == STATE_LASTREQUEST and not JB.ValidLR(JB.LastRequestTypes[JB.LastRequest])) or JB.State == STATE_SETUP);
end
concommand.Add("jb_lastrequest_start",function(p,c,a)
if not JB:CanLastRequest() or p:Team() ~= TEAM_PRISONER or not p:Alive() or not a or not a[1] or not a[2] then return end
local lr = a[1];
if not JB.ValidLR(JB.LastRequestTypes[lr]) then return end
local guard = Entity(tonumber(a[2]));
if not IsValid(guard) or not guard.IsPlayer or not guard:IsPlayer() or guard:Team() ~= TEAM_GUARD or not guard:Alive() then return end
JB:DebugPrint("Setting up LR for ",p:Nick())
JB.LastRequest = {type=lr,guard=guard,prisoner=p};
end);

145
gamemode/core/sv_warden.lua Normal file
View File

@@ -0,0 +1,145 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local function claimWarden(p,c,a)
if not IsValid(p) or p:Team() ~= TEAM_GUARD or JB.State ~= STATE_SETUP or IsValid(JB:GetWarden()) then return end
if p.wardenRounds and p.wardenRounds >= tonumber(JB.Config.maxWardenRounds) and ( CurTime() - JB.RoundStartTime ) < 20 then
p:SendQuickNotification("You have to give others a chance to claim warden.");
return;
end
p:AddWardenStatus();
if not p.wardenRounds then
p.wardenRounds = 1;
else
p.wardenRounds = p.wardenRounds + 1;
end
for _,v in pairs(team.GetPlayers(TEAM_GUARD))do
if IsValid(v) and v ~= p and p.wardenRounds then
p.wardenRounds = 0;
end
end
hook.Call("JailBreakClaimWarden",JB.Gamemode,p,p.wardenRounds);
end
JB.Util.addChatCommand("warden",claimWarden)
concommand.Add("jb_claim_warden",claimWarden);
concommand.Add("jb_warden_changecontrol",function(p,c,a)
if not IsValid(p) or not p.GetWarden or not p:GetWarden() or not IsValid(JB.TRANSMITTER) then return end
local opt = a[1];
local val = a[2];
if not opt or not val then
return
elseif opt == "PVP" then
JB.TRANSMITTER:SetJBWarden_PVPDamage(tobool(val));
JB:BroadcastNotification("Friendly fire is now "..(tobool(val) and "enabled" or "disabled"));
elseif opt == "Pickup" then
JB.TRANSMITTER:SetJBWarden_ItemPickup(tobool(val));
JB:BroadcastNotification("Item pickup is now "..(tobool(val) and "enabled" or "disabled"));
end
hook.Call("JailBreakWardenControlChanged",JB.Gamemode,p,opt,val);
end);
local function spawnProp(p,typ,model)
local spawned = 0;
for k,v in pairs(ents.GetAll())do
if v and IsValid(v) and v.wardenSpawned then
spawned = spawned + 1;
end
end
if spawned > tonumber(JB.Config.maxWardenItems) then
p:SendQuickNotification("You can not spawn over "..tostring(JB.Config.maxWardenItems).." items.");
return
end
local prop = ents.Create(typ);
prop:SetAngles(p:GetAngles());
prop:SetPos(p:EyePos() + p:GetAngles():Forward() * 60);
if model then
prop:SetModel(model)
end
prop:Spawn();
prop:Activate();
prop.wardenSpawned = true;
hook.Call("JailBreakWardenSpawnProp",JB.Gamemode,p,typ,model);
end
concommand.Add("jb_warden_spawn",function(p,c,a)
if not IsValid(p) or not p.GetWarden or not p:GetWarden() or not tobool(JB.Config.wardenControl) then return end
local opt = a[1];
if not opt then
return
elseif opt == "Crate" then
spawnProp(p,"prop_physics_multiplayer","models/props_junk/wood_crate001a.mdl")
elseif opt == "Blockade" then
spawnProp(p,"prop_physics_multiplayer","models/props_trainstation/TrackSign02.mdl")
elseif opt == "AmmoBox" then
spawnProp(p,"jb_ammobox")
end
end);
local pointerRemove = -1;
concommand.Add("jb_warden_placepointer",function(p,c,a)
if not IsValid(p) or not p.GetWarden or not p:GetWarden() then return end
local typ = tostring(a[1]);
if not typ then return end;
local pos = p:GetEyeTrace().HitPos;
JB:DebugPrint("Warden "..p:Nick().." has placed a marker at "..tostring(pos));
JB:BroadcastQuickNotification("The warden has placed a marker");
pointerRemove = CurTime()+120;
JB.TRANSMITTER:SetJBWarden_PointerPos(pos);
JB.TRANSMITTER:SetJBWarden_PointerType(typ);
hook.Call("JailBreakWardenPlacePointer",JB.Gamemode,p,typ,pos);
end);
hook.Add("Think","JB.Think.PointerTimeout",function()
if CurTime() > pointerRemove and pointerRemove ~= -1 then
JB.TRANSMITTER:SetJBWarden_PointerType("0");
end
end);

153
gamemode/core/sv_zones.lua Normal file
View File

@@ -0,0 +1,153 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
JB.Zones={}
hook.Add("InitPostEntity","JB.InitPostEntity.LoadZones",function()
if not file.Exists("jailbreak","DATA") then
file.CreateDir("jailbreak")
end
if not file.Exists("jailbreak/zones","DATA") then
file.CreateDir("jailbreak/zones")
end
if file.Exists("jailbreak/zones/"..game.GetMap()..".txt","DATA") then
local data=util.JSONToTable(file.Read("jailbreak/zones/"..game.GetMap()..".txt","DATA"));
if not data or not data[1] then return end
JB.Zones=data
for k,v in pairs(data) do
local ent=ents.Create("jb_zone")
ent:SetPos(Vector(0,0,0))
ent:Spawn()
ent.handle_min:SetPos(Vector(v.startpos))
ent.handle_max:SetPos(Vector(v.endpos))
ent._zoneid=k;
end
end
end)
function JB.SaveZone(startpos,endpos,zoneid)
if not file.Exists("jailbreak","DATA") then
file.CreateDir("jailbreak")
end
if not file.Exists("jailbreak/zones","DATA") then
file.CreateDir("jailbreak/zones")
end
if not zoneid then
zoneid = (#JB.Zones) + 1
end
JB.Zones[zoneid] = {}
JB.Zones[zoneid]["startpos"]=startpos
JB.Zones[zoneid]["endpos"]=endpos
file.Write("jailbreak/zones/"..(game.GetMap())..".txt",util.TableToJSON(JB.Zones))
print(startpos,endpos)
PrintTable(JB.Zones)
return zoneid
end
concommand.Add("jb_admin_configmode",function(ply)
if not ply:IsSuperAdmin() then return end
ply:Give("weapon_physgun")
ply:SelectWeapon("weapon_physgun")
ply:ChatPrint("You have entered map configuration mode.")
end)
local waitSave=false;
function JB.Gamemode:OnPhysgunFreeze(weapon, physobj, ent, ply)
if not ply:IsSuperAdmin() or waitSave then return false end
if not IsValid(ent) or ent:GetClass() ~= "jb_zone_handle" then return false end
ent.isPositioned=true;
local finishEnt=ent:GetZoneEntity()
if IsValid(finishEnt.handle_min) and IsValid(finishEnt.handle_max) and finishEnt.handle_min.isPositioned and finishEnt.handle_max.isPositioned then
ent._zoneid=JB.SaveZone(tostring(finishEnt.handle_min:GetPos()),tostring(finishEnt.handle_max:GetPos()),ent._zoneid)
ply:ChatPrint("Zone saved.")
end
return true
end
function JB.Gamemode:OnPhysgunReload(physgun, ply)
if not ply:IsSuperAdmin() then return false end
local ent=ents.Create("jb_zone")
ent:Spawn()
local ps=ply:GetEyeTrace().HitPos
ent.handle_min:SetPos(ps+Vector(-.1,-.1,-.1))
ent.handle_max:SetPos(ps+Vector(.1,.1,.1))
ent:Think()
ply:ChatPrint("Guard-only zone designator spawned. Freeze both handles (green circles) to save guard-only zone.")
return true
end
function JB.Gamemode:PhysgunPickup(ply,ent)
return ply:IsSuperAdmin() and ent:GetClass() == "jb_zone_handle"
end
local oldCleanup=game.CleanUpMap
function game.CleanUpMap(dontsend,filters)
if not dontsend then
dontsend=false
end
if not filters then
filters={}
end
table.insert(filters,"jb_zone_handle")
table.insert(filters,"jb_zone")
return oldCleanup(dontsend,filters)
end

37
gamemode/init.lua Normal file
View File

@@ -0,0 +1,37 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
include "sh_init.lua";
AddCSLuaFile "sh_init.lua";

View File

@@ -0,0 +1,54 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local LR = JB.CLASS_LR();
LR:SetName("Airborne Battle");
LR:SetDescription("The guard and the prisoner both get a Famas rifle and knife, but they can only fire if they are in the air, so they will have to either jump from fall in order to fire.");
LR:SetStartCallback(function(prisoner,guard)
for _,ply in ipairs{prisoner,guard} do
ply:StripWeapons();
ply:Give("weapon_jb_famas");
ply:Give("weapon_jb_knife");
ply:GiveAmmo(899,"SMG1");
ply:SetHealth(100);
ply:SetArmor(0);
end
end)
LR:SetIcon(Material("icon16/flag_green.png"))
local this = LR();
hook.Add("PlayerBindPress", "JB.PlayerBindPress.LR.Airborne", function(pl, bind, pressed) // Not the safest way, but it requires the least amount of touching code outside of this file (without using nasty hacky methods)
if JB.LastRequest == this and table.HasValue(JB.LastRequestPlayers,pl) and pl:IsOnGround() and string.find( bind,"+attack" ) then
return true;
end
end)

View File

@@ -0,0 +1,56 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local RandomLoadouts = {};
RandomLoadouts[1] = {
primary="weapon_jb_ak47",
secondary="weapon_jb_glock"
};
RandomLoadouts[2] = {
primary="weapon_jb_scout",
secondary="weapon_jb_deagle"
};
local LR = JB.CLASS_LR();
LR:SetName("Duel");
LR:SetDescription("Both the prisoner and guard are given the same random loadout and full ammo. They may fight without interruption of other guards.");
LR:SetStartCallback(function(prisoner,guard)
local randomSelect = RandomLoadouts[math.random(1,#RandomLoadouts)];
JB.Util.iterate{prisoner,guard}:GiveAmmo(1000,"SMG1"):GiveAmmo(1000,"pistol"):Give(randomSelect.primary):Give(randomSelect.secondary):Give("weapon_jb_fists");
end)
LR:SetIcon(Material("icon16/bomb.png"))
LR();

View File

@@ -0,0 +1,48 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local LR = JB.CLASS_LR();
LR:SetName("Knife Battle");
LR:SetDescription("The guard and the prisoner both get a knife, all other weapons are stripped, and they must fight eachother until one of the two dies");
LR:SetStartCallback(function(prisoner,guard)
for _,ply in ipairs{prisoner,guard} do
ply:StripWeapons();
ply:Give("weapon_jb_knife");
ply:Give("weapon_jb_fists");
ply:SetHealth(100);
ply:SetArmor(0);
end
end)
LR:SetIcon(Material("icon16/flag_blue.png"))
LR();

View File

@@ -0,0 +1,53 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local LR = JB.CLASS_LR();
LR:SetName("No-Scope Battle");
LR:SetDescription("The guard and the prisoner both get a sniper rifle, which they may use to kill each other. The catch: no aiming through the scope allowed.");
LR:SetStartCallback(function(prisoner,guard)
for _,ply in ipairs{prisoner,guard} do
ply:StripWeapons();
ply:Give("weapon_jb_scout");
ply:GiveAmmo(899,"SMG1");
ply:SetHealth(100);
ply:SetArmor(0);
end
end)
LR:SetIcon(Material("icon16/flag_red.png"))
local this = LR();
hook.Add("PlayerBindPress", "JB.PlayerBindPress.LR.NoScopeBattle", function(pl, bind, pressed) // Not the safest way, but it requires the least amount of touching code outside of this file (without using nasty hacky methods)
if JB.LastRequest == this and table.HasValue(JB.LastRequestPlayers,pl) and string.find( bind,"+attack2" ) then
return true;
end
end)

View File

@@ -0,0 +1,190 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local randomQuestions = {
{ // Questions about the Jail Break gamemode
{question="Who created the first version of Jail Break for Garry's Mod?",answer="excl"},
{question="What does LR stand for?",answer="last request"},
{question="Who is the person in charge of the prison?",answer="warden"},
},
{ // Questions about internet culture, games, etc...
{question="In the game Metal Gear Solid,who is the twin brother of Solid Snake?",answer="Liquid Snake"},
{question="In video gaming, what is the name of the princess whom Mario repeatedly stops Bowser from kidnapping?",answer="Princess Peach"},
{question="In the game Mortal Kombat, what phrase is heard when Scorpion uses his spear?",answer="Get over here"},
{question="What is the name of the gang member that video game Grand Theft Auto: San Andreas revolves around?",answer="CJ"},
{question="How many rows of aliens are there usually at the start of a Space Invaders game?",answer="5"},
{question="How many square blocks is each game piece composed of in the game of Tetris?",answer="4"},
{question="What is the name of the fictional English archaeologist in the game Tomb Raider?",answer="Lara Croft"},
{question="In the game Doom, which planet is the space marine posted to after assaulting his commanding officer?",answer="Mars"},
{question="Which Playstation 2 game, released in 2003, was banned by several countries and implicated by the media in a murder, due to its graphic violence?",answer="Manhunt"},
{question="Which 1997 Playstation games opening song is a Chemical Brothers remix of the Manic Street Preachers song Everything Must Go?",answer="Gran Turismo"},
{question="Which 1986 Nintendo game is set in the fantasy land of Hyrule, and centres on a boy named Link?",answer="Zelda"},
{question="In video games, what colour is Pac-Man?",answer="yellow"},
{question="Black Ops is the subtitle of which game?",answer="Call of Duty"},
{question="Pikachu is one of the species of creatures in which series of games?",answer="Pokemon"},
{question="Jumpmans goal is to save the Lady from the giant ape in which 1981 arcade game?",answer="Donkey Kong"},
{question="The Covenant are fictional military alien races in which game series?",answer="Halo"},
{question="What color is the most autistic video game hedgehog?",answer="blue"},
},
{ // Questions about human subjects, such as history and geography
{question="Name a game in which two teams kick a ball around.",answer="football"},
{question="Who wrote Julius Caesar, Macbeth and Hamlet?",answer="Shakespeare"},
{question="When was Elvis' first ever concert?",answer="1954"},
{question="In which city is Hollywood?",answer="Los Angeles"},
{question="Who was the director of the film 'Psycho'?",answer="Hitchcock"},
{question="What's the smallest country in the world?",answer="Vatican City"},
{question="What's the capital of Finland?",answer="Helsinki"},
{question="How many legs has a spider got?",answer="8"},
},
"mathproblem"
};
local question,answer;
_RTN_RUNSTRING_JB_LR_TRIVIA_QUESTION = 0;
local winner_found = false;
local LR = JB.CLASS_LR();
LR:SetName("Trivia");
LR:SetDescription("After the countdown, a random question about a random subject will be asked. The first person to answer this question correctly in chat will win the last request, the loser will be killed.");
LR:SetStartCallback(function(prisoner,guard)
local subject = randomQuestions[math.random(1,#randomQuestions)];
if type("subject") == "string" and subject == "mathproblem" then
local operationsFirst = {" + "," - "};
local operationsSecond = {" * "};
question=tostring(math.random(1,10));
local typ = math.random(1,4);
if typ == 1 or typ == 2 then
question=question..table.Random(operationsFirst)..tostring(math.random(1,10));
end
local div = 0;
if typ == 2 or typ == 3 or typ == 4 then
div = math.random(1,10);
question=question..table.Random(operationsSecond)..(typ == 4 and "( " or "")..tostring(div);
end
if typ == 3 then
question=question..table.Random(operationsSecond)..tostring(math.random(1,10))
elseif typ == 4 then
local sec = math.random(-10,10);
if div-sec == 0 then
sec = sec+math.random(1,5);
end
question=question..table.Random(operationsFirst)..sec.." )";
end
RunString("_RTN_RUNSTRING_JB_LR_TRIVIA_QUESTION = "..question..";");
answer = _RTN_RUNSTRING_JB_LR_TRIVIA_QUESTION;
question=question.." = "
elseif type(subject) == "table" then
local rnd = table.Random(subject);
question = rnd.question; // TODO: add more questions
answer = rnd.answer;
end
winner_found = false;
net.Start("JB.LR.Trivia.SendQuestion");
net.WriteString(question);
net.Broadcast();
end)
LR:SetSetupCallback(function(prisoner,guard)
net.Start("JB.LR.Trivia.SendPrepare");
net.WriteEntity(prisoner);
net.WriteEntity(guard);
net.Broadcast();
return false; // don't halt setup
end)
LR:SetIcon(Material("icon16/rosette.png"))
local id = LR();
if SERVER then
util.AddNetworkString("JB.LR.Trivia.SendQuestion");
util.AddNetworkString("JB.LR.Trivia.SendPrepare");
util.AddNetworkString("JB.LR.Trivia.SendWinner");
hook.Add( "PlayerSay", "JB.PlayerSay.LR.Trivia", function( ply, text, team )
if JB.LastRequest == id and table.HasValue(JB.LastRequestPlayers,ply) and string.find(string.lower(text),string.lower(answer)) and not winner_found then
timer.Simple(0,function()
net.Start("JB.LR.Trivia.SendWinner");
net.WriteEntity(ply);
net.Broadcast();
end);
for k,v in ipairs(JB.LastRequestPlayers)do
if IsValid(v) and v ~= ply then
v:Kill();
end
end
winner_found = true;
end
end )
elseif CLIENT then
hook.Add("PlayerBindPress", "JB.PlayerBindPress.LR.TriviaNoSayBindsFuckYou", function(pl, bind, pressed) // Not the safest way, but it requires the least amount of touching code outside of this file (without using nasty hacky methods)
if JB.LastRequest == id and table.HasValue(JB.LastRequestPlayers,pl) and string.find( bind,"say" ) then
return true;
end
end)
net.Receive("JB.LR.Trivia.SendPrepare",function()
local guard,prisoner = net.ReadEntity(),net.ReadEntity();
if not JB.Util.isValid(guard,prisoner) then return end
chat.AddText( JB.Color["#bbb"], "Quizmaster", JB.Color.white, ": Hello ", guard, JB.Color.white, " and ", prisoner, JB.Color.white, ", prepare to give your answer via chat." );
timer.Simple(2,function()
chat.AddText( JB.Color["#bbb"], "Quizmaster", JB.Color.white, ": The first person to answer correctly will win this game of Trivia." );
end);
end);
net.Receive("JB.LR.Trivia.SendQuestion",function()
local question = net.ReadString() or "ERROR";
chat.AddText( JB.Color["#bbb"], "Quizmaster", JB.Color.white, ": "..question );
end);
net.Receive("JB.LR.Trivia.SendWinner",function()
local winner = net.ReadEntity();
if not IsValid(winner) then return end
chat.AddText( JB.Color["#bbb"], "Quizmaster", JB.Color.white, ": That is correct! ", winner, JB.Color.white, " wins." );
end);
end

183
gamemode/sh_init.lua Normal file
View File

@@ -0,0 +1,183 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local config = {};
local function makeConfig(name,default)
if SERVER then
CreateConVar(name,default,{ FCVAR_ARCHIVE, FCVAR_SERVER_CAN_EXECUTE, FCVAR_DONTRECORD });
end
return {name=name,default=default};
end
config.debug = makeConfig("jb_config_debug","0")
config.font = makeConfig("jb_config_font","Roboto")
config.website = makeConfig("jb_config_website","example.com");
config.maxWardenItems = makeConfig("jb_config_max_warden_items","20");
config.maxWardenRounds = makeConfig("jb_config_max_warden_rounds","3");
config.joinTime = makeConfig("jb_config_jointime","20");
config.setupTime = makeConfig("jb_config_setuptime","60");
config.guardsAllowed = makeConfig("jb_config_guards_allowed","30");
config.rebelSensitivity = makeConfig("jb_config_rebel_sensitivity","2");
config.guardPlaytime = makeConfig("jb_config_guards_playtime","120");
config.prisonerNameChange = makeConfig("jb_config_prisoners_namechange","0");
config.wardenControl = makeConfig("jb_config_warden_control_enabled","1");
config.prisonerSpecialChance = makeConfig("jb_config_prisoner_special_chance","10");
config.knivesAreConcealed = makeConfig("jb_config_knives_are_concealed","1");
config.roundsPerMap = makeConfig("jb_config_rounds_per_map","9999");
config.notifyLG = makeConfig("jb_config_notify_lastguard",1);
-- meta stuff
JB = {}
JB._IndexCallback = {}; -- {get = function() end, set = function() end};
setmetatable(JB,{
__index = function(tbl,key)
if key == "Gamemode" then
return GM or GAMEMODE or {};
end
if JB._IndexCallback[key] and JB._IndexCallback[key].get then
return JB._IndexCallback[key].get();
end
return nil;
end,
__newindex = function(t,key,value)
if JB._IndexCallback[key] and JB._IndexCallback[key].set then
JB._IndexCallback[key].set(value);
return nil;
end
rawset(t,key,value);
return nil;
end
})
JB.Config = {};
setmetatable(JB.Config,{
__index = function(tbl,key)
if config[key] then
if SERVER then
local val = GetConVarString(config[key].name);
return val and val ~= "" and val or config[key] and config[key].default or "0";
elseif CLIENT then
return config[key].v or config[key].default;
end
end
return nil;
end
})
-- debug
function JB:DebugPrint(...)
if self.Config.debug and self.Config.debug == "1" then
MsgC(Color(220,2420,220),"[JB DEBUG] [")
MsgC(SERVER and Color(90,150,255) or Color(255,255,90),SERVER and "SERVER" or "CLIENT");
MsgC(Color(220,220,220),"] ["..os.date().."]\t\t");
MsgC(Color(255,255,255),...);
Msg("\n");
end
end
-- some networking
if CLIENT then
net.Receive("JB.FetchConfig",function(len)
for k,v in pairs(net.ReadTable() or {})do
if not config[k] then return end
config[k].v = v;
end
JB:DebugPrint("Config received!");
end);
hook.Add("InitPostEntity","JB.FetchConfig.Load",function()
net.Start("JB.FetchConfig");
net.SendToServer();
hook.Remove("Initialize","JB.FetchConfig.Load");
JB:DebugPrint("Requesting config...");
end);
elseif SERVER then
util.AddNetworkString("JB.FetchConfig");
net.Receive("JB.FetchConfig",function(len,ply)
JB:DebugPrint("Received config request by: "..ply:Nick());
net.Start("JB.FetchConfig");
local tab = {};
for k,v in pairs(config)do
tab[k]=JB.Config[k];
end
net.WriteTable(tab);
net.Send(ply);
end);
end
-- dumb stuff I'm forced into adding
JB.Gamemode.TeamBased = true;
JB.Gamemode.Name = "Jail Break";
-- utility functions
local loadFolder = function(folder,shared)
local path = "jailbreak/gamemode/"..folder.."/";
for _,name in pairs(file.Find(path.."*.lua","LUA")) do
local runtype = shared or "sh";
if not shared then
runtype = string.Left(name, 2);
end
if not runtype or ( runtype ~= "sv" and runtype ~= "sh" and runtype ~= "cl" ) then return false end
if SERVER then
if runtype == "sv" then
JB:DebugPrint("Loading file: "..name);
include(folder.."/"..name);
elseif runtype == "sh" then
JB:DebugPrint("Loading file: "..name);
include(folder.."/"..name);
AddCSLuaFile(folder.."/"..name);
elseif runtype == "cl" then
AddCSLuaFile(folder.."/"..name);
end
elseif CLIENT then
if (runtype == "sh" or runtype == "cl") then
JB:DebugPrint("Loading file: "..name);
include(folder.."/"..name);
end
end
end
return true
end
JB.Util = {};
assert(loadFolder("util") and loadFolder("core") and loadFolder("classes","sh") and loadFolder("lastrequests","sh") and loadFolder("vgui","cl"),"Failed to load Jail Break 7! Contact a developer!")

View File

@@ -0,0 +1,82 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
/*
drawSimpleShadowText
draws a text with a shadow font under it.
*/
// we will probably call this many times each frame, so let's localize a bit
local getTextSize = surface.GetTextSize;
local setTextPos = surface.SetTextPos;
local setTextColor = surface.SetTextColor;
local setFont = surface.SetFont;
local drawText = surface.DrawText;
local ceil = math.ceil;
local w,h;
// actual function
function JB.Util.drawSimpleShadowText(text,font,x,y,color,xalign,yalign,passes)
if not font or not x or not y or not color or not xalign or not yalign then return end
passes=passes or 2;
text = tostring( text )
setFont(font.."Shadow");
w,h = getTextSize( text )
if (xalign == TEXT_ALIGN_CENTER) then
x = x - w/2
elseif (xalign == TEXT_ALIGN_RIGHT) then
x = x - w
end
if (yalign == TEXT_ALIGN_CENTER) then
y = y - h/2
elseif ( yalign == TEXT_ALIGN_BOTTOM ) then
y = y - h
end
setTextColor( 0,0,0,color.a )
for i=1,passes do
setTextPos( ceil( x ), ceil( y ) );
drawText(text)
end
setFont(font);
setTextPos( ceil( x ), ceil( y ) );
setTextColor( color.r, color.g, color.b, color.a )
drawText(text)
return w, h
end

View File

@@ -0,0 +1,45 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
function JB.Util.memoize(f)
local mem = {}
setmetatable(mem, {__mode = "kv"})
return (function (x)
local r = mem[x]
if r == nil then
r = f(x)
mem[x] = r
end
return r
end)
end

132
gamemode/util/sh_util.lua Normal file
View File

@@ -0,0 +1,132 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
function JB.Util.iterate(tab)
local wrap = {};
setmetatable(wrap,{__index = function(self,req)
return (function(...)
for _,v in pairs(tab)do
if not (v[req] and type(v[req]) == "function" ) then continue end
args={...};
for i,arg in ipairs(args)do
if arg == wrap then
rawset(args,i,v);
end
end
v[req](unpack(args));
end
return wrap;
end)
end})
return wrap;
end
function JB.Util.isValid(...)
for k,v in ipairs{...}do
if not IsValid(v) then return false end
end
return true;
end
function JB.Util.formatLine(str,size)
//surface.SetFont( font );
local start = 1;
local c = 1;
local endstr = "";
local n = 0;
local lastspace = 0;
while( string.len( str ) > c )do
local sub = string.sub( str, start, c );
if( string.sub( str, c, c ) == " " ) then
lastspace = c;
end
if( surface.GetTextSize( sub ) >= size ) then
local sub2;
if( lastspace == 0 ) then
lastspace = c;
end
if( lastspace > 1 ) then
sub2 = string.sub( str, start, lastspace - 1 );
c = lastspace;
else
sub2 = string.sub( str, start, c );
end
endstr = endstr .. sub2 .. "\n";
start = c + 1;
n = n + 1;
end
c = c + 1;
end
if( start < string.len( str ) ) then
endstr = endstr .. string.sub( str, start );
end
return endstr, n;
end
JB.Commands = {};
function JB.Util.addChatCommand(cmd,func)
JB.Commands[cmd] = {func=func};
end
hook.Add("PlayerSay","JBUtil.PlayerSay.ChatCommands",function(p,t)
if (p.JBNextCmd and p.JBNextCmd > CurTime()) or not IsValid(p) or not t then return end
p.JBNextCmd = CurTime()+1; -- prevent spam
local text = t;
if t and ( string.Left(t,1) == "!" or string.Left(t,1) == "/" or string.Left(t,1) == ":") then
local t = string.Explode(" ",t or "",false);
t[1] = string.gsub(t[1] or "",string.Left(t[1],1) or "","");
if t and t[1] then
local c = string.lower(t[1]);
if JB.Commands and JB.Commands[c] then
table.remove(t,1);
JB.Commands[c].func(p,c,t);
JB:DebugPrint(p:Nick().." ran chat command '"..text.."'");
return false
end
end
end
end)

86
gamemode/vgui/button.lua Normal file
View File

@@ -0,0 +1,86 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local matEdge = Material("materials/jailbreak_excl/button_edge.png");
local matMid = Material("materials/jailbreak_excl/button_middle.png")
surface.CreateFont("JBButton",{
font=JB.Config.font,
size=14,
weight = 700,
});
surface.CreateFont("JBButtonShadow",{
font=JB.Config.font,
size=14,
weight = 700,
blursize=2,
});
local PNL = {};
AccessorFunc(PNL,"text","Text",FORCE_STRING);
function PNL:Init()
self:SetText("Example text");
self.color = Color(200,200,200);
end
function PNL:OnCursorEntered()
self.Hover = true;
end
function PNL:OnCursorExited()
self.Hover=false;
end
function PNL:Paint(w,h)
if self.Hover then
self.color.r = math.Approach( self.color.r, 255, FrameTime() * 600 )
self.color.g = math.Approach( self.color.g, 255, FrameTime() * 600 )
self.color.b = math.Approach( self.color.b, 255, FrameTime() * 600 )
else
self.color.r = math.Approach( self.color.r, 180, FrameTime() * 400 )
self.color.g = math.Approach( self.color.g, 180, FrameTime() * 400 )
self.color.b = math.Approach( self.color.b, 180, FrameTime() * 400 )
end
surface.SetDrawColor(Color(self.color.r * .8,self.color.g * .8, self.color.b * .8))
surface.SetMaterial(matEdge);
surface.DrawTexturedRectRotated(32/2,h/2,32,32,0);
surface.DrawTexturedRectRotated(w-32/2,h/2,32,32,180);
surface.SetMaterial(matMid);
surface.DrawTexturedRectRotated(w/2,h/2,w-64,32,0);
draw.SimpleText(self:GetText(),"JBButtonShadow",w/2,h/2,JB.Color.black,1,1);
draw.SimpleText(self:GetText(),"JBButtonShadow",w/2,h/2,JB.Color.black,1,1);
draw.SimpleText(self:GetText(),"JBButton",w/2,h/2,self.color,1,1);
end
vgui.Register("JB.Button",PNL,"Panel");

182
gamemode/vgui/frame.lua Normal file
View File

@@ -0,0 +1,182 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
/* backup of old vgui
local matGradient = Material("materials/jailbreak_excl/gradient.png");
local matClose = Material("materials/jailbreak_excl/vgui_close.png");
local matCloseHover = Material("materials/jailbreak_excl/vgui_close_hover.png");
local color_white_shadow = Color(255,255,255,60);
vgui.Register("JB.Frame.CloseButton",{
OnCursorEntered = function(self)
self.Hover = true;
end,
OnCursorExited = function(self)
self.Hover = false;
end,
Paint = function(self,w,h)
surface.SetMaterial(self.Hover and matCloseHover or matClose)
surface.SetDrawColor(JB.Color.white);
surface.DrawTexturedRectRotated(w/2,h/2,32,32,0);
end
},"Panel");
local PNL = {};
AccessorFunc(PNL,"title","Title",FORCE_STRING);
function PNL:Init()
self:SetTitle("Example title");
self.CloseButton = vgui.Create("JB.Frame.CloseButton",self)
self.CloseButton:SetSize(32,32);
self.CloseButton.OnMouseReleased = function()
self:Remove();
end
end
function PNL:PerformLayout()
self.CloseButton:SetPos(self:GetWide()-32,0);
end
function PNL:Paint(w,h)
draw.RoundedBox(8,0,0,w,h,JB.Color.black);
draw.RoundedBoxEx(6,2,2,w-4,28,JB.Color["#BBB"],true,true);
draw.SimpleText(string.upper(self:GetTitle()),"JBNormal",13,30/2+1,color_white_shadow,0,1);
draw.SimpleText(string.upper(self:GetTitle()),"JBNormal",12,30/2,JB.Color["#222"],0,1);
surface.SetDrawColor(color_white_shadow);
surface.DrawRect(2,29,w-4,1);
surface.SetDrawColor(Color(0,0,0,120));
surface.SetMaterial(matGradient);
surface.DrawTexturedRectRotated(w/2,30 - 20/2,w-4,20,180);
draw.RoundedBoxEx(6,2,32,w-4,h-32-2,JB.Color["#444"],false,false,true,true);
surface.SetDrawColor(Color(0,0,0,120));
surface.SetMaterial(matGradient);
local h_grad = math.Clamp(h-30-2-8,0,256);
surface.DrawTexturedRectRotated(w/2,30 + 3 + (h_grad)/2,w-6,h_grad,0);
end
vgui.Register("JB.Frame",PNL,"EditablePanel");
*/
surface.CreateFont("JBWindowTitle",{
font = "Arial",
size = 18,
weight = 800
})
surface.CreateFont("JBWindowTitleShadow",{
font = "Arial",
size = 18,
weight = 800,
blursize =2
})
local matGradient = Material("materials/jailbreak_excl/gradient.png");
local matClose = Material("materials/jailbreak_excl/vgui_close.png");
local matCloseHover = Material("materials/jailbreak_excl/vgui_close_hover.png");
local color_white_shadow = Color(255,255,255,1);
local color_gradient_top = Color(0,0,0,20);
local color_gradient_bottom = Color(0,0,0,120);
vgui.Register("JB.Frame.CloseButton",{
Init = function(self)
self.clr = Color(200,0,0,80);
end,
OnCursorEntered = function(self)
self.Hover = true;
end,
OnCursorExited = function(self)
self.Hover = false;
end,
Paint = function(self,w,h)
//surface.SetMaterial(self.Hover and matCloseHover or matClose)
//surface.SetDrawColor(JB.Color.white);
//surface.DrawTexturedRectRotated(w/2,h/2,32,32,0);
if self.Hover then
self.clr.a = Lerp(FrameTime()*6,self.clr.a,255);
else
self.clr.a = Lerp(FrameTime()*6,self.clr.a,60);
end
draw.RoundedBox(6,0,0,w,h,Color(0,0,0,150));
draw.RoundedBox(4,1,1,w-2,h-2,JB.Color.black);
draw.RoundedBox(4,2,2,w-4,h-4,self.clr)
surface.SetDrawColor(color_gradient_bottom);
surface.SetMaterial(matGradient);
surface.DrawTexturedRect(2,2,w-4,h-4);
end
},"Panel");
local PNL = {};
AccessorFunc(PNL,"title","Title",FORCE_STRING);
function PNL:Init()
self:SetTitle("Example title");
self.CloseButton = vgui.Create("JB.Frame.CloseButton",self)
self.CloseButton:SetSize(20,20);
self.CloseButton.OnMouseReleased = function()
self:Remove();
end
end
function PNL:PerformLayout()
self.CloseButton:SetPos(self:GetWide()-(self.CloseButton:GetWide())-(32-self.CloseButton:GetWide())/2,(32-self.CloseButton:GetTall())/2);
end
function PNL:Paint(w,h)
draw.RoundedBox(8,0,0,w,h,Color(0,0,0,150));
draw.RoundedBox(4,1,1,w-2,h-2,JB.Color.black);
draw.RoundedBoxEx(4,2,2,w-4,28,JB.Color["#111"],true,true);
draw.RoundedBox(6,2,2,w-4,h-4,JB.Color["#4a4a4a"],false,false,true,true);
surface.SetDrawColor(color_gradient_top);
surface.SetMaterial(matGradient);
surface.DrawTexturedRectRotated(w/2,30 - 20/2,w-4,20,180);
surface.SetDrawColor(color_white_shadow);
surface.DrawRect(2,29,w-4,1);
surface.SetDrawColor(color_gradient_bottom);
surface.SetMaterial(matGradient);
local h_grad = math.Clamp(h-30-8,0,256);
surface.DrawTexturedRectRotated(w/2,31 + (h_grad)/2,w-6,h_grad,0);
local wTitle,hTitle = JB.Util.drawSimpleShadowText(string.upper(self:GetTitle()),"JBWindowTitle",12,32/2 + 1,JB.Color["#EEE"],0,1,4);
end
vgui.Register("JB.Frame",PNL,"EditablePanel");

50
gamemode/vgui/panel.lua Normal file
View File

@@ -0,0 +1,50 @@
-- ####################################################################################
-- ## ##
-- ## ##
-- ## CASUAL BANANAS CONFIDENTIAL ##
-- ## ##
-- ## __________________________ ##
-- ## ##
-- ## ##
-- ## Copyright 2014 (c) Casual Bananas ##
-- ## All Rights Reserved. ##
-- ## ##
-- ## NOTICE: All information contained herein is, and remains ##
-- ## the property of Casual Bananas. The intellectual and technical ##
-- ## concepts contained herein are proprietary to Casual Bananas and may be ##
-- ## covered by U.S. and Foreign Patents, patents in process, and are ##
-- ## protected by trade secret or copyright law. ##
-- ## Dissemination of this information or reproduction of this material ##
-- ## is strictly forbidden unless prior written permission is obtained ##
-- ## from Casual Bananas ##
-- ## ##
-- ## _________________________ ##
-- ## ##
-- ## ##
-- ## Casual Bananas is registered with the "Kamer van Koophandel" (Dutch ##
-- ## chamber of commerce) in The Netherlands. ##
-- ## ##
-- ## Company (KVK) number : 59449837 ##
-- ## Email : info@casualbananas.com ##
-- ## ##
-- ## ##
-- ####################################################################################
local PNL = {};
local color_shade = Color(255,255,255,5);
local color_bg = Color(20,20,20);
local color_bg_weak = Color(20,20,20,240);
local matGradient = Material("materials/jailbreak_excl/gradient.png");
function PNL:Paint(w,h)
surface.SetMaterial(matGradient);
surface.SetDrawColor(color_bg);
surface.DrawTexturedRect(0,0,w,h);
surface.SetDrawColor(color_bg_weak);
surface.DrawRect(0,0,w,h);
draw.RoundedBox(0,0,0,w,1,color_shade);
end
vgui.Register("JB.Panel",PNL,"EditablePanel");