Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions SQL/tgstation_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,18 @@ CREATE TABLE `player` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `metacoin_purchases`
-- MASSMETA EDIT ADDITION START (metacoins)
DROP TABLE IF EXISTS `metacoin_purchases`;
CREATE TABLE `metacoin_purchases` (
`ckey` varchar(32) NOT NULL,
`listing` varchar(64) NOT NULL,
`owned` tinyint(1) NOT NULL DEFAULT 1,
PRIMARY KEY (`ckey`, `listing`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- MASSMETA EDIT ADDITION END (metacoins)

--
-- Table structure for table `poll_option`
--
Expand Down
6 changes: 3 additions & 3 deletions code/modules/deathmatch/deathmatch_controller.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@
entry_fee = min(max(round(text2num("[entry_fee]") || 0), 0), 1000)

if(entry_fee > 0)
var/datum/metacoin_shop_controller/shop = get_metacoin_shop_controller()
var/datum/metacoin_shop_controller/shop = get_metacoin_controller()
if(!shop)
return list("ok" = FALSE, "error" = "shop_unavailable")

var/current_balance = shop.fetch_metacoin_balance(host.ckey)
var/current_balance = shop.fetch_balance(host.ckey)
if(isnull(current_balance))
return list("ok" = FALSE, "error" = "db_unavailable")
if(current_balance < entry_fee)
Expand All @@ -52,7 +52,7 @@
lobbies[host.ckey] = new_lobby
deadchat_broadcast(" has opened a new deathmatch lobby. <a href=byond://?src=[REF(new_lobby)];join=1>(Join)</a>", "<B>[host]</B>")
return list("ok" = TRUE)
//MASSMETA EDIT CHANGE START (metacoins)
//MASSMETA EDIT CHANGE END (metacoins)

/datum/deathmatch_controller/proc/remove_lobby(ckey)
var/lobby = lobbies[ckey]
Expand Down
37 changes: 21 additions & 16 deletions modular_meta/features/metacoins/code/award_overrides.dm
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@

// CLOSE_TO_NOTHING

// ONE_POINT
// You genuinely don't want to award much for every "robot" served in kitchen. Five points is okay, in my opinion.

/datum/award/score/drake_score
reward = METACOIN_AWARD_ONE_POINT
/datum/award/score/bartender_tourist_score

/datum/award/score/hierophant_score
reward = METACOIN_AWARD_ONE_POINT
/datum/award/score/chef_tourist_score

// ONE_POINT

/datum/award/score/maintenance_pill
reward = METACOIN_AWARD_ONE_POINT
Expand All @@ -101,24 +101,29 @@
/datum/award/score/wendigo_score
reward = METACOIN_AWARD_SMALL

/datum/award/score/colussus_score
/datum/award/score/hardcore_random
reward = METACOIN_AWARD_SMALL

/datum/award/score/thething_score
reward = METACOIN_AWARD_SMALL
/datum/award/score/style_score
reward = METACOIN_AWARD_NONE

/datum/award/score/bartender_tourist_score
/datum/award/score/drake_score
reward = METACOIN_AWARD_SMALL

/datum/award/score/chef_tourist_score
/datum/award/score/hierophant_score
reward = METACOIN_AWARD_SMALL

/datum/award/score/hardcore_random
reward = METACOIN_AWARD_SMALL
// METACOIN_AWARD_MED

/datum/award/score/style_score
reward = METACOIN_AWARD_SMALL
/datum/award/score/bubblegum_score
reward = METACOIN_AWARD_MED

/datum/award/score/colussus_score
reward = METACOIN_AWARD_MED

// METACOIN_AWARD_BIG
/datum/award/score/thething_score
reward = METACOIN_AWARD_BIG //overall rare boss, why not?

// METACOIN_AWARD_MED
/datum/award/score/legion_score
reward = METACOIN_AWARD_MED // this one is hard to kill y'know?
reward = METACOIN_AWARD_BIG // this one is hard to kill y'know?
119 changes: 84 additions & 35 deletions modular_meta/features/metacoins/code/metacoin.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)
if(.)
return
get_metacoins_controller()
get_metacoin_shop_controller()
get_metacoin_controller()

/datum/metacoins_controller
var/list/roundstart_ready_ckeys = list()
Expand Down Expand Up @@ -69,12 +69,9 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)

processed_ckeys[player_ckey] = TRUE

if(METACOIN_REWARD_SURVIVE_EVAC > 0 && is_evacuation_condition_met(player_ckey))
award_metacoins(player_ckey, METACOIN_REWARD_SURVIVE_EVAC, "survived_shift", "Survived Shift")
if(METACOIN_REWARD_IMPORTANT_JOBS > 0 && is_important_role(player_ckey))
award_metacoins(player_ckey, METACOIN_REWARD_IMPORTANT_JOBS, "social_role", "Highly Important Role")
if(METACOIN_REWARD_ANTAG_GREENTEXT > 0 && is_antag_greentext(player_ckey))
award_metacoins(player_ckey, METACOIN_REWARD_ANTAG_GREENTEXT, "antag_greentext", "Antagonist Greentext")
var/list/rewards = get_round_rewards(player_ckey)
if(length(rewards))
award_entries(player_ckey, rewards)
/// Main proc for your awards. Integrate it wherever you like to
///
/// Arguments:
Expand All @@ -84,7 +81,7 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)
/// * reason - reason shown in reward chat message.
/// * allow_repeat - If TRUE, skips source dedupe and allows payout on every call.
/// * resolve_from_award_type - If TRUE, reward_value is resolved through the award datum's reward var.
/// * sound - If TRUE plays a sound, check notify_player_reward_awarded
/// * sound - If TRUE plays a sound, check notify_reward
/// Returns TRUE when payout is persisted, FALSE otherwise.
/datum/metacoins_controller/proc/award_metacoins(target_ckey, reward_value, source, reason, allow_repeat = FALSE, resolve_from_award_type = FALSE, sound = TRUE)
var/amount
Expand All @@ -95,8 +92,17 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)
if(!target_ckey || amount <= 0)
return FALSE

var/sanitized_source = source || "unknown"
var/sanitized_reason = reason || "Reward"
var/list/rewards = list(list(
"amount" = amount,
"source" = source || "unknown",
"reason" = reason || "Reward",
"by_award_type" = resolve_from_award_type,
))
return award_entries(target_ckey, rewards, allow_repeat, sound)

/datum/metacoins_controller/proc/award_entries(target_ckey, list/rewards, allow_repeat = FALSE, sound = TRUE)
if(!target_ckey || !length(rewards))
return FALSE

var/list/source_awards
if(!allow_repeat)
Expand All @@ -105,35 +111,77 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)
source_awards = list()
awarded_sources_by_ckey[target_ckey] = source_awards

if(source_awards[sanitized_source])
return FALSE
var/total_amount = 0
var/list/pay_rewards = list()
for(var/list/reward_entry as anything in rewards)
var/amount = reward_entry["amount"] || 0
if(amount <= 0)
continue

var/sanitized_source = reward_entry["source"] || "unknown"
var/sanitized_reason = reward_entry["reason"] || "Reward"
if(!allow_repeat && source_awards[sanitized_source])
log_game("[src] metacoin payout skipped: ckey=[target_ckey], amount=[amount], source='[sanitized_source]', reason='[sanitized_reason]', cause='duplicate source'.")
continue

pay_rewards += list(list(
"amount" = amount,
"source" = sanitized_source,
"reason" = sanitized_reason,
"by_award_type" = reward_entry["by_award_type"] || FALSE,
))
total_amount += amount

if(total_amount <= 0)
return FALSE

if(!SSdbcore.Connect())
log_game("[src] metacoin payout failed: ckey=[target_ckey], amount=[total_amount], cause='db unavailable', rewards=[json_encode(pay_rewards)].")
return FALSE

if(!add_metacoins(target_ckey, amount))
if(!add_metacoins(target_ckey, total_amount))
log_game("[src] metacoin payout failed: ckey=[target_ckey], amount=[total_amount], cause='update failed', rewards=[json_encode(pay_rewards)].")
return FALSE

if(!allow_repeat)
source_awards[sanitized_source] = TRUE
for(var/list/reward_entry as anything in pay_rewards)
source_awards[reward_entry["source"]] = TRUE

log_game("[src] metacoin payout: ckey=[target_ckey], amount=[amount], source='[sanitized_source]', reason='[sanitized_reason]', allow_repeat=[allow_repeat], by_award_type=[resolve_from_award_type].")
log_game("[src] metacoin payout: ckey=[target_ckey], amount=[total_amount], allow_repeat=[allow_repeat], rewards=[json_encode(pay_rewards)].")

add_round_award_log_entry(target_ckey, amount, sanitized_source, sanitized_reason)
for(var/list/reward_entry as anything in pay_rewards)
add_round_award_log_entry(target_ckey, reward_entry["amount"], reward_entry["source"], reward_entry["reason"])

var/list/reward_entries = list(list(
"amount" = amount,
"source" = sanitized_source,
"reason" = sanitized_reason,
))
notify_player_reward_awarded(target_ckey, amount, reward_entries, sound)
notify_reward(target_ckey, total_amount, pay_rewards, sound)

var/mob/player_mob = get_mob_by_ckey(target_ckey)
if(player_mob)
SStgui.update_user_uis(player_mob)

return TRUE

/datum/metacoins_controller/proc/get_round_rewards(target_ckey)
var/list/rewards = list()
if(METACOIN_REWARD_SURVIVE_EVAC > 0 && is_evacuation_condition_met(target_ckey))
rewards += list(list(
"amount" = METACOIN_REWARD_SURVIVE_EVAC,
"source" = "survived_shift",
"reason" = "Survived Shift",
))
if(METACOIN_REWARD_IMPORTANT_JOBS > 0 && is_important_role(target_ckey))
rewards += list(list(
"amount" = METACOIN_REWARD_IMPORTANT_JOBS,
"source" = "social_role",
"reason" = "Highly Important Role",
))
if(METACOIN_REWARD_ANTAG_GREENTEXT > 0 && is_antag_greentext(target_ckey))
rewards += list(list(
"amount" = METACOIN_REWARD_ANTAG_GREENTEXT,
"source" = "antag_greentext",
"reason" = "Antagonist Greentext",
))
return rewards

/datum/metacoins_controller/proc/get_reward_amount(award_type)
if(!ispath(award_type, /datum/award))
return 0
Expand Down Expand Up @@ -222,7 +270,7 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)
if(!player_turf)
return FALSE

if(player_turf.onCentCom())
if(player_turf.onCentCom() || player_turf.onSyndieBase() || player_turf.on_escaped_shuttle())
return TRUE

return !!SSshuttle.emergency.shuttle_areas[player_area]
Expand All @@ -245,13 +293,13 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)
return TRUE
if(antag_datum.antag_flags & ANTAG_FAKE)
continue
if(!is_antag_objectives_successful(antag_datum))
if(!is_greentext(antag_datum))
continue
return TRUE

return FALSE

/datum/metacoins_controller/proc/is_antag_objectives_successful(datum/antagonist/antag_datum)
/datum/metacoins_controller/proc/is_greentext(datum/antagonist/antag_datum)
if(!antag_datum)
return FALSE

Expand All @@ -264,7 +312,7 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)

return TRUE

/datum/metacoins_controller/proc/notify_player_reward_awarded(target_ckey, total_reward, list/reward_entries, sound = TRUE)
/datum/metacoins_controller/proc/notify_reward(target_ckey, total_reward, list/reward_entries, sound = TRUE)
if(total_reward <= 0)
return

Expand Down Expand Up @@ -298,8 +346,9 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)
)

var/success = update_query.warn_execute(async = FALSE)
var/affected = update_query.affected
qdel(update_query)
return success
return success && affected > 0

/datum/metacoins_panel
var/client/owner
Expand Down Expand Up @@ -329,7 +378,7 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)
data["roundAwardLog"] = client_ckey ? controller.get_round_award_log(client_ckey) : list()
data["canOpenShop"] = TRUE

var/balance = fetch_metacoin_balance(client_ckey)
var/balance = fetch_balance(client_ckey)
data["dbConnected"] = !isnull(balance)
data["balance"] = isnull(balance) ? 0 : balance

Expand All @@ -346,7 +395,7 @@ GLOBAL_DATUM(metacoins_controller, /datum/metacoins_controller)

return FALSE

/datum/metacoins_panel/proc/fetch_metacoin_balance(target_ckey)
/datum/metacoins_panel/proc/fetch_balance(target_ckey)
if(!target_ckey)
return 0

Expand Down Expand Up @@ -392,7 +441,7 @@ ADMIN_VERB(mc_give, R_ADMIN, "Grant Metacoins", "Grant metacoins to a target cke
if(!length(grant_reason))
grant_reason = "Manual admin grant"

var/create_note = tgui_alert(user, "Include a note?", "Grant Metacoins", list("No", "Yes")) == "Yes"
// var/create_note = tgui_alert(user, "Include a note?", "Grant Metacoins", list("No", "Yes")) == "Yes"

var/datum/metacoins_controller/controller = get_metacoins_controller()
if(!controller)
Expand All @@ -409,15 +458,15 @@ ADMIN_VERB(mc_give, R_ADMIN, "Grant Metacoins", "Grant metacoins to a target cke
log_admin("[key_name(user)] failed to grant [amount] metacoins to [target_ckey]. Reason='[grant_reason]'.")
to_chat(user, span_warning("Failed to grant metacoins. Check SQL logs"), confidential = TRUE)
return

/* // i've thought about it, that's kinda useless
if(create_note)
var/note_text = "Metacoins granted: +[amount]. Reason: [grant_reason]"
create_message("note", target_ckey, user.ckey, note_text, null, null, 0, 0, null, 0, "none")

var/admin_msg = "[key_name_admin(user)] granted [amount] metacoins to [target_ckey]. Reason='[grant_reason]'. Auto-note=[create_note ? "yes" : "no"]."
*/
var/admin_msg = "[key_name_admin(user)] granted [amount] metacoins to [target_ckey]. Reason='[grant_reason]']."
message_admins(admin_msg)
log_admin("[key_name(user)] granted [amount] metacoins to [target_ckey]. Reason='[grant_reason]'. Auto-note=[create_note ? "yes" : "no"].")
log_game("[key_name(user)] granted [amount] metacoins to [target_ckey]. Reason='[grant_reason]'. Auto-note=[create_note ? "yes" : "no"].")
log_admin("[key_name(user)] granted [amount] metacoins to [target_ckey]. Reason='[grant_reason]'.")
log_game("[key_name(user)] granted [amount] metacoins to [target_ckey]. Reason='[grant_reason]'].")

/client/verb/view_metacoins()
set name = "View Metacoins"
Expand Down
12 changes: 6 additions & 6 deletions modular_meta/features/metacoins/code/metacoin_deathmatch.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
if(!player?.ckey)
return FALSE

var/already_paid = text2num(fees_paid[player.ckey]) || 0
var/already_paid = fees_paid[player.ckey] || 0
if(entry_fee <= already_paid)
return TRUE

var/to_pay = entry_fee - already_paid
var/datum/metacoin_shop_controller/shop = get_metacoin_shop_controller()
var/datum/metacoin_shop_controller/shop = get_metacoin_controller()
if(!shop)
to_chat(player, span_warning("Metacoin subsystem is unavailable."))
return FALSE
Expand All @@ -34,12 +34,12 @@
if(!target_ckey)
return FALSE

var/paid_amount = text2num(fees_paid[target_ckey]) || 0
var/paid_amount = fees_paid[target_ckey] || 0
if(paid_amount <= 0)
fees_paid -= target_ckey
return TRUE

var/datum/metacoin_shop_controller/shop = get_metacoin_shop_controller()
var/datum/metacoin_shop_controller/shop = get_metacoin_controller()
if(!shop || !shop.add_metacoins(target_ckey, paid_amount))
log_game("Deathmatch lobby [host] failed to refund [paid_amount] metacoins to [target_ckey].")
return FALSE
Expand All @@ -59,7 +59,7 @@

var/payout_amount = prize_pool
var/list/paid_snapshot = fees_paid?.Copy() || list()
var/datum/metacoin_shop_controller/shop = get_metacoin_shop_controller()
var/datum/metacoin_shop_controller/shop = get_metacoin_controller()

if(winner_ckey && shop?.add_metacoins(winner_ckey, payout_amount))
announce(span_boldnicegreen("[winner ? winner.real_name : winner_ckey] received [payout_amount] metacoins from the prize pool."))
Expand All @@ -74,7 +74,7 @@
log_game("Deathmatch lobby [host] failed to pay prize pool [payout_amount] to [payout_target], trying refunds.")
if(shop)
for(var/paid_ckey in paid_snapshot)
var/paid_amount = text2num(paid_snapshot[paid_ckey]) || 0
var/paid_amount = paid_snapshot[paid_ckey] || 0
if(paid_amount <= 0)
continue
shop.add_metacoins(paid_ckey, paid_amount)
Expand Down
Loading
Loading