Initial commit

This commit is contained in:
2020-12-19 12:59:49 +01:00
parent e35a212e4f
commit fc0e6ad84f
9 changed files with 659 additions and 0 deletions

173
c_script.lua Normal file
View File

@@ -0,0 +1,173 @@
local total
local rank = 0
local start
local sx, sy = GuiElement.getScreenSize()
local alpha
local leaders
local length,lowerLimit, upperLimit = 0,0,0
local removeTimer
addEventHandler('onClientResourceStart', resourceRoot,
function()
local txd = EngineTXD('model.txd', true)
txd:import(1974)
local dff = EngineDFF('model.dff', 0)
dff:replace(1974)
local col = EngineCOL('model.col')
col:replace(1974)
end
)
addEvent("showTotal", true)
addEventHandler("showTotal", root,
function (prez)
total = prez
start = getTickCount()
if prez == 1 then
alpha = 255
removeEventHandler("onClientRender", root, intro)
addEventHandler("onClientRender", root, intro)
else
removeEventHandler("onClientRender", root, drawTotal)
addEventHandler("onClientRender", root, drawTotal)
end
end)
function drawTotal()
local now = getTickCount()
if now - start > 5000 then
removeEventHandler("onClientRender", root, drawTotal)
end
dxDrawText("You have " ..total.. " presents", 0, sy-30, sx, sy, tocolor(255,255,255,255), 1.3, "default-bold", "center", "center", false, false, false, true)
end
function intro()
local now = getTickCount()
if now - start > 15000 then
if alpha < 10 then
removeEventHandler("onClientRender", root, intro)
else
alpha = alpha - 10
end
end
dxDrawText("Welcome to the SKC Christmas Event!", 0, sy-300, sx+1, sy+1, tocolor(0,0,0,alpha), 2, "default-bold", "center", "center", false, false, false, true)
dxDrawText("Welcome to the #ff8000SKC Christmas Event!", 0, sy-300, sx, sy, tocolor(255,255,255,alpha), 2, "default-bold", "center", "center", false, false, false, true)
dxDrawText("Collect as many presents as you can.", 0, sy-220, sx+1, sy+1, tocolor(0,0,0,alpha), 1.6, "default-bold", "center", "center", false, false, false, true)
dxDrawText("Collect as many presents as you can.", 0, sy-220, sx, sy, tocolor(255,255,255,alpha), 1.6, "default-bold", "center", "center", false, false, false, true)
end
function drawLeaders()
local offsetX_SKC = 400
dxDrawRectangle(sx-200-offsetX_SKC, 10, length, 35, tocolor(0,0,0,220))
if length >= 190 then
dxDrawText("Christmas Event Leaders", sx-200-offsetX_SKC, 20, sx-10-offsetX_SKC, 40, tocolor(255,255,255,255), 1, "default-bold", "center")
for i, v in ipairs(leaders) do
if i > lowerLimit and i <= upperLimit then
if i == rank then
dxDrawRectangle(sx-170-offsetX_SKC, 24+(28*(i-lowerLimit)), 160, 28, tocolor(100,100,100,155))
else
dxDrawRectangle(sx-170-offsetX_SKC, 24+(28*(i-lowerLimit)), 160, 28, tocolor(0,0,0,155))
end
dxDrawRectangle(sx-200-offsetX_SKC, 24+(28*(i-lowerLimit)), 30, 28, tocolor(0,0,0,220))
if i < 6 then
dxDrawText(i, sx-200-offsetX_SKC, 30+(28*(i-lowerLimit)), sx-170-offsetX_SKC, 30+(30*(i-lowerLimit)), tocolor(255,255,0+((i-1)*50),255), 1, "default-bold", "center")
else
dxDrawText(i, sx-200-offsetX_SKC, 30+(28*(i-lowerLimit)), sx-170-offsetX_SKC, 30+(30*(i-lowerLimit)), tocolor(255,255,255,255), 1, "default-bold", "center")
end
dxDrawText(v[1], sx-160-offsetX_SKC, 30+(28*(i-lowerLimit)), sx-10-offsetX_SKC, 30+(30*(i-lowerLimit)), tocolor(255,255,255,255), 1, "default-bold", "left", "top", false, false, false, true)
dxDrawText(v[2], sx-31-offsetX_SKC, 30+(28*(i-lowerLimit)), sx-15-offsetX_SKC, 30+(30*(i-lowerLimit)), tocolor(255,0,0,255), 1, "default-bold", "right", "top")
if i > upperLimit then
break --don't carry on looping, this helps performance quite a bit
end
end
end
if rank > upperLimit and upperLimit > 0 then
dxDrawRectangle(sx-170-offsetX_SKC, 61+(28*(upperLimit-lowerLimit)), 160, 28, tocolor(0,0,0,155))
dxDrawRectangle(sx-200-offsetX_SKC, 61+(28*(upperLimit-lowerLimit)), 30, 28, tocolor(0,0,0,220))
dxDrawText(rank, sx-200-offsetX_SKC, 67+(28*(upperLimit-lowerLimit)), sx-170-offsetX_SKC, 100+(28*(upperLimit-lowerLimit)), tocolor(255,255,255,255), 1, "default-bold", "center")
dxDrawText(leaders[rank][1], sx-160-offsetX_SKC, 67+(28*(upperLimit-lowerLimit)), sx-10-offsetX_SKC, 100+(28*(upperLimit-lowerLimit)), tocolor(255,255,255,255), 1, "default-bold", "left", "top", false, false, false, true)
dxDrawText(leaders[rank][2], sx-31-offsetX_SKC, 67+(28*(upperLimit-lowerLimit)), sx-15-offsetX_SKC, 100+(28*(upperLimit-lowerLimit)), tocolor(255,0,0,255), 1, "default-bold", "right", "top")
end
if upperLimit == 0 then
dxDrawRectangle(sx-200-offsetX_SKC, 45, length, 25, tocolor(0,0,0,220))
dxDrawText("Mouse wheel to show", sx-200-offsetX_SKC, 45, sx-10-offsetX_SKC, 60, tocolor(255,255,255,255), 0.85, "default-bold", "center")
end
else
length = length + 5
end
end
addEvent("updateTables", true)
addEventHandler("updateTables", root,
function (data)
leaders = data
if removeTimer and removeTimer.valid then
removeTimer:reset()
elseif upperLimit == 0 then
removeTimer = Timer(removeLeaders, 15000, 1)
end
removeEventHandler("onClientRender", root, drawLeaders)
removeEventHandler("onClientRender", root, boom)
addEventHandler("onClientRender", root, drawLeaders)
local name = localPlayer.name
for i, v in ipairs(leaders) do
if v[1] == name then
rank = i
end
end
if length == 0 then
bindKey("mouse_wheel_up", "down", moveLimits)
bindKey("mouse_wheel_down", "down", moveLimits)
end
end)
function removeLeaders()
addEventHandler("onClientRender", root, boom)
end
function boom()
if length < 10 then
unbindKey("mouse_wheel_up", "down", moveLimits)
unbindKey("mouse_wheel_down", "down", moveLimits)
removeEventHandler("onClientRender", root, drawLeaders)
removeEventHandler("onClientRender", root, boom)
length = 0
else
length = length - 10
end
end
function moveLimits(button)
if length < 190 then return end
if button == "mouse_wheel_up" then
if lowerLimit > 0 then
upperLimit = upperLimit - 1
lowerLimit = lowerLimit - 1
elseif lowerLimit == 0 and upperLimit == 5 then
upperLimit = 0
removeTimer = Timer(removeLeaders, 15000, 1)
elseif upperLimit ~= 0 then
lowerLimit = 0
upperLimit = 5
end
elseif button == "mouse_wheel_down" then
if upperLimit < #leaders then
if upperLimit == 0 then
triggerServerEvent("statsForPoon", localPlayer)
if removeTimer and removeTimer.valid then
removeTimer:destroy()
end
upperLimit = 5
elseif upperLimit < 10 then
upperLimit = 10
else
upperLimit = upperLimit + 1
lowerLimit = lowerLimit + 1
end
end
end
end

81
meta.xml Normal file
View File

@@ -0,0 +1,81 @@
<meta>
<oop>true</oop>
<info name="xmas" author="Driggero and Greenlander" description="Xmas presents for DD and DM" type="script" version="2.0" addon="race"/>
<script src="c_script.lua" type="client" />
<script src="s_utils.lua" type="server" />
<script src="s_script.lua" type="server" />
<script src="s_commands.lua" type="server" />
<script src="s_events.lua" type="server" />
<file src="model.dff" />
<file src="model.col" />
<file src="model.txd" />
<settings>
<setting name="*gamemode" value="DM"
friendlyname="Gamemode"
accept="DD,DM"
group="Gamemode"
desc="Switch between DD and DM gamemode depending on server."
/>
<setting name="*minplayers" value="3"
friendlyname="Min player count"
accept="1-5"
group="Gameplay"
desc="Presents will only spawn with at least this amount of players online."
/>
<setting name="*giftfactor" value="1"
friendlyname="Presents score multiplicator"
accept="1-10"
group="Gameplay"
desc="Determines how valuable the presents are. (NOT USED ATM!)"
/>
<setting name="*spawnprobability" value="10"
friendlyname="Probability threshold of spwaning presents"
accept="0-50"
group="Gameplay"
desc="Determines the probability threashold of spawning a present on parts of the track (in %)."
/>
<setting name="*minplayers" value="3"
friendlyname="Min player count"
accept="1-5"
group="Gameplay"
desc="Presents will only spawn with at least this amount of players online."
/>
<setting name="*eventstart" value="18"
friendlyname="Starting hour of the event"
accept="0-23"
group="Event"
desc="Sets the hour of the days when the event will start."
/>
<setting name="*eventduration" value="2"
friendlyname="Duration of the event"
accept="1-24"
group="Event"
desc="Sets the duration for the event [in hours]."
/>
<setting name="*endmonth" value="1"
friendlyname="Ending month"
accept="1-12"
group="End date"
desc="Sets the month when the event will end automatically."
/>
<setting name="*endday" value="1"
friendlyname="Ending day"
accept="1-31"
group="End date"
desc="Sets the day when the event will end automatically."
/>
<setting name="*endhour" value="0"
friendlyname="Ending hour"
accept="0-23"
group="End date"
desc="Sets the hour when the event will end automatically."
/>
<setting name="*endminute" value="0"
friendlyname="Ending minute"
accept="0-59"
group="End date"
desc="Sets the minute when the event will end automatically."
/>
</settings>
</meta>

BIN
model.col Normal file

Binary file not shown.

BIN
model.dff Normal file

Binary file not shown.

BIN
model.txd Normal file

Binary file not shown.

22
s_commands.lua Normal file
View File

@@ -0,0 +1,22 @@
addCommandHandler("xmas",
function(player, arg1, arg2)
local accName = getAccountName ( getPlayerAccount ( player ) )
local isAdmin = isObjectInACLGroup ("user."..accName, aclGetGroup ( "Admin" )) or isObjectInACLGroup ("user."..accName, aclGetGroup ( "Administrator" ))
if arg2 == "update" then
updateTop(player)
elseif arg2 == "clearstats" then
if accName ~= "Greenlander" then return end
if isAdmin then
outputDebugString('[xmas]: Clearing the Xmas presents account stats.')
executeSQLQuery("DELETE FROM `xmas`")
g_data["leaders"] = {}
updateTop()
end
elseif arg2 == "top" then
if (isAdmin) then
updateTop()
showTop()
end
end
end)

91
s_events.lua Normal file
View File

@@ -0,0 +1,91 @@
addEvent ( "onSettingChange" )
addEventHandler('onSettingChange', getResourceRootElement(),
function(name, oldvalue, value, player)
cacheGameOptions()
checkTime()
end
)
addEventHandler("onResourceStart", resourceRoot,
function ()
math.randomseed(os.time())
cacheGameOptions()
checkTime()
executeSQLQuery("CREATE TABLE IF NOT EXISTS `xmas` (`account` TEXT, `name` TEXT, `presents` INTEGER)")
end)
addEvent("statsForPoon", true)
addEventHandler("statsForPoon", root,
function()
if source.type ~= "player" then return end
outputDebugString(source.name .. " checked the scoreboard")
end)
addEvent("onRaceStateChanging")
addEventHandler("onRaceStateChanging", root,
function(new, old)
if new == "PreGridCountdown" then
if g_data["finished"] then outputDebugString("[xmas]: Competition over, not generating presents") return end
if g_data["event"] == false then return end
setTimer(function() spawnPresents() end, 1500, 1)
elseif new == "GridCountdown" then
if g_data["event"] == false then return end
updateTop()
elseif new == "LoadingMap" then
for i, v in ipairs(g_data["presents"]) do
v[1]:destroy()
v[2]:destroy()
end
g_data["presents"] = {}
end
end)
addEventHandler ( "onColShapeHit", root,
function (player)
if player.type ~= "player" then return end
for i, v in ipairs(g_data["presents"]) do
if source == v[2] then
local acc = player.account
local accName = acc.name
--local acc = getPlayerAccount(player)
--local accName = getAccountName(acc)
if acc.guest then
outputChatBox("* #ffffffPlease #ff8000login#ffffff to join the Christmas Competition", player, 255,0,0,true)
else
v[1]:destroy()
v[2]:destroy()
v[1], v[2] = nil, nil
table.remove(g_data["presents"], i)
local result = executeSQLQuery("SELECT `name`, `presents` FROM `xmas` WHERE LOWER(`account`)=?", string.lower(accName))
if result == false or #result == 0 then
executeSQLQuery("INSERT INTO `xmas`(`account`,`name`,`presents`) VALUES(?,?,?)", accName, player.name, 0)
result = executeSQLQuery("SELECT `name`, `presents` FROM `xmas` WHERE LOWER(`account`)=?", string.lower(accName))
end
local prez = result[1].presents
local name = result[1].name
if not name or name ~= player.name then
executeSQLQuery("UPDATE `xmas` SET `name`=? WHERE LOWER(`account`)=?", player.name, string.lower(accName))
end
prez = prez + 1
executeSQLQuery("UPDATE `xmas` SET `presents`=? WHERE LOWER(`account`)=?", prez, string.lower(accName))
triggerClientEvent(player, "showTotal", resourceRoot, prez)
local randomScore = math.random(1, 4)*g_data["gameOptions"].giftfactor
--addPoints(randomScore, player)
--[[if randomScore > 1 then
outputChatBox("* #ffffffYou recieved #ff0000" .. randomScore .. "#ffffff points from this present", player, 255,0,0,true)
else
outputChatBox("* #ffffffYou recieved #ff0000" .. randomScore .. "#ffffff point from this present", player, 255,0,0,true)
end]]
outputChatBox("* #ffffff" .. player.name .. "#ffffff found a present! [" .. #g_data["presents"] .. " left]", root,255,0,0,true)
end
end
end
end)

192
s_script.lua Normal file
View File

@@ -0,0 +1,192 @@
g_data = {}
g_data["presents"] = {}
g_data["leaders"] = {}
g_data["gameOptions"] = {}
g_data["finished"] = false
g_data["event"] = false
g_data["validObjects"] = {}
function cacheGameOptions()
g_data["gameOptions"] = {}
g_data["gameOptions"].gamemode = getString('gamemode','DM')
g_data["gameOptions"].minplayers = getNumber('minplayers',3)
g_data["gameOptions"].giftfactor = getNumber('giftfactor',1)
g_data["gameOptions"].spawnprobability = getNumber('spawnprobability',10)
g_data["gameOptions"].eventstart = getNumber('eventstart',18)
g_data["gameOptions"].eventduration = getNumber('eventduration',2)
g_data["gameOptions"].endmonth = getNumber('endmonth',1)
g_data["gameOptions"].endday = getNumber('endday',1)
g_data["gameOptions"].endhour = getNumber('endhour',0)
g_data["gameOptions"].endminute = getNumber('endminute',0)
if g_data["gameOptions"].gamemode == 'DM' then
g_data["validObjects"] = {
[3458]=true,
[8558]=true,
[8838]=true,
[8947]=true,
[6959]=true,
[18450]=true,
[7657]=true,
[9623]=true}
elseif g_data["gameOptions"].gamemode == 'DD' then
g_data["validObjects"] = {
[3458]=true,
[8558]=true,
[8838]=true,
[3095]=true,
[13649]=true,
[1482]=true,
[12857]=true}
end
end
function spawnPresents()
local playerCount = #Element.getAllByType("player")
local probability
if playerCount < g_data["gameOptions"].minplayers then
outputDebugString("[xmas]: No presents this time. Not enough players.")
return
else
probability = math.random(0, g_data["gameOptions"].spawnprobability)
end
local objects = {}
for index, object in pairs(Element.getAllByType("object")) do
if g_data["validObjects"][object.model] then
if isElementVisible(object) then
if isElementFlat(object) then --only use flat objects
table.insert(objects, object)
end
end
end
end
outputDebugString("[xmas]: " .. #objects .. " possible places with " .. probability .. "% chance.")
local count = 0
for i=1, math.floor(#objects*(probability/100)) do
-- limit amount of presents spawned based on playercount
if count > (playerCount*2) then
break
end
-- get random object from table
local index = math.random(#objects)
local object = objects[index]
-- model specific offsets with randomness in present placement
local offset = getModelOffset(object)
-- spawn present and create colsphere for hit detection
local v = object.position
local o = Object(1974, v.x+offset.x, v.y+offset.y, v.z+offset.z, 0,0,0,true)
o:setCollisionsEnabled(false)
local c = ColShape.Sphere(v.x+offset.x, v.y+offset.y, v.z+offset.z, 3.0)
table.insert(g_data["presents"], {o, c})
count = count + 1
-- remove object from list
table.remove(objects, index)
end
if #g_data["presents"] == 0 then
outputChatBox("* #ffffff"..#g_data["presents"] .. " presents spawned on the map. Blame Ryan... #ff0000*", root,255,0,0,true)
else
outputChatBox("* #ffffff"..#g_data["presents"] .. " presents spawned on the map. Try to find them all #ff0000*", root,255,0,0,true)
end
outputDebugString("[xmas]: " .. #g_data["presents"] .. " presents spawned.")
end
function rotatePresents()
for i, v in ipairs(g_data["presents"]) do
local pos = v[1].position
moveObject(v[1], 5000, pos.x, pos.y, pos.z, 0, 0, 360)
end
end
setTimer(rotatePresents, 5000, 0)
function addPoints(pts, player)
--SKC specific!!! Just tested for DD
--[[local result = executeSQLQuery( "SELECT score FROM stats WHERE LOWER(nick)=?" , string.lower(getAccountName(getPlayerAccount(player))) )
if result == false or #result == 0 then return end
local pts_before = result[1]["score"]
executeSQLQuery( "UPDATE stats SET score=? WHERE LOWER(nick)=?", pts_before+pts, string.lower(getAccountName(getPlayerAccount(player))) )
exports.dd_player_stats:updatePlayerVisualPoints(player)]]
end
function checkTime()
local t = getRealTime()
local hour = t.hour
local minute = t.minute
local day = t.monthday
local month = t.month
outputDebugString("[xmas]: "..month..' - '..day..' - '..hour..':'..minute)
-- check if competition ended
if month == (g_data["gameOptions"].endmonth-1) then
if day >= g_data["gameOptions"].endday then
if hour >= g_data["gameOptions"].endhour then
if minute >= g_data["gameOptions"].endminute and not g_data["finished"] then
outputChatBox("* #ffffffThe Christmas Competition has now ended! Thanks to all those who took part #ff0000*", root, 255,0,0, true)
--outputChatBox("* #ffffffThe Top 5 will be contacted shortly about the prizes #ff0000*", root, 255,0,0, true)
g_data["finished"] = true
end
end
end
end
-- check if it's event time
if hour >= g_data["gameOptions"].eventstart and hour < (g_data["gameOptions"].eventstart+g_data["gameOptions"].eventduration) then
if g_data["event"] == false then
outputDebugString("[xmas]: Event started.")
outputChatBox("* #ffffffThe Christmas Competition has started for "..g_data["gameOptions"].eventduration.." hours. Collect as many presents as possible #ff0000*", root, 255,0,0, true)
end
g_data["event"] = true
else
if g_data["event"] then
outputDebugString("[xmas]: Event ended.")
outputChatBox("* #ffffffThe Christmas Competition has ended for today. #ff0000*", root, 255,0,0, true)
end
g_data["event"] = false
end
-- check if it's about to be event time
if hour == (g_data["gameOptions"].eventstart-1) and minute == 55 then
outputChatBox("* #ffffffThe Christmas Competition will start in 5 minutes #ff0000*", root, 255,0,0, true)
end
end
setTimer(checkTime, 50000, 0)
function updateTop(player)
if player then
outputChatBox(" * #ffffff" ..player.name.. "#ffffff updated the top 3", root,255,0,0,true)
end
g_data["leaders"] = {}
local result = executeSQLQuery([[
SELECT `name`, `presents`
FROM `xmas`
WHERE `presents`>0
ORDER BY `presents` DESC
LIMIT 10]])
for i,v in ipairs(result) do
local prez = v.presents
local name = v.name
table.insert(g_data["leaders"], {name, prez})
end
triggerClientEvent("updateTables", resourceRoot, g_data["leaders"])
end
function showTop()
outputChatBox("** #ffffffChristmas Event Top 3 #ff0000**", root, 255,0,0,true)
outputChatBox(" ")
for i, v in ipairs(g_data["leaders"]) do
if v[1] and i < 11 then
outputChatBox(i .. ". #ffffff" .. v[1] .. " - #ff0000" ..v[2], root, 255,0,0,true)
end
end
outputChatBox("** #ffffffEnds 1st January 2021 #ff0000**", root, 255,0,0,true)
end

100
s_utils.lua Normal file
View File

@@ -0,0 +1,100 @@
-- get string or default
function getString(var,default)
local result = get(var)
if not result then
return default
end
return tostring(result)
end
-- get number or default
function getNumber(var,default)
local result = get(var)
if not result then
return default
end
return tonumber(result)
end
-- get true or false or default
function getBool(var,default)
local result = get(var)
if not result then
return default
end
return result == 'true'
end
function isElementVisible(e)
local res = false
if e.interior == 0 and e.dimension == 0 and e.alpha == 255 and e.scale == 1.0 then
res = true
end
return res
end
function isElementFlat(e)
local ret = false
local tol = 0.1
if not e then return ret end
local v = e.rotation
if e.model == 7657 then
if (v.x < 270+tol and v.x > 270-tol) and (v.y < tol and v.y > -tol) then
ret = true
end
else
if (v.y < tol and v.y > -tol) and (v.x < tol and v.x > -tol) then
ret = true
end
end
return ret
end
function getModelOffset(m)
local offset = Vector3(0.0, 0.0, 0.0)
local randX, randY = 0.0, 0.0
if m.model == 3458 or m.model == 8558 or m.model == 8838 then
randX = math.random(-9,9) + math.random()
randY = math.random(-1,1) + math.random()
offset.z = 1.6
elseif m.model == 8947 then
randX = math.random(-2,2) + math.random()
randY = math.random(-6,6) + math.random()
offset.z = 3.25
elseif m.model == 6959 then
randX = math.random(-7,7) + math.random()
randY = math.random(-7,7) + math.random()
elseif m.model == 18450 then
randX = math.random(-24,24) + math.random()
randY = math.random(-4,4) + math.random()
offset.z = 0.5
elseif m.model == 7657 then
randX = math.random(-4,4) + math.random()
randY = math.random()
offset.z = 0.15
elseif m.model == 9623 then
randX = math.random(-9,9) + math.random()
randY = math.random(-2,2) + math.random()
offset.z = 3.0
elseif m.model == 13649 then
offset.z = 0.7
elseif m.model == 3095 then
randX = math.random(-2,2) + math.random()
randY = math.random(-2,2) + math.random()
offset.z = 0.6
elseif m.model == 1482 then
randX = math.random()
randY = math.random(-2,2) + math.random()
offset.z = 1.5
elseif m.model == 12857 then
randX = math.random(-3,3) + math.random()
randY = math.random(-17,17) + math.random()
offset.z = 2.6
end
offset.x = math.cos(math.rad(m.rotation.z))*randX + math.sin(math.rad(m.rotation.z))*randY
offset.y = math.sin(math.rad(m.rotation.z))*randX - math.cos(math.rad(m.rotation.z))*randY
return offset
end