From 69c90069a152213914abdf7a61febe10d0cf094f Mon Sep 17 00:00:00 2001 From: Jayefuu Date: Wed, 30 Mar 2022 19:36:18 +0100 Subject: [PATCH] Updated donor features (#1262) - Team buffs for donators with tier 2 or higher Patreon status - Tier 2 (coal): +10% team hand mining bonus per online donator, up to a maximum of 10 online donators - Tier 3 (solid fuel): +10% team hand crafting bonus per online donator, up to a max of 10 online donators - Tier 4 (rocket fuel): +10% team run speed per online donator, up to a max of 10 online donators - Tier 5 (nuclear fuel): +5 inventory slots for all. Up to max of 30 extra. Does not reduce down when donator logs off. --- config.lua | 5 + features/donator.lua | 224 ++++++++++++++++++++++++++---- features/donator_commands.lua | 40 ++++++ locale/en/redmew_command_text.cfg | 2 +- resources/donator_perks.lua | 18 ++- 5 files changed, 259 insertions(+), 30 deletions(-) diff --git a/config.lua b/config.lua index 5803160f..798e1f52 100644 --- a/config.lua +++ b/config.lua @@ -436,6 +436,11 @@ global.config = { }, spidertron_group_control = { enabled = true + }, + donator = { + donator_perks = { + enabled = true + } } } diff --git a/features/donator.lua b/features/donator.lua index 56c2557a..05491fb7 100644 --- a/features/donator.lua +++ b/features/donator.lua @@ -6,27 +6,62 @@ local Token = require 'utils.token' local table = require 'utils.table' local Global = require 'utils.global' local Task = require 'utils.task' +local DonatorPerks = require 'resources.donator_perks' local concat = table.concat local remove = table.remove local set_data = Server.set_data local random = math.random +local config = global.config.donator local donator_data_set = 'donators' - local donators = {} -- global register +local donator_perks_perm = {} -- buffs to the force that will remain even when the donator is offline (T5) +local donator_perks_temp = {} -- buffs to the force that are only applied while the donator is online (T2, T3, T4) +local donator_tiers = { + [1] = {name = "[img=item.wood]", count = 0, max = 10}, -- keeps track of how many have been applied so we can limit the amount of donators contributing to buffs + [2] = {name = "[img=item.coal]", count = 0, max = 10}, + [3] = {name = "[img=item.solid-fuel]", count = 0, max = 10}, + [4] = {name = "[img=item.rocket-fuel]", count = 0, max = 10}, + [5] = {name = "[img=item.nuclear-fuel]", count = 0, max = 6} + } Global.register( { - donators = donators + donators = donators, + donator_perks_perm = donator_perks_perm, + donator_perks_temp = donator_perks_temp, + donator_tiers = donator_tiers }, function(tbl) donators = tbl.donators + donator_perks_perm = tbl.donator_perks_perm + donator_perks_temp = tbl.donator_perks_temp + donator_tiers = tbl.donator_tiers + config = tbl.global.config.donator.donator_perks end ) local Public = {} +--- Checks if a player has a specific donator perk +-- @param player_name +-- @param perf_flag +-- @return +function Public.player_has_donator_perk(player_name, perk_flag) + local d = donators[player_name] + if not d then + return false + end + + local flags = d.perk_flags + if not flags then + return false + end + + return bit32.band(flags, perk_flag) == perk_flag +end + --- Prints the donator message with the color returned from the server local print_after_timeout = Token.register( @@ -40,6 +75,18 @@ local print_after_timeout = end ) +-- Just in case we want to turn it off mid-game, we can use /sc package.loaded['features.donator'].toggle_perks() +function Public.toggle_perks() + config.donator_perks.enabled = not config.donator_perks.enabled + if config.donator_perks.enabled == true then + game.print("Donator perks now enabled") + print("Donator perks now enabled") -- prints to server console + else + game.print("Donator perks now disabled") + print("Donator perks now disabled") + end +end + --- When a player joins, set a 1s timer to retrieve their color before printing their welcome message local function player_joined(event) local player = game.get_player(event.player_index) @@ -52,19 +99,117 @@ local function player_joined(event) return nil end - local messages = d.welcome_messages - if not messages then + local perk_flag = d.perk_flags + if perk_flag < 2 then return end - local count = #messages - if count == 0 then + if Public.player_has_donator_perk(player.name, DonatorPerks.welcome_msg) then + local messages = d.welcome_messages + if messages then + local count = #messages + if count ~= 0 and count then + local message = messages[random(count)] + message = concat({'*** ', message, ' ***'}) + Task.set_timeout_in_ticks(60, print_after_timeout, {player = player, message = message}) + end + end + end + + if not config.donator_perks.enabled then return end - local message = messages[random(count)] - message = concat({'*** ', message, ' ***'}) - Task.set_timeout_in_ticks(60, print_after_timeout, {player = player, message = message}) + local mining_flag = Public.player_has_donator_perk(player.name, DonatorPerks.team_mining) + local crafting_flag = Public.player_has_donator_perk(player.name, DonatorPerks.team_crafting) + local running_flag = Public.player_has_donator_perk(player.name, DonatorPerks.team_run) + local inventory_flag = Public.player_has_donator_perk(player.name, DonatorPerks.team_inventory) + + if not mining_flag and not crafting_flag and not running_flag and not inventory_flag then + return + end + + -- Update team perks + if not donator_perks_temp[player.name] then -- check they're not already in donator_perks_temp table, this keeps track of bonuses that are added and removed as players join and leave + local donator_perk_msg = concat({"Donator Tier: ",donator_tiers[d.patreon_tier].name, ". Team bonuses applied for ", player.name,": "}) + if mining_flag and donator_tiers[2].count < donator_tiers[2].max then -- Apply tier 2 (Coal) reward: +10 % team manual mining bonus per online tier 2+ donator + player.force.manual_mining_speed_modifier = player.force.manual_mining_speed_modifier + 0.1 + donator_tiers[2].count = donator_tiers[2].count + 1 + donator_perk_msg = concat({donator_perk_msg, "+10% hand mining. "}) + end + if crafting_flag and donator_tiers[3].count < donator_tiers[3].max then -- Apply tier 3 (Solid Fuel) reward: + 10 % team manual crafting bonus per online tier 3+ donator + player.force.manual_crafting_speed_modifier = player.force.manual_crafting_speed_modifier + 0.1 + donator_tiers[3].count = donator_tiers[3].count + 1 + donator_perk_msg = concat({donator_perk_msg, "+10% hand crafting. "}) + end + if running_flag and donator_tiers[4].count < donator_tiers[4].max then -- Apply Tier 4 (Rocket Fuel) reward: + 10 % team running speed bonus per online tier 4+ donator + player.force.character_running_speed_modifier = player.force.character_running_speed_modifier + 0.1 + donator_tiers[4].count = donator_tiers[4].count + 1 + donator_perk_msg = concat({donator_perk_msg, "+10% run speed. "}) + end + donator_perks_temp[player.name] = perk_flag + if inventory_flag and not donator_perks_perm[player.name] and donator_tiers[5].count < donator_tiers[5].max then + player.force.character_inventory_slots_bonus = player.force.character_inventory_slots_bonus + 5 + donator_tiers[5].count = donator_tiers[5].count + 1 + donator_perk_msg = concat({donator_perk_msg, "+5 inventory slots. "}) + donator_perks_perm[player.name] = true + elseif donator_perks_perm[player.name] then -- for if they're already in the table. We don't want to apply the perk again but we do want to append the perk to the message. + donator_perk_msg = concat({donator_perk_msg, "+5 inventory slots. "}) + end + donator_perk_msg = donator_perk_msg .. " Use /perks to see bonuses." + Task.set_timeout_in_ticks(80, print_after_timeout, {player = player, message = donator_perk_msg}) + end +end + +local function player_left(event) + local player = game.get_player(event.player_index) + + if not player or not player.valid or not config.donator_perks.enabled then + return + end + + local d = donators[player.name] + if not donator_perks_temp[player.name] and not d then + return + end + + local mining_flag = Public.player_has_donator_perk(player.name, DonatorPerks.team_mining) + local crafting_flag = Public.player_has_donator_perk(player.name, DonatorPerks.team_crafting) + local running_flag = Public.player_has_donator_perk(player.name, DonatorPerks.team_run) + + -- To do: What happens if an admin changes the players donator status or flags while they're online? + if not mining_flag and not crafting_flag and not running_flag then + return + end + + if donator_perks_temp[player.name] then + if mining_flag then + if player.force.manual_mining_speed_modifier >= 0.1 then + player.force.manual_mining_speed_modifier = player.force.manual_mining_speed_modifier - 0.1 + else + player.force.manual_mining_speed_modifier = 0 + end + donator_tiers[2].count = donator_tiers[2].count - 1 + end + if crafting_flag then + if player.force.manual_crafting_speed_modifier >= 0.1 then + player.force.manual_crafting_speed_modifier = player.force.manual_crafting_speed_modifier - 0.1 + else + player.force.manual_crafting_speed_modifier = 0 + end + donator_tiers[3].count = donator_tiers[4].count - 1 + end + if running_flag and player.force.character_running_speed_modifier >= 0.1 then + if player.force.character_running_speed_modifier >= 0.1 then + player.force.character_running_speed_modifier = player.force.character_running_speed_modifier - 0.1 + else + player.force.character_running_speed_modifier = 0 + end + donator_tiers[4].count = donator_tiers[4].count - 1 + end + donator_perks_temp[player.name] = nil -- remove them from the table + end + end --- Prints a message on donator death @@ -79,6 +224,9 @@ local function player_died(event) return nil end + if not Public.player_has_donator_perk(player.name, DonatorPerks.death_msg) then + return + end local messages = d.death_messages if not messages then return @@ -98,12 +246,48 @@ local function player_died(event) game.print(message, player.chat_color) end +local reset_run_speed = + Token.register( + function(player) + if not player.valid then + return + end + player.character_running_speed_modifier = player.character_running_speed_modifier - 1 + end +) + +local function player_respawned(event) + local player = game.get_player(event.player_index) + if not player or not player.valid or not config.donator_perks.enabled then + return + end + + local d = donators[player.name] + if not d then + return nil + end + + local respawn_flag = Public.player_has_donator_perk(player.name, DonatorPerks.respawn_boost) + if not respawn_flag then + return + end + + player.character_running_speed_modifier = player.character_running_speed_modifier + 1 + Task.set_timeout_in_ticks(30*60, reset_run_speed, player) +end + --- Returns the table of donators -- @return function Public.get_donators_table() return donators end +--- Returns the table of active perks +-- @return
+function Public.get_donator_perks_table() + return donator_tiers +end + --- Checks if a player is a donator -- @param player_name -- @return @@ -111,24 +295,6 @@ function Public.is_donator(player_name) return donators[player_name] ~= nil end ---- Checks if a player has a specific donator perk --- @param player_name --- @param perf_flag --- @return -function Public.player_has_donator_perk(player_name, perk_flag) - local d = donators[player_name] - if not d then - return false - end - - local flags = d.perk_flags - if not flags then - return false - end - - return bit32.band(flags, perk_flag) == perk_flag -end - --- Sets the data for a donator, all existing data for the entry is removed -- @param player_name -- @param data
@@ -244,6 +410,10 @@ Server.on_data_set_changed( Event.add(defines.events.on_player_joined_game, player_joined) +Event.add(defines.events.on_player_left_game, player_left) + Event.add(defines.events.on_player_died, player_died) +Event.add(defines.events.on_player_respawned, player_respawned) + return Public diff --git a/features/donator_commands.lua b/features/donator_commands.lua index 8f6273ee..75fa23b8 100644 --- a/features/donator_commands.lua +++ b/features/donator_commands.lua @@ -3,8 +3,20 @@ local Game = require 'utils.game' local Command = require 'utils.command' local Donator = require 'features.donator' local Color = require 'resources.color_presets' +local Global = require 'utils.global' local format = string.format +local config = global.config.donator.donator_perks + + +Global.register( + { + config = config + }, + function(tbl) + config = tbl.global.config.donator.donator_perks + end +) -- Local functions @@ -73,6 +85,26 @@ local function donator_death_message_command(args, player) command_path_decider(args, player, table_name) end +-- Prints a list of currently active perks to the player +local function print_perks(_, player) + local print = print + if player and player.valid then -- allows us to call print_perks from the server console OR in-game + print = player.print + end + + if not config.enabled then + print("Donator perks have been disabled for this map.") + return + end + + local donator_tiers = Donator.get_donator_perks_table() + + print("Currently active team perks: +"..(donator_tiers[2].count*10).."% hand mining speed (max +"..(donator_tiers[2].max*10).."%), +" + ..(donator_tiers[3].count*10).."% hand crafting speed (max +"..(donator_tiers[3].max*10).."%), +" + ..(donator_tiers[4].count*10).."% run speed (max +"..(donator_tiers[4].max*10).."%) and +" + ..(donator_tiers[5].count*5).." inventory slots (max +"..(donator_tiers[5].max*5).."%).") +end + -- Commands Command.add( @@ -98,3 +130,11 @@ Command.add( }, donator_death_message_command ) + +Command.add( + 'perks', + { + description = {'command_description.perks'}, + }, + print_perks +) \ No newline at end of file diff --git a/locale/en/redmew_command_text.cfg b/locale/en/redmew_command_text.cfg index 371754ce..5cd1ed0f 100644 --- a/locale/en/redmew_command_text.cfg +++ b/locale/en/redmew_command_text.cfg @@ -14,7 +14,6 @@ crash_site_spy=Spend coins to send a fish to spy on the enemy for a short time. crash_site_spy_invalid=You need to add a valid location to send a spy fish. e.g /spy [gps=-110,-17,redmew] crash_site_spy_funds=Training these spy fish ain't cheap! You need more coins! crash_site_spy_success=__1__ used the /spy command and spent __2__ coins to train a fish to spy on the enemy [gps=__3__,__4__,redmew] - crash_site_airstrike_invalid=Invalid co-ordinates. crash_site_airstrike=Launch an airstrike against the enemy with poison capsules. crash_site_airstrike_count=Upgrade the airstrike damage to to level __1__\n\nTo use airstrike place poison capsules in the spawn chest then type /strike followed by a gps position\n\nDamage upgrades increase the number of poison capsules launched by airstrike.\n\nCurrent level: __2__\nCurrent shell count: __3__\nCurrent cost: __4__ @@ -108,6 +107,7 @@ quick_bar_load=Loads your quick bars from the server (overwriting existing bars) quick_bar_delete=Erases your saved quick bars from the server set_pollution_multiplier=EXPERIMENTAL. An integer which gets multiplied by 0.01 to give the amount of pollution crash site magic crafters emit. Default is 0 get_pollution_multiplier=The current pollution multiplier for crash site. The default is 0. +perks=Lists Patreon donators that are contributing to currently active perks. [command_custom_help] tp= 3 different uses: "/tp" to tp to selected entity. "/tp mode" to toggle tp mode. "/tp Newcott" to tp to Newcott. diff --git a/resources/donator_perks.lua b/resources/donator_perks.lua index 1e68bc6d..70331b3e 100644 --- a/resources/donator_perks.lua +++ b/resources/donator_perks.lua @@ -1,4 +1,18 @@ return { - rank = 0x1, - train = 0x2 + rank = 0x1, -- T1 + train = 0x2, -- T3. train saviour perk + welcome_msg = 0x4, -- T2. enables a message upon player join + team_mining = 0x8, -- T2. boosts team manual mining speed while player is online + death_msg = 0x10, -- T3. enables a message upon player death + team_crafting = 0x20, -- T3. boosts team manual crafting speed while player is online + team_run = 0x40, -- T4. boosts team run speed while player is online + respawn_boost = 0x80, -- T4. player runs faster for 30 seconds after respawn + team_inventory = 0x160 -- T5. boosts team inventory size for remainder of map } + +-- 2021-12-30 +-- Tier 1 = 1 +-- Tier 2 = 8 + 4 + 1 = 21 +-- Tier 3 = 8 + 4 + 1 + 16 + 32 + 2= 63 +-- Tier 4 = 63 + 64 + 128 = 255 +-- Tier 5 = 255 + 256 = 511 \ No newline at end of file