mirror of
https://github.com/ChronosX88/mta-ptp.git
synced 2024-12-27 00:41:47 +00:00
Implement basic team/skin selection and spawning player on team base
This commit is contained in:
commit
a284a69e98
38
.vscode/settings.json
vendored
Normal file
38
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"Lua.diagnostics.globals": [
|
||||
"addEventHandler",
|
||||
"getRootElement",
|
||||
"outputChatBox",
|
||||
"source",
|
||||
"spawnPlayer",
|
||||
"setCameraMatrix",
|
||||
"fadeCamera",
|
||||
"toggleAllControls",
|
||||
"showCursor",
|
||||
"setPlayerHudComponentVisible",
|
||||
"guiGetScreenSize",
|
||||
"root",
|
||||
"dxDrawText",
|
||||
"dxDrawRectangle",
|
||||
"tocolor",
|
||||
"guiCreateLabel",
|
||||
"resourceRoot",
|
||||
"guiGetText",
|
||||
"guiSetAlpha",
|
||||
"bitExtract",
|
||||
"destroyElement",
|
||||
"removeEventHandler",
|
||||
"outputDebugString",
|
||||
"addEvent",
|
||||
"triggerClientEvent",
|
||||
"aclGetGroup",
|
||||
"aclGroupAddObject",
|
||||
"setElementModel",
|
||||
"localPlayer",
|
||||
"bindKey",
|
||||
"setCameraTarget"
|
||||
],
|
||||
"Lua.diagnostics.disable": [
|
||||
"lowercase-global"
|
||||
]
|
||||
}
|
171
client.lua
Normal file
171
client.lua
Normal file
@ -0,0 +1,171 @@
|
||||
local screenW, screenH = guiGetScreenSize()
|
||||
|
||||
SkinSelectionMenu = class(function(menu)
|
||||
menu.isTeamFull = false
|
||||
menu.policeSkins = {280, 281, 282, 283, 284, 285, 288, 265, 266, 267}
|
||||
menu.secretServiceSkins = {163, 164, 165, 166, 194}
|
||||
menu.terroristsSkins = {124, 125, 126, 127, 111, 112}
|
||||
menu._selectSecretService = function()
|
||||
menu.teamSelected = Teams.SECRET_SERVICE
|
||||
setElementModel(localPlayer, menu.secretServiceSkins[1])
|
||||
menu._currentSkinIndex = 1
|
||||
menu._currentSkinArray = menu.secretServiceSkins
|
||||
end
|
||||
menu._selectPolice = function()
|
||||
menu.teamSelected = Teams.POLICE
|
||||
setElementModel(localPlayer, menu.policeSkins[1])
|
||||
menu._currentSkinIndex = 1
|
||||
menu._currentSkinArray = menu.policeSkins
|
||||
end
|
||||
menu._selectTerrorists = function()
|
||||
menu.teamSelected = Teams.TERRORISTS
|
||||
setElementModel(localPlayer, menu.terroristsSkins[1])
|
||||
menu._currentSkinIndex = 1
|
||||
menu._currentSkinArray = menu.terroristsSkins
|
||||
end
|
||||
end)
|
||||
|
||||
function SkinSelectionMenu:showSkinSelectionDxLabels()
|
||||
dxDrawText("Protect The President", (screenW * 0.2870) - 1, (screenH * 0.0528) - 1, (screenW * 0.6734) - 1, (screenH * 0.1176) - 1, tocolor(0, 0, 0, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
dxDrawText("Protect The President", (screenW * 0.2870) + 1, (screenH * 0.0528) - 1, (screenW * 0.6734) + 1, (screenH * 0.1176) - 1, tocolor(0, 0, 0, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
dxDrawText("Protect The President", (screenW * 0.2870) - 1, (screenH * 0.0528) + 1, (screenW * 0.6734) - 1, (screenH * 0.1176) + 1, tocolor(0, 0, 0, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
dxDrawText("Protect The President", (screenW * 0.2870) + 1, (screenH * 0.0528) + 1, (screenW * 0.6734) + 1, (screenH * 0.1176) + 1, tocolor(0, 0, 0, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
dxDrawText("Protect The President", screenW * 0.2870, screenH * 0.0528, screenW * 0.6734, screenH * 0.1176, tocolor(255, 255, 255, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
|
||||
dxDrawText("Select the team:", (screenW * 0.0896) - 1, (screenH * 0.2685) - 1, (screenW * 0.3693) - 1, (screenH * 0.3250) - 1, tocolor(0, 0, 0, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
dxDrawText("Select the team:", (screenW * 0.0896) + 1, (screenH * 0.2685) - 1, (screenW * 0.3693) + 1, (screenH * 0.3250) - 1, tocolor(0, 0, 0, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
dxDrawText("Select the team:", (screenW * 0.0896) - 1, (screenH * 0.2685) + 1, (screenW * 0.3693) - 1, (screenH * 0.3250) + 1, tocolor(0, 0, 0, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
dxDrawText("Select the team:", (screenW * 0.0896) + 1, (screenH * 0.2685) + 1, (screenW * 0.3693) + 1, (screenH * 0.3250) + 1, tocolor(0, 0, 0, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
dxDrawText("Select the team:", screenW * 0.0896, screenH * 0.2685, screenW * 0.3693, screenH * 0.3250, tocolor(255, 255, 255, 255), 2.00, "bankgothic", "left", "top", false, false, false, false, false)
|
||||
|
||||
dxDrawText("You can change skin via left & right arrow buttons. When you are done - click Space", screenW * 0.3089, screenH * 0.8111, screenW * 0.6896, screenH * 0.9185, tocolor(255, 255, 255, 255), 3.00, "arial", "left", "top", false, true, false, false, false)
|
||||
if self.isTeamFull then
|
||||
dxDrawText("Team is full!", (screenW * 0.6896) + 1, (screenH * 0.5630) + 1, (screenW * 0.7984) + 1, (screenH * 0.6139) + 1, tocolor(0, 0, 0, 255), 3.00, "arial", "left", "top", false, false, false, false, false)
|
||||
dxDrawText("Team is full!", screenW * 0.6896, screenH * 0.5630, screenW * 0.7984, screenH * 0.6139, tocolor(241, 6, 0, 254), 3.00, "arial", "left", "top", false, false, false, false, false)
|
||||
end
|
||||
end
|
||||
|
||||
function SkinSelectionMenu:showSkinSelectionButtons()
|
||||
self.secretServiceTeamButton = DxButton(
|
||||
"secret_service",
|
||||
0.0896,
|
||||
0.3574,
|
||||
0.2786,
|
||||
0.0481,
|
||||
tocolor(29, 253, 0, 200),
|
||||
"Secret Service",
|
||||
"pricedown",
|
||||
2.0,
|
||||
tocolor(255, 255, 255, 255),
|
||||
true,
|
||||
self._selectSecretService
|
||||
)
|
||||
|
||||
self.policeTeamButton = DxButton(
|
||||
"police",
|
||||
0.0891,
|
||||
0.4278,
|
||||
0.2792,
|
||||
0.0454,
|
||||
tocolor(0, 23, 252, 200),
|
||||
"Police",
|
||||
"pricedown",
|
||||
2.0,
|
||||
tocolor(255, 255, 255, 255),
|
||||
true,
|
||||
self._selectPolice
|
||||
)
|
||||
|
||||
self.terroristsTeamButton = DxButton(
|
||||
"terrorists",
|
||||
0.0891,
|
||||
0.4917,
|
||||
0.2792,
|
||||
0.0472,
|
||||
tocolor(251, 0, 0, 200),
|
||||
"Terrorists",
|
||||
"pricedown",
|
||||
2.0,
|
||||
tocolor(255, 255, 255, 255),
|
||||
true,
|
||||
self._selectTerrorists
|
||||
)
|
||||
|
||||
self.secretServiceTeamButton:show()
|
||||
self.policeTeamButton:show()
|
||||
self.terroristsTeamButton:show()
|
||||
end
|
||||
|
||||
function SkinSelectionMenu:hideSkinSelectionButtons()
|
||||
self.secretServiceTeamButton:hide()
|
||||
self.policeTeamButton:hide()
|
||||
self.terroristsTeamButton:hide()
|
||||
end
|
||||
|
||||
function SkinSelectionMenu:switchSkin(key)
|
||||
if not self.teamSelected then
|
||||
outputChatBox("Please select the team!")
|
||||
return
|
||||
end
|
||||
if key == "arrow_r" then
|
||||
if self._currentSkinIndex + 1 > #self._currentSkinArray then
|
||||
self._currentSkinIndex = 1
|
||||
setElementModel(localPlayer, self._currentSkinArray[self._currentSkinIndex])
|
||||
return
|
||||
else
|
||||
self._currentSkinIndex = self._currentSkinIndex + 1
|
||||
setElementModel(localPlayer, self._currentSkinArray[self._currentSkinIndex])
|
||||
return
|
||||
end
|
||||
elseif key == "arrow_l" then
|
||||
if self._currentSkinIndex - 1 < 1 then
|
||||
self._currentSkinIndex = #self._currentSkinArray
|
||||
setElementModel(localPlayer, self._currentSkinArray[self._currentSkinIndex])
|
||||
return
|
||||
else
|
||||
self._currentSkinIndex = self._currentSkinIndex - 1
|
||||
setElementModel(localPlayer, self._currentSkinArray[self._currentSkinIndex])
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function selectTeamAndSpawn(team, skin)
|
||||
triggerServerEvent("onPlayerTeamSelected", localPlayer, team, skin)
|
||||
end
|
||||
|
||||
addEventHandler("onClientResourceStart", resourceRoot, function()
|
||||
skinSelectionMenu = SkinSelectionMenu()
|
||||
skinSelectionMenu:showSkinSelectionButtons()
|
||||
skinSelectionMenu._showLabels = function()
|
||||
skinSelectionMenu:showSkinSelectionDxLabels()
|
||||
end
|
||||
skinSelectionMenu._switchSkin = function(key)
|
||||
skinSelectionMenu:switchSkin(key)
|
||||
end
|
||||
bindKey("arrow_l", "down", skinSelectionMenu._switchSkin)
|
||||
bindKey("arrow_r", "down", skinSelectionMenu._switchSkin)
|
||||
addEventHandler("onClientRender", root, skinSelectionMenu._showLabels)
|
||||
function _selectTeamAndSpawn()
|
||||
selectTeamAndSpawn(skinSelectionMenu.teamSelected, skinSelectionMenu._currentSkinArray[skinSelectionMenu._currentSkinIndex])
|
||||
end
|
||||
bindKey("space", "down", _selectTeamAndSpawn)
|
||||
skinSelectionMenu._selectSecretService()
|
||||
end)
|
||||
|
||||
addEvent("onPlayerTeamFull", true)
|
||||
addEventHandler("onPlayerTeamFull", root, function()
|
||||
skinSelectionMenu.isTeamFull = true
|
||||
setTimer(function()
|
||||
skinSelectionMenu.isTeamFull = false
|
||||
end, 2000, 1)
|
||||
end)
|
||||
|
||||
addEvent("onPlayerTeamSelectedSuccessful", true)
|
||||
addEventHandler("onPlayerTeamSelectedSuccessful", root, function()
|
||||
unbindKey("arrow_l", "down", skinSelectionMenu._switchSkin)
|
||||
unbindKey("arrow_r", "down", skinSelectionMenu._switchSkin)
|
||||
unbindKey("space", "down", _selectTeamAndSpawn)
|
||||
removeEventHandler("onClientRender", root, skinSelectionMenu._showLabels)
|
||||
skinSelectionMenu:hideSkinSelectionButtons()
|
||||
end)
|
5
enums.lua
Normal file
5
enums.lua
Normal file
@ -0,0 +1,5 @@
|
||||
Teams = {
|
||||
SECRET_SERVICE = "secret_service",
|
||||
POLICE = "police",
|
||||
TERRORISTS = "terrorists"
|
||||
}
|
63
gui/dxbutton.lua
Normal file
63
gui/dxbutton.lua
Normal file
@ -0,0 +1,63 @@
|
||||
DxButton = class(function(button, button_id, startX, startY, width, height, bgColor, text, textFont, textScale, textColor, textShadowEnabled, onClickHandler)
|
||||
local screenW, screenH = guiGetScreenSize()
|
||||
button.button_id = button_id
|
||||
button.startX = startX * screenW
|
||||
button.startY = startY * screenH
|
||||
button.width = width * screenW
|
||||
button.height = height * screenH
|
||||
button.bgColor = bgColor
|
||||
button.text = text
|
||||
button.textFont = textFont
|
||||
button.textScale = textScale
|
||||
button.textColor = textColor
|
||||
button.textShadowEnabled = textShadowEnabled
|
||||
button.onClickHandler = onClickHandler
|
||||
end)
|
||||
|
||||
function DxButton:show()
|
||||
--self._invisibleLabel = guiCreateLabel(0.09, 0.36, 0.28, 0.05, self.button_id, true)
|
||||
self._invisibleLabel = guiCreateLabel(self.startX, self.startY, self.width, self.height, self.button_id, false)
|
||||
guiSetAlpha(self._invisibleLabel, 0.0)
|
||||
|
||||
self._drawButton = function()
|
||||
dxDrawRectangle(self.startX, self.startY, self.width, self.height, self.bgColor)
|
||||
if self._currentButtonUnderCursor then
|
||||
local red, green, blue, alpha = extractRgbFromColor(self.bgColor)
|
||||
local lightRed, lightGreen, lightBlue = shadeColor(red, green, blue, 20)
|
||||
dxDrawRectangle(self.startX, self.startY, self.width, self.height, tocolor(lightRed, lightGreen, lightBlue, alpha))
|
||||
end
|
||||
if self.textShadowEnabled then
|
||||
dxDrawText(self.text, self.startX + 1, self.startY + 1, self.width + 1, self.height + 1, tocolor(0, 0, 0, 255), self.textScale, self.textFont, "left", "top", false, false, false, false, false)
|
||||
end
|
||||
dxDrawText(self.text, self.startX, self.startY, self.width, self.height, self.textColor, self.textScale, self.textFont, "left", "top", false, false, false, false, false)
|
||||
end
|
||||
|
||||
self._handleMouseOverButton = function()
|
||||
if guiGetText(source) == self.button_id then
|
||||
self._currentButtonUnderCursor = true
|
||||
end
|
||||
end
|
||||
|
||||
self._handleMouseLeaveButtonRectangle = function()
|
||||
self._currentButtonUnderCursor = false
|
||||
end
|
||||
|
||||
self._handleClickOnLabel = function()
|
||||
if guiGetText(source) == self.button_id then
|
||||
self.onClickHandler()
|
||||
end
|
||||
end
|
||||
|
||||
addEventHandler("onClientRender", root, self._drawButton)
|
||||
addEventHandler("onClientMouseEnter", root, self._handleMouseOverButton)
|
||||
addEventHandler("onClientMouseLeave", root, self._handleMouseLeaveButtonRectangle)
|
||||
addEventHandler("onClientGUIClick", root, self._handleClickOnLabel)
|
||||
end
|
||||
|
||||
function DxButton:hide()
|
||||
destroyElement(self._invisibleLabel)
|
||||
removeEventHandler("onClientRender", root, self._drawButton)
|
||||
removeEventHandler("onClientMouseEnter", root, self._handleMouseOverButton)
|
||||
removeEventHandler("onClientMouseLeave", root, self._handleMouseLeaveButtonRectangle)
|
||||
removeEventHandler("onClientGUIClick", root, self._handleClickOnLabel)
|
||||
end
|
11
meta.xml
Normal file
11
meta.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<meta>
|
||||
<info author="ChronosX88" type="gamemode" name="PTP" description="Classic Protect The President Mode" />
|
||||
<script src="util\class.lua" type="shared"/>
|
||||
<script src="util\color.lua" type="shared"/>
|
||||
<script src="enums.lua" type="shared"/>
|
||||
<script src="team.lua" type="shared"/>
|
||||
<script src="server.lua" type="server"/>
|
||||
<script src="client.lua" type="client"/>
|
||||
<script src="gui\dxbutton.lua" type="client"/>
|
||||
<oop>true</oop>
|
||||
</meta>
|
43
server.lua
Normal file
43
server.lua
Normal file
@ -0,0 +1,43 @@
|
||||
local teams = {}
|
||||
|
||||
local function mainOnPlayerJoin()
|
||||
setCameraMatrix(source, 1654.3691, -1643.5967, 85.176224, 1658.8364, -1545.6569, 65.482597)
|
||||
spawnPlayer(source, 1654.524, -1637.7119, 85.157089, 180.0, 0)
|
||||
toggleAllControls(source, false, true, false)
|
||||
setPlayerHudComponentVisible(source, "all", false)
|
||||
fadeCamera(source, true, 5)
|
||||
showCursor(source, true)
|
||||
outputChatBox("Please select the class and skin of your player", source, 255, 255, 0)
|
||||
end
|
||||
|
||||
local function spawnPlayerOnTeamBase(player, x, y, z, rotation, skinID)
|
||||
showCursor(player, false)
|
||||
spawnPlayer(player, x, y, z, rotation, skinID)
|
||||
setCameraTarget(player)
|
||||
fadeCamera(source, true)
|
||||
setPlayerHudComponentVisible(player, "all", true)
|
||||
toggleAllControls(player, true, true, true)
|
||||
end
|
||||
|
||||
local function mainOnPlayerTeamSelected(team, skinID)
|
||||
if type(team) ~= "string" or type(skinID) ~= "number" then
|
||||
outputDebugString("OnPlayerTeamSelected: Invalid argument type")
|
||||
end
|
||||
if team == Teams.SECRET_SERVICE then
|
||||
spawnPlayerOnTeamBase(source, 2795.0, -1825.0, 9.9, 90, skinID)
|
||||
elseif team == Teams.POLICE then
|
||||
spawnPlayerOnTeamBase(source, 1532.6, -1677.3, 5.9, 90, skinID)
|
||||
elseif team == Teams.TERRORISTS then
|
||||
spawnPlayerOnTeamBase(source, 1774.0, -1926.5, 13.5, 90, skinID)
|
||||
end
|
||||
triggerClientEvent(source, "onPlayerTeamSelectedSuccessful", resourceRoot)
|
||||
end
|
||||
|
||||
addEvent("onPlayerTeamSelected", true)
|
||||
addEventHandler("onPlayerTeamSelected", root, mainOnPlayerTeamSelected)
|
||||
addEventHandler("onPlayerJoin", root, mainOnPlayerJoin)
|
||||
addEventHandler("onResourceStart", root, function()
|
||||
teams[Teams.SECRET_SERVICE] = Team(Teams.SECRET_SERVICE, "Secret Service", tocolor(29, 253, 0, 255))
|
||||
teams[Teams.POLICE] = Team(Teams.POLICE, "Police", tocolor(0, 23, 252, 55))
|
||||
teams[Teams.TERRORISTS] = Team(Teams.TERRORISTS, "Terrorists", tocolor(251, 0, 0, 200))
|
||||
end)
|
6
team.lua
Normal file
6
team.lua
Normal file
@ -0,0 +1,6 @@
|
||||
Team = class(function(team, teamID, teamName, teamColor)
|
||||
team.teamID = teamID
|
||||
team.teamName = teamName
|
||||
team.teamColor = teamColor
|
||||
team.playersCount = 0
|
||||
end)
|
43
util/class.lua
Normal file
43
util/class.lua
Normal file
@ -0,0 +1,43 @@
|
||||
function class(base, init)
|
||||
local c = {} -- a new class instance
|
||||
if not init and type(base) == 'function' then
|
||||
init = base
|
||||
base = nil
|
||||
elseif type(base) == 'table' then
|
||||
-- our new class is a shallow copy of the base class!
|
||||
for i,v in pairs(base) do
|
||||
c[i] = v
|
||||
end
|
||||
c._base = base
|
||||
end
|
||||
-- the class will be the metatable for all its objects,
|
||||
-- and they will look up their methods in it.
|
||||
c.__index = c
|
||||
|
||||
-- expose a constructor which can be called by <classname>(<args>)
|
||||
local mt = {}
|
||||
mt.__call = function(class_tbl, ...)
|
||||
local obj = {}
|
||||
setmetatable(obj, c)
|
||||
if init then
|
||||
init(obj, ...)
|
||||
else
|
||||
-- make sure that any stuff from the base class is initialized!
|
||||
if base and base.init then
|
||||
base.init(obj, ...)
|
||||
end
|
||||
end
|
||||
return obj
|
||||
end
|
||||
c.init = init
|
||||
c.is_a = function(self, klass)
|
||||
local m = getmetatable(self)
|
||||
while m do
|
||||
if m == klass then return true end
|
||||
m = m._base
|
||||
end
|
||||
return false
|
||||
end
|
||||
setmetatable(c, mt)
|
||||
return c
|
||||
end
|
44
util/color.lua
Normal file
44
util/color.lua
Normal file
@ -0,0 +1,44 @@
|
||||
function roundNumber(number)
|
||||
local _, decimals = math.modf(number)
|
||||
if decimals < 0.5 then return math.floor(number) end
|
||||
return math.ceil(number)
|
||||
end
|
||||
|
||||
function shadeColor(red, green, blue, percent)
|
||||
--[[red = (red * (100 + percent) / 100)
|
||||
green = (green * (100 + percent) / 100)
|
||||
blue = (blue * (100 + percent) / 100)]]
|
||||
|
||||
--percent = percent / 100
|
||||
-- //FIXME don't work properly
|
||||
red = red + (255 - red) * percent
|
||||
green = green + (255 - green) * percent
|
||||
blue = blue + (255 - blue) * percent
|
||||
|
||||
if red > 255 then
|
||||
red = 255
|
||||
end
|
||||
|
||||
if green > 255 then
|
||||
green = 255
|
||||
end
|
||||
|
||||
if blue > 255 then
|
||||
blue = 255
|
||||
end
|
||||
|
||||
red = roundNumber(red)
|
||||
blue = roundNumber(blue)
|
||||
green = roundNumber(green)
|
||||
|
||||
return red, green, blue
|
||||
end
|
||||
|
||||
function extractRgbFromColor(color)
|
||||
local red = bitExtract(color, 0, 8)
|
||||
local green = bitExtract(color, 8, 8)
|
||||
local blue = bitExtract(color, 16, 8)
|
||||
local alpha = bitExtract(color, 24, 8)
|
||||
|
||||
return red, green, blue, alpha
|
||||
end
|
Loading…
Reference in New Issue
Block a user