mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-15 12:53:46 +03:00
685 lines
22 KiB
Lua
685 lines
22 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
|
|
if SERVER then
|
|
AddCSLuaFile()
|
|
end
|
|
|
|
ENT.Type = "anim"
|
|
ENT.Model = Model("models/weapons/w_slam.mdl")
|
|
ENT.Base = "ent_chess_board"
|
|
ENT.Models = {
|
|
["board"] = Model("models/props_phx/games/chess/board.mdl"),
|
|
["table"] = Model("models/props/de_tides/restaurant_table.mdl"),
|
|
["hl2table"] = Model( "models/props_c17/furnituretable001a.mdl" ),
|
|
|
|
["dama"] = Model("models/props_phx/games/chess/white_pawn.mdl"),
|
|
|
|
["WhiteMan"] = Model("models/props_phx/games/chess/white_dama.mdl"), ["BlackMan"] = Model("models/props_phx/games/chess/black_dama.mdl"),
|
|
["WhiteKing"] = Model("models/props_phx/games/chess/white_dama.mdl"), ["BlackKing"] = Model("models/props_phx/games/chess/black_dama.mdl"),
|
|
}
|
|
ENT.Characters = { -- Notepad's being weird and not showing these characters. If you can't see them, they'll still show up in-game.
|
|
["WhiteMan"] = Model("⛀"), ["BlackMan"] = Model("⛂"),
|
|
["WhiteKing"] = Model("⛁"), ["BlackKing"] = Model("⛃"),
|
|
}
|
|
ENT.DrawDouble = {
|
|
["King"] = true,
|
|
}
|
|
|
|
ENT.PrintName = "Draughts/Checkers"
|
|
ENT.Author = "my_hat_stinks"
|
|
ENT.Information = "A draughts (checkers) board"
|
|
ENT.Category = "Game boards"
|
|
|
|
ENT.Game = "Draughts"
|
|
ENT.Spawnable = true
|
|
ENT.AdminOnly = true
|
|
ENT.AdminSpawnable = true
|
|
|
|
--Status
|
|
local CHESS_INACTIVE = 0
|
|
local CHESS_WHITEMOVE = 1
|
|
local CHESS_BLACKMOVE = 2
|
|
local CHESS_WHITEPROMO = 3 local CHESS_WHITEJUMP = 3
|
|
local CHESS_BLACKPROMO = 4 local CHESS_BLACKJUMP = 4
|
|
local CHESS_WAGER = 5
|
|
|
|
--Captured piece squares
|
|
local CHESS_WCAP1 = 10
|
|
local CHESS_WCAP2 = 11
|
|
local CHESS_BCAP1 = 12
|
|
local CHESS_BCAP2 = 13
|
|
|
|
-- Draw Offer
|
|
local PLAYER_NONE = 0 -- Nobody offering to draw
|
|
local PLAYER_WHITE = 1 -- White offering to draw
|
|
local PLAYER_BLACK = 2 -- Black offering to draw
|
|
|
|
local NumToLetter = {"a", "b", "c", "d", "e", "f", "g", "h", ["a"]=1, ["b"]=2, ["c"]=3, ["d"]=4, ["e"]=5, ["f"]=6, ["g"]=7, ["h"]=8} --Used extensively for conversions
|
|
|
|
ENT.StartState = CHESS_BLACKMOVE
|
|
|
|
function ENT:SetupDataTables()
|
|
-- self:NetworkVar( "Int", 0, "BlackPassant" )
|
|
-- self:NetworkVar( "Int", 1, "WhitePassant" )
|
|
|
|
self:NetworkVar( "Int", 2, "ChessState" )
|
|
self:NetworkVar( "Bool", 0, "Playing" )
|
|
self:NetworkVar( "Int", 3, "DrawOffer" )
|
|
|
|
self:NetworkVar( "Float", 0, "WhiteWager" )
|
|
self:NetworkVar( "Float", 1, "BlackWager" )
|
|
|
|
self:NetworkVar( "Entity", 0, "WhitePlayer" )
|
|
self:NetworkVar( "Entity", 1, "BlackPlayer" )
|
|
self:NetworkVar( "Entity", 2, "TableEnt" )
|
|
|
|
-- self:NetworkVar( "Int", 3, "MoveCount" )
|
|
-- self:NetworkVar( "Bool", 1, "Repetition" )
|
|
|
|
self:NetworkVar( "Bool", 2, "PSWager" )
|
|
|
|
self:NetworkVar( "Float", 2, "WhiteTime" )
|
|
self:NetworkVar( "Float", 3, "BlackTime" )
|
|
|
|
--Draughts vars
|
|
self:NetworkVar( "Bool", 1, "JumpMove" )
|
|
self:NetworkVar( "Int", 0, "JumpLet" )
|
|
self:NetworkVar( "Int", 1, "JumpNum" )
|
|
end
|
|
|
|
function ENT:Initialize()
|
|
self.ChessDerived = true
|
|
self.IsDraughts = true
|
|
|
|
return self.BaseClass.Initialize( self )
|
|
end
|
|
|
|
function ENT:GetManMoves( tbl, GridLet, GridNum, IsWhite )
|
|
local CapMove = false
|
|
|
|
--Forward Right
|
|
local TargetRow = GridNum+ (IsWhite and 1 or (-1))
|
|
local TargetColumn = NumToLetter[GridLet]+1
|
|
if TargetRow<=8 and TargetRow>=1 and TargetColumn<=8 and TargetColumn>=1 then
|
|
local target = self:GetSquare( NumToLetter[TargetColumn], TargetRow )
|
|
if target then
|
|
if ((self:SquareTeam(target)=="White")~=IsWhite) then --Enemy piece
|
|
local CapRow = TargetRow+ (IsWhite and 1 or (-1))
|
|
local CapCol = TargetColumn+1
|
|
|
|
if CapRow<=8 and CapRow>=1 and CapCol<=8 and CapCol>=1 then --In range
|
|
local target = self:GetSquare( NumToLetter[CapCol], CapRow )
|
|
if not target then --Empty space
|
|
tbl[NumToLetter[CapCol]][CapRow] = {"CAPTURE", NumToLetter[TargetColumn], TargetRow} --Capture move
|
|
CapMove = true --Flag as capture move
|
|
end
|
|
end
|
|
end
|
|
else
|
|
tbl[NumToLetter[TargetColumn]][TargetRow] = true --Standard valid move
|
|
end
|
|
end
|
|
--Forward Left
|
|
local TargetRow = GridNum+ (IsWhite and 1 or (-1))
|
|
local TargetColumn = NumToLetter[GridLet]-1
|
|
if TargetRow<=8 and TargetRow>=1 and TargetColumn<=8 and TargetColumn>=1 then
|
|
local target = self:GetSquare( NumToLetter[TargetColumn], TargetRow )
|
|
if target then
|
|
if ((self:SquareTeam(target)=="White")~=IsWhite) then
|
|
local CapRow = TargetRow+ (IsWhite and 1 or (-1))
|
|
local CapCol = TargetColumn-1
|
|
|
|
if CapRow<=8 and CapRow>=1 and CapCol<=8 and CapCol>=1 then
|
|
local target = self:GetSquare( NumToLetter[CapCol], CapRow )
|
|
if not target then
|
|
tbl[NumToLetter[CapCol]][CapRow] = {"CAPTURE", NumToLetter[TargetColumn], TargetRow}
|
|
CapMove = true
|
|
end
|
|
end
|
|
end
|
|
else
|
|
tbl[NumToLetter[TargetColumn]][TargetRow] = true --Standard valid move
|
|
end
|
|
end
|
|
|
|
return CapMove
|
|
end
|
|
function ENT:GetKingMoves( tbl, GridLet, GridNum, IsWhite )
|
|
local CapMove = self:GetManMoves( tbl, GridLet, GridNum, IsWhite ) --Forward moves
|
|
|
|
--Back Right
|
|
local TargetRow = GridNum+ (IsWhite and (-1) or (1))
|
|
local TargetColumn = NumToLetter[GridLet]+1
|
|
if TargetRow<=8 and TargetRow>=1 and TargetColumn<=8 and TargetColumn>=1 then
|
|
local target = self:GetSquare( NumToLetter[TargetColumn], TargetRow )
|
|
if target then
|
|
if ((self:SquareTeam(target)=="White")~=IsWhite) then
|
|
local CapRow = TargetRow+ (IsWhite and (-1) or (1))
|
|
local CapCol = TargetColumn+1
|
|
|
|
if CapRow<=8 and CapRow>=1 and CapCol<=8 and CapCol>=1 then
|
|
local target = self:GetSquare( NumToLetter[CapCol], CapRow )
|
|
if not target then
|
|
tbl[NumToLetter[CapCol]][CapRow] = {"CAPTURE", NumToLetter[TargetColumn], TargetRow}
|
|
CapMove = true
|
|
end
|
|
end
|
|
end
|
|
else
|
|
tbl[NumToLetter[TargetColumn]][TargetRow] = true --Standard valid move
|
|
end
|
|
end
|
|
--Back Left
|
|
local TargetRow = GridNum+ (IsWhite and (-1) or (1))
|
|
local TargetColumn = NumToLetter[GridLet]-1
|
|
if TargetRow<=8 and TargetRow>=1 and TargetColumn<=8 and TargetColumn>=1 then
|
|
local target = self:GetSquare( NumToLetter[TargetColumn], TargetRow )
|
|
if target then
|
|
if ((self:SquareTeam(target)=="White")~=IsWhite) then
|
|
local CapRow = TargetRow+ (IsWhite and (-1) or (1))
|
|
local CapCol = TargetColumn-1
|
|
|
|
if CapRow<=8 and CapRow>=1 and CapCol<=8 and CapCol>=1 then
|
|
local target = self:GetSquare( NumToLetter[CapCol], CapRow )
|
|
if not target then
|
|
tbl[NumToLetter[CapCol]][CapRow] = {"CAPTURE", NumToLetter[TargetColumn], TargetRow}
|
|
CapMove = true
|
|
end
|
|
end
|
|
end
|
|
else
|
|
tbl[NumToLetter[TargetColumn]][TargetRow] = true --Standard valid move
|
|
end
|
|
end
|
|
|
|
return CapMove
|
|
end
|
|
function ENT:GetMove( GridLet, GridNum, IgnoreCap )
|
|
if not (GridLet and GridNum) then return {} end
|
|
if not NumToLetter[GridLet] then return {} end
|
|
if NumToLetter[GridLet]<1 or NumToLetter[GridLet]>8 then return {} end
|
|
if GridNum<1 or GridNum>8 then return {} end
|
|
|
|
local square = self:GetSquare( GridLet, GridNum )
|
|
if not square then return {} end
|
|
|
|
local class = square.Class or (IsValid(square.Ent) and square.Ent:GetRole())
|
|
if not class then return {} end
|
|
|
|
if self:GetJumpMove() and self:GetJumpLet()~=0 and self:GetJumpNum()~=0 and (NumToLetter[GridLet]~=self:GetJumpLet() or GridNum~=self:GetJumpNum()) then return {} end
|
|
|
|
local IsWhite = self:SquareTeam(square)=="White"
|
|
local Moved = self:SquareMoved(square)
|
|
|
|
local CanJump = IgnoreCap or self:CanCapture( IsWhite )
|
|
local tbl = { ["a"] = {}, ["b"] = {}, ["c"] = {}, ["d"] = {}, ["e"] = {}, ["f"] = {}, ["g"] = {}, ["h"] = {} }
|
|
if class=="King" then
|
|
self:GetKingMoves( tbl, GridLet, GridNum, IsWhite )
|
|
else
|
|
self:GetManMoves( tbl, GridLet, GridNum, IsWhite )
|
|
end
|
|
|
|
if CanJump then
|
|
for CheckLet,File in pairs(tbl) do
|
|
for CheckNum,v in pairs(File) do
|
|
if v==true then
|
|
tbl[CheckLet][CheckNum] = nil --We can capture, but this isn't a capture move
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return tbl
|
|
end
|
|
|
|
function ENT:ResetBoard()
|
|
if SERVER then
|
|
self:SetDrawOffer( PLAYER_NONE )
|
|
|
|
self:SetWhiteWager( -1 )
|
|
self:SetBlackWager( -1 )
|
|
|
|
self:SetWhiteTime( 600 )
|
|
self:SetBlackTime( 600 )
|
|
|
|
self:SetJumpMove( false )
|
|
self:SetJumpLet( 0 )
|
|
self:SetJumpNum( 0 )
|
|
end
|
|
self:RefreshSquares()
|
|
|
|
if self.Pieces then
|
|
for _,File in pairs( self.Pieces ) do
|
|
for _,Square in pairs(File) do
|
|
if IsValid(Square.Ent) then Square.Ent:SetGridNum(-1) Square.Ent:Remove() end
|
|
end
|
|
end
|
|
end
|
|
self.Pieces = {
|
|
["a"] = {
|
|
[1] = {Team="White",Class="Man",Moved=false}, [3] = {Team="White",Class="Man",Moved=false}, [7] = {Team="Black",Class="Man",Moved=false},
|
|
},
|
|
["b"] = {
|
|
[2] = {Team="White",Class="Man",Moved=false}, [6] = {Team="Black",Class="Man",Moved=false}, [8] = {Team="Black",Class="Man",Moved=false},
|
|
},
|
|
["c"] = {
|
|
[1] = {Team="White",Class="Man",Moved=false}, [3] = {Team="White",Class="Man",Moved=false}, [7] = {Team="Black",Class="Man",Moved=false},
|
|
},
|
|
["d"] = {
|
|
[2] = {Team="White",Class="Man",Moved=false}, [6] = {Team="Black",Class="Man",Moved=false}, [8] = {Team="Black",Class="Man",Moved=false},
|
|
},
|
|
["e"] = {
|
|
[1] = {Team="White",Class="Man",Moved=false}, [3] = {Team="White",Class="Man",Moved=false}, [7] = {Team="Black",Class="Man",Moved=false},
|
|
},
|
|
["f"] = {
|
|
[2] = {Team="White",Class="Man",Moved=false}, [6] = {Team="Black",Class="Man",Moved=false}, [8] = {Team="Black",Class="Man",Moved=false},
|
|
},
|
|
["g"] = {
|
|
[1] = {Team="White",Class="Man",Moved=false}, [3] = {Team="White",Class="Man",Moved=false}, [7] = {Team="Black",Class="Man",Moved=false},
|
|
},
|
|
["h"] = {
|
|
[2] = {Team="White",Class="Man",Moved=false}, [6] = {Team="Black",Class="Man",Moved=false}, [8] = {Team="Black",Class="Man",Moved=false},
|
|
},
|
|
[CHESS_WCAP1] = {}, [CHESS_WCAP2] = {}, [CHESS_BCAP1] = {}, [CHESS_BCAP2] = {},
|
|
}
|
|
self:Update()
|
|
end
|
|
|
|
function ENT:CanCapture( White )
|
|
for Let,column in pairs( self.Pieces ) do
|
|
for Num,square in pairs( column ) do
|
|
if square.Team==(White and "White" or "Black") then
|
|
local moves = self:GetMove( Let, Num, true )
|
|
for _,column in pairs( moves ) do
|
|
for _,move in pairs( column ) do
|
|
if type(move)=="table" and move[1]=="CAPTURE" then return true end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
function ENT:CanMove( White )
|
|
for Let,column in pairs( self.Pieces ) do
|
|
for Num,square in pairs( column ) do
|
|
if square.Team==(White and "White" or "Black") then
|
|
local moves = self:GetMove( Let, Num )
|
|
for _,column in pairs( moves ) do
|
|
for _,move in pairs( column ) do
|
|
if move then return true end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function ENT:NoMaterialCheck()
|
|
local BlackMat = {}
|
|
local WhiteMat = {}
|
|
|
|
for GridLet,File in pairs(self.Pieces) do
|
|
if GridLet==CHESS_WCAP1 or GridLet==CHESS_WCAP2 or GridLet==CHESS_BCAP1 or GridLet==CHESS_BCAP2 then continue end
|
|
for GridNum,square in pairs(File) do
|
|
if square then
|
|
local IsWhite = self:SquareTeam(square)=="White"
|
|
|
|
if IsWhite then
|
|
table.insert( WhiteMat, {Square=square, Class=Class, GridLet=GridLet, GridNum=GridNum} )
|
|
else
|
|
table.insert( BlackMat, {square=square, Class=Class, GridLet=GridLet, GridNum=GridNum} )
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (#BlackMat+#WhiteMat)==0 then self:EndGame() return false end
|
|
if #WhiteMat==0 then self:EndGame("Black") return false end
|
|
if #BlackMat==0 then self:EndGame("White") return false end
|
|
|
|
return true
|
|
end
|
|
function ENT:EndGame( winner, NoMsg )
|
|
self:SetChessState( CHESS_INACTIVE )
|
|
self:SetPlaying( false )
|
|
|
|
local White = self:GetPlayer( "White" )
|
|
local Black = self:GetPlayer( "Black" )
|
|
local WhiteName = IsValid(White) and White:Nick() or "[Anonymous White]"
|
|
local BlackName = IsValid(Black) and Black:Nick() or "[Anonymous Black]"
|
|
if not NoMsg then
|
|
net.Start( "Chess GameOver" )
|
|
if winner=="White" then
|
|
net.WriteTable( {" ", Color(255,255,255), WhiteName, Color(150,255,150), " has won against ", Color(100,100,100), BlackName, Color(150,255,150), "!"} )
|
|
else
|
|
net.WriteTable( {" ", Color(100,100,100), BlackName, Color(150,255,150), " has won against ", Color(255,255,255), WhiteName, Color(150,255,150), "!"} )
|
|
end
|
|
net.WriteString( "icon16/medal_gold_2.png" )
|
|
net.Broadcast()
|
|
end
|
|
|
|
timer.Simple( 0.5, function()
|
|
if not IsValid(self) then return end
|
|
if IsValid(Black) and Black:GetVehicle()==self.BlackSeat then Black:ExitVehicle() end
|
|
if IsValid(White) and White:GetVehicle()==self.WhiteSeat then White:ExitVehicle() end
|
|
end)
|
|
|
|
local winnings = (self.WagerValue or 0)*2
|
|
if IsValid( White ) then
|
|
if winner=="White" then
|
|
if IsValid(Black) then White:DraughtsWin( Black ) end
|
|
if self.WagerValue then
|
|
if self:GetPSWager() then
|
|
White:PS_GivePoints( winnings )
|
|
else
|
|
if White.addMoney then White:addMoney( winnings ) else White:SetDarkRPVar( "money", (White:getDarkRPVar( "money" ) or 0) + winnings ) end
|
|
end
|
|
end
|
|
elseif winner~="Black" then
|
|
if IsValid(Black) and winner~="Error" then White:DraughtsDraw( Black ) end
|
|
if self.WagerValue then
|
|
if self:GetPSWager() then
|
|
White:PS_GivePoints( self.WagerValue )
|
|
else
|
|
if White.addMoney then White:addMoney( self.WagerValue ) else White:SetDarkRPVar( "money", (White:getDarkRPVar( "money" ) or 0) + self.WagerValue ) end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if IsValid( Black ) then
|
|
if winner=="Black" then
|
|
if IsValid(White) then Black:DraughtsWin( White ) end
|
|
if self.WagerValue then
|
|
if self:GetPSWager() then
|
|
Black:PS_GivePoints( winnings )
|
|
else
|
|
if Black.addMoney then Black:addMoney( winnings ) else Black:SetDarkRPVar( "money", (Black:getDarkRPVar( "money" ) or 0) + winnings ) end
|
|
end
|
|
end
|
|
elseif winner~="White" then
|
|
if self.WagerValue then
|
|
if self:GetPSWager() then
|
|
White:PS_GivePoints( self.WagerValue )
|
|
else
|
|
if White.addMoney then White:addMoney( self.WagerValue ) else White:SetDarkRPVar( "money", (White:getDarkRPVar( "money" ) or 0) + self.WagerValue ) end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
function ENT:DoCapture( square, EndLet, EndNum )
|
|
if not square then return end
|
|
|
|
local class = square.Class
|
|
|
|
local made = false
|
|
local CapLet,CapNum
|
|
if square.Team=="White" then --Black captured
|
|
for i=CHESS_BCAP1,CHESS_BCAP2 do
|
|
for n=1,8 do
|
|
local CapSq = self:GetSquare( i, n )
|
|
if not CapSq then
|
|
self.Pieces[i][n] = {Team="White", Class=class, Moved=false}
|
|
CapSq = self.Pieces[i][n]
|
|
|
|
made = true
|
|
CapLet,CapNum = i,n
|
|
break
|
|
end
|
|
end
|
|
if made then break end
|
|
end
|
|
else
|
|
for i=CHESS_WCAP1,CHESS_WCAP2 do
|
|
for n=1,8 do
|
|
local CapSq = self:GetSquare( i, n )
|
|
if not CapSq then
|
|
self.Pieces[i][n] = {Team="Black", Class=class, Moved=false}
|
|
CapSq = self.Pieces[i][n]
|
|
|
|
made = true
|
|
CapLet,CapNum = i,n
|
|
break
|
|
end
|
|
end
|
|
if made then break end
|
|
end
|
|
end
|
|
|
|
return {From={EndLet,EndNum}, To={CapLet,CapNum}}
|
|
end
|
|
function ENT:DoMove( StartLet, StartNum, EndLet, EndNum )
|
|
if CLIENT then return end
|
|
if not (StartLet and EndLet and StartNum and EndNum) then return end
|
|
if (StartLet==EndLet) and (StartNum==EndNum) then return end
|
|
|
|
local Start = self:GetSquare( StartLet, StartNum )
|
|
if not Start then return end
|
|
|
|
local Moves = self:GetMove( StartLet, StartNum )
|
|
if not Moves[EndLet][EndNum] then return end
|
|
local Move = Moves[EndLet][EndNum]
|
|
|
|
local CapMove
|
|
if type(Move)=="table" then
|
|
if Move[1]=="CAPTURE" then
|
|
local CapLet, CapNum = Move[2], Move[3]
|
|
local square = self:GetSquare( CapLet, CapNum )
|
|
if CapLet and CapNum then
|
|
CapMove = self:DoCapture( square, CapLet, CapNum )
|
|
self.Pieces[CapLet][CapNum] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
local End = self:GetSquare( EndLet, EndNum )
|
|
if not End then
|
|
self.Pieces[EndLet] = self.Pieces[EndLet] or {}
|
|
self.Pieces[EndLet][EndNum] = self.Pieces[EndLet][EndNum] or {}
|
|
End = self.Pieces[EndLet][EndNum]
|
|
end
|
|
|
|
End.Team=Start.Team
|
|
End.Class=Start.Class
|
|
End.Moved=true
|
|
|
|
self.Pieces[StartLet][StartNum] = nil
|
|
|
|
local ply = self:GetPlayer( End.Team )
|
|
if (EndNum==1 or EndNum==8) and End.Class=="Man" then --End of the board, promote
|
|
End.Class = "King"
|
|
// self:SetChessState( End.Team=="White" and CHESS_BLACKMOVE or CHESS_WHITEMOVE )
|
|
//
|
|
// self:SetJumpMove( false )
|
|
// self:SetJumpLet( 0 )
|
|
// self:SetJumpNum( 0 )
|
|
end
|
|
if type(Move)=="table" and Move[1]=="CAPTURE" then
|
|
self:SetJumpMove(false)
|
|
if self:CanCapture( End.Team=="White" ) then
|
|
local GetMoves = self:GetMove(EndLet, EndNum)
|
|
local Cap = false
|
|
for _,column in pairs( GetMoves ) do
|
|
for _,move in pairs(column) do
|
|
if move and move~=true then
|
|
Cap=true
|
|
end
|
|
end
|
|
end
|
|
if Cap then
|
|
self:SetJumpMove( true )
|
|
self:SetJumpLet( NumToLetter[EndLet] )
|
|
self:SetJumpNum( EndNum )
|
|
else
|
|
self:SetChessState( End.Team=="White" and CHESS_BLACKMOVE or CHESS_WHITEMOVE )
|
|
|
|
self:SetJumpMove( false )
|
|
self:SetJumpLet( 0 )
|
|
self:SetJumpNum( 0 )
|
|
end
|
|
else
|
|
self:SetChessState( End.Team=="White" and CHESS_BLACKMOVE or CHESS_WHITEMOVE )
|
|
|
|
self:SetJumpMove( false )
|
|
self:SetJumpLet( 0 )
|
|
self:SetJumpNum( 0 )
|
|
end
|
|
else --Standard move, other player's turn
|
|
self:SetChessState( End.Team=="White" and CHESS_BLACKMOVE or CHESS_WHITEMOVE )
|
|
|
|
self:SetJumpMove( false )
|
|
self:SetJumpLet( 0 )
|
|
self:SetJumpNum( 0 )
|
|
end
|
|
|
|
local move = {From={StartLet,StartNum},To={EndLet,EndNum}}
|
|
self:Update( move, CapMove )
|
|
|
|
self:NoMaterialCheck()
|
|
|
|
if self:GetChessState()==CHESS_BLACKMOVE and not self:CanMove( false ) then self:EndGame( "White" ) end
|
|
if self:GetChessState()==CHESS_WHITEMOVE and not self:CanMove( true ) then self:EndGame( "Black" ) end
|
|
|
|
return move
|
|
end
|
|
|
|
function ENT:GetElo( ply )
|
|
return IsValid(ply) and " ("..ply:GetDraughtsElo()..")" or ""
|
|
end
|
|
|
|
if CLIENT then
|
|
local PanelCol = {
|
|
Main = Color(0,0,0,200), ToMove = Color(200,200,200,20), Text = Color(180,180,180),
|
|
White = Color(255,255,255), Black = Color(20,20,20,255),
|
|
}
|
|
local StateToString = {[CHESS_INACTIVE] = "Waiting", [CHESS_WHITEMOVE] = "White", [CHESS_BLACKMOVE] = "Black", [CHESS_WHITEPROMO] = "White (jumping)", [CHESS_BLACKPROMO] = "Black (jumping)", [CHESS_WAGER] = "Wagers"}
|
|
function ENT:CreateChessPanel()
|
|
self:EndSpectating()
|
|
|
|
local frame = vgui.Create( "DFrame" )
|
|
frame:SetSize(400,115)
|
|
frame:SetPos( (ScrW()/2)-100, ScrH()-150 )
|
|
--frame:SetDraggable( false )
|
|
frame:SetTitle( "" )
|
|
frame:ShowCloseButton( false )
|
|
frame:SetDeleteOnClose( true )
|
|
frame.Paint = function( s,w,h )
|
|
if not IsValid(self) then
|
|
s:Remove()
|
|
gui.EnableScreenClicker( false )
|
|
|
|
return
|
|
end
|
|
|
|
draw.RoundedBox( 8, 0, 0, w, h, PanelCol.Main )
|
|
end
|
|
frame:DockMargin( 0,0,0,0 )
|
|
frame:DockPadding( 5,6,5,5 )
|
|
|
|
local TimePnl = vgui.Create( "DPanel", frame )
|
|
TimePnl:Dock( RIGHT )
|
|
TimePnl:SetWide( 100 )
|
|
TimePnl:DockMargin( 2,2,2,2 )
|
|
TimePnl.Paint = function(s,w,h)
|
|
if not IsValid(self) then return end
|
|
|
|
draw.RoundedBox( 16, 0, 0, w, (h/2)-1, PanelCol.ToMove )
|
|
draw.RoundedBox( 16, 0, (h/2)+1, w, (h/2)-1, PanelCol.ToMove )
|
|
|
|
draw.SimpleText( string.FormattedTime( math.Round(self:GetWhiteTime() or 300,1), "%02i:%02i" ), "ChessText", w/2, h/4, PanelCol.White, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
|
|
draw.SimpleText( string.FormattedTime( math.Round(self:GetBlackTime() or 300,1), "%02i:%02i" ), "ChessText", w/2, (h/4)+(h/2), PanelCol.Black, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
|
|
end
|
|
|
|
local ButtonPanel = vgui.Create( "DPanel", frame )
|
|
ButtonPanel:SetSize( 100, 20 )
|
|
ButtonPanel:Dock( LEFT )
|
|
ButtonPanel.Paint = function() end
|
|
|
|
local ToMove = vgui.Create( "DPanel", frame )
|
|
ToMove:SetSize(200,80)
|
|
ToMove:Dock( FILL )
|
|
ToMove.Paint = function( s,w,h )
|
|
draw.RoundedBox( 4, 0, 0, w, h, PanelCol.ToMove )
|
|
draw.SimpleText( "To move", "ChessTextSmall", 5, 0, PanelCol.Text )
|
|
local state = IsValid(self) and self:GetChessState()
|
|
if not (IsValid( self ) and state) then
|
|
draw.SimpleText( "[N/A]", "ChessTextSmall", w/2, h/2, PanelCol.Text, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
|
|
else
|
|
local str = (StateToString[state] or "N/A")..( (self:GetPlaying() and self:GetJumpMove() and " (jump)") or "" )
|
|
local col = ((state==CHESS_WHITEMOVE or state==CHESS_WHITEPROMO) and PanelCol.White) or ((state==CHESS_BLACKMOVE or state==CHESS_BLACKPROMO) and PanelCol.Black) or PanelCol.Text
|
|
draw.SimpleText( str, "ChessTextLarge", w/2, h/2, col, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
|
|
end
|
|
end
|
|
|
|
frame.OfferDraw = vgui.Create( "DButton", ButtonPanel)
|
|
frame.OfferDraw:SetSize(94,35)
|
|
frame.OfferDraw:Dock( TOP )
|
|
frame.OfferDraw:SetText( "Offer Draw" )
|
|
frame.OfferDraw.DoClick = function( s )
|
|
if (IsValid(self)) and not (self:GetPlaying()) then
|
|
chat.AddText( Color(150,255,150), "You can't offer a draw before the game starts!" )
|
|
return
|
|
end
|
|
net.Start( "Chess DrawOffer" ) net.SendToServer()
|
|
-- s:SetText( "Draw offered" )
|
|
end
|
|
frame.OfferDraw.Think = function(s)
|
|
if IsValid(self) and self:GetDrawOffer()~=PLAYER_NONE then
|
|
if s.TextChanged then return end
|
|
s.TextChanged = true
|
|
|
|
if LocalPlayer()==self:GetWhitePlayer() then
|
|
if self:GetDrawOffer()==PLAYER_WHITE then
|
|
s:SetText( "Draw Offered" )
|
|
elseif self:GetDrawOffer()==PLAYER_BLACK then
|
|
s:SetText( "Accept Draw Offer" )
|
|
end
|
|
elseif LocalPlayer()==self:GetBlackPlayer() then
|
|
if self:GetDrawOffer()==PLAYER_WHITE then
|
|
s:SetText( "Accept Draw Offer" )
|
|
elseif self:GetDrawOffer()==PLAYER_BLACK then
|
|
s:SetText( "Draw Offered" )
|
|
end
|
|
end
|
|
elseif s.TextChanged then
|
|
s.TextChanged = false
|
|
s:SetText( "Offer Draw" )
|
|
end
|
|
end
|
|
|
|
local Resign = vgui.Create( "DButton", ButtonPanel)
|
|
Resign:SetSize(94,35)
|
|
Resign:Dock( TOP )
|
|
Resign:SetText( "Resign" )
|
|
Resign.DoClick = function( s )
|
|
net.Start( "Chess ClientResign" ) net.SendToServer() --No client-side exit func :/
|
|
end
|
|
|
|
local DermaMode = vgui.Create( "DButton", ButtonPanel)
|
|
DermaMode:SetSize(94,35)
|
|
DermaMode:Dock( TOP )
|
|
DermaMode:SetText( "Toggle 2D Mode" )
|
|
DermaMode.DoClick = function( s )
|
|
if IsValid(Chess_2DDermaPanel) then
|
|
Chess_2DDermaPanel:Remove()
|
|
else
|
|
Chess_Open2DBoard( self )
|
|
end
|
|
end
|
|
|
|
return frame
|
|
end
|
|
end
|