Christmas Event - Santa’s Present Hunt
Bring the magic of Christmas to your server with the Santa’s Present Hunt event script! This fun and festive script lets players go on a scavenger hunt to gather presents scattered around the map. As they collect presents, they contribute to the community goal, unlocking rewards for everyone once the target is met!
Get it here: gamzkystore.com
Support: Discord
Detailed Preview: Youtube
Key Features
Gift Collection: Presents will randomly appear in the world around the player, with adjustable spawn distances from the player, roads, and other presents.
Community Goal: Everyone works together to reach the community-wide goal (Configurable). Players need to collect a set minimum number of gifts to be eligible for the prize.
Anti-Abuse System: Built-in server-side checks detect and block any invalid collection attempts. If abuse is detected, the player is temporarily prevented from contributing to the community goal.
Customizable Settings: Tweak spawn rates, distances, pickup effects, and more to suit your server.
Santa & Blip: Santa Claus is by default located at Legion Square where players can claim their rewards, marked by a blip on the map.
Save System: Progress is saved in JSON format, so no progress gets lost during the event.
Resmon: 0.00ms
How it works
- By default, a max of 3 presents spawn at random spots in a configurable area around the player. (Presents automatically despawn when out of range.)
- Players can pickup presents. As they collect the presents they contribute to the community goal.
- Once the goal is reached and a player has collected the minimum required number of presents, they can visit Santa to claim their reward!
Installation
The script is pretty much drag and drop and works for ESX or QBCore by default. You can easily adapt to other frameworks through the bridge functions. No database tables have to be created.
If you need help setting up and configuring the script, feel free to contact us.
The code snippets below are accessible in the encrypted version:
Config
Config = {
debug = false, -- When enabled, draws a 3D text on the present entities.
communityGoal = 500, -- The amount of presents that need to be collected to reach the community goal.
minimumPresents = 3, -- The minimum amount of presents that a player needs to collect to be able to claim the reward.
rewards = { -- The rewards that can be claimed by players once the community goal is reached.
{ type = 'item', item = 'your_item_here', amount = 1 },
{ type = 'money', amount = 7500 },
},
-- Spawn present settings
presentModel = `xm3_prop_xm3_present_01a`,
spawnRange = 60.0, -- The maximum range from the player where the present can spawn.
maxPresentObjects = 3, -- The maximum amount of present objects that can be spawned at the same time.
distFromPlayer = 15.0, -- Minimum distance from the player.
distFromRoads = 30.0, -- Minimum distance from roads. (To make it harder to find presents in the open. For example on sidewalks)
distBetweenPresents = 30.0, -- Minimum distance between two presents.
ignoredZones = { -- The zone where the presents will not spawn
{ coords = vector3(169.63, -975.51, 29.09), size = 80.0 }, -- Don't spawn near santa ped
},
enableParticles = true, -- Enable particles when a present is picked up.
pickupParticles = { dict = 'scr_indep_fireworks', name = 'scr_indep_firework_shotburst', size = 0.4 },
-- Save data settings
saveInterval = 30, -- Interval in seconds to save the data.
-- Miscellaneous settings
timeBetweenFinds = 5, -- If a player finds multiple presents within this time (in seconds), it will be considered not legit.
overlayUpdateInterval = 5000, -- The interval in milliseconds to update the overlay with the most recent data. (Only works if the overlay is open)
-- Used when there is no target script and the drawtext function is used.
drawText = {
key = 38,
keyLabel = '[~b~E~s~] ',
},
santa = {
blip = {
sprite = 304,
color = 35,
scale = 1.2,
label = 'Santa\'s Present Hunt',
},
ped = {
coords = vector4(169.63, -975.51, 29.09, 135.15),
distance = 7.5,
model = `mp_m_freemode_01`,
componentVariations = {
{ componentId = 11, drawableId = 116, textureId = 0 }, -- Torso
{ componentId = 1, drawableId = 8, textureId = 0 }, -- Mask
{ componentId = 3, drawableId = 14, textureId = 0 }, -- Arms
{ componentId = 4, drawableId = 57, textureId = 0 }, -- Legs
{ componentId = 6, drawableId = 39, textureId = 0 }, -- Shoes
{ componentId = 8, drawableId = 15, textureId = 0 }, -- Shirt
}
}
},
}
Config.Locales = {
['pickup_present'] = 'Pickup present',
['claim_reward'] = 'Claim reward',
['present_picked_up'] = '~g~Present successfully picked up.',
['community_goal_not_reached'] = '~r~The community goal has not been reached yet.',
['not_enough_presents'] = '~r~You do not have enough presents to claim the reward.',
['reward_already_claimed'] = '~r~You have already claimed your reward.',
['reward_claimed'] = '~g~You have claimed your reward.',
}
Accessible Client Bridge Functions
ESX = nil
QBCore = nil
if (GetResourceState('es_extended') == 'started') then
ESX = exports['es_extended']:getSharedObject()
elseif (GetResourceState('qb-core') == 'started') then
QBCore = exports['qb-core']:GetCoreObject()
end
Functions = {}
Functions.Notify = function(message)
if ESX then
ESX.ShowNotification(message, 'info', 5000)
elseif QBCore then
QBCore.Functions.Notify(message, 'primary', 5000)
end
end
-- Used to check if the player can use any of the target interactions
Functions.CanInteract = function()
local playerPed = PlayerPedId()
if IsPedDeadOrDying(playerPed, true) then
return false
end
if IsPedInAnyVehicle(playerPed, false) then
return false
end
return true
end
Functions.AddTarget = function(targetEntity, icon, label, distance, canInteract, onSelect)
if (GetResourceState('ox_target') == 'started') then
exports.ox_target:addLocalEntity(targetEntity, { {
icon = icon,
label = label,
distance = distance,
canInteract = canInteract,
onSelect = onSelect
} })
return
end
-- Fallback in case you don't want to use a target script
AddTextTarget(targetEntity, label, distance, canInteract, onSelect)
end
Accessible Server Bridge Functions
ESX = nil
QBCore = nil
if (GetResourceState('es_extended') == 'started') then
ESX = exports['es_extended']:getSharedObject()
elseif (GetResourceState('qb-core') == 'started') then
QBCore = exports['qb-core']:GetCoreObject()
end
Functions = {}
Functions.GiveReward = function(playerId)
if ESX then
local xPlayer = ESX.GetPlayerFromId(playerId)
for i = 1, #Config.rewards do
local reward = Config.rewards[i]
if reward.type == 'item' then
xPlayer.addInventoryItem(reward.item, reward.amount)
elseif reward.type == 'money' then
xPlayer.addAccountMoney('bank', reward.amount)
end
end
elseif QBCore then
local Player = QBCore.Functions.GetPlayer(playerId)
for i = 1, #Config.rewards do
local reward = Config.rewards[i]
if reward.type == 'item' then
Player.Functions.AddItem(reward.item, reward.amount)
elseif reward.type == 'money' then
Player.Functions.AddMoney('bank', reward.amount)
end
end
end
TriggerClientEvent('gs_presenthunt:Notify', playerId, Config.Locales['reward_claimed'])
end
Functions.GetIdentifier = function(playerId)
if ESX then
local xPlayer = ESX.GetPlayerFromId(playerId)
return xPlayer.identifier
elseif QBCore then
local Player = QBCore.Functions.GetPlayer(playerId)
return Player.PlayerData.citizenid
end
end
-- Don't worry about performance. The names will be cached.
Functions.GetCharacterName = function(identifier)
if ESX then
local character = MySQL.single.await('SELECT `firstname`, `lastname` FROM `users` WHERE `identifier` = ?', { identifier })
return ('%s %s'):format(character.firstname, character.lastname)
elseif QBCore then
local result = MySQL.scalar.await('SELECT `charinfo` FROM `players` WHERE `citizenid` = ?', { identifier })
local charinfo = json_decode(result)
return ('%s %s'):format(charinfo.firstname, charinfo.lastname)
end
end
AddEventHandler('gs_presenthunt:OnPresentFound', function(data)
local playerId = data.playerId
local count = data.count -- The players present count
local totalCount = data.totalCount -- The total amount of presents found across all players
-- For example: Give an extra reward to the player
end)
AddEventHandler('gs_presenthunt:OnSuspiciousActivity', function(data)
local playerId = data.playerId
local reason = data.reason
if (reason == 'too_fast') then
-- Found 2 presents in x seconds
elseif (reason == 'same_location') then
-- Found a present at the same location in 60 seconds
end
end)
Code is accessible | No, but there is an unencrypted version available |
Subscription-based | No |
Lines (approximately) | 1144 |
Requirements | ox_lib |
Support | Yes |