From a55b2c4ff3ebfd22e8ed6d56966199d774743975 Mon Sep 17 00:00:00 2001 From: shellspeed1 Date: Tue, 20 Sep 2022 20:05:59 -0700 Subject: [PATCH] ports https://github.com/tgstation/tgstation/pull/56375. Credit to cacogen. --- code/datums/components/pricetag.dm | 23 +++-- code/game/machinery/civilian_bountys.dm | 93 +++++++++++++++++-- code/modules/cargo/export_scanner.dm | 23 ++++- code/modules/cargo/exports/civilain_bounty.dm | 2 +- .../mob/living/carbon/human/human_helpers.dm | 11 ++- 5 files changed, 132 insertions(+), 20 deletions(-) diff --git a/code/datums/components/pricetag.dm b/code/datums/components/pricetag.dm index 3220dc425a..2ad63c6464 100644 --- a/code/datums/components/pricetag.dm +++ b/code/datums/components/pricetag.dm @@ -1,13 +1,17 @@ /datum/component/pricetag - var/datum/bank_account/owner - var/profit_ratio = 1 + ///Payee gets 100% of the value if no ratio has been set. + var/default_profit_ratio = 1 + ///List of bank accounts this pricetag pays out to. Format is payees[bank_account] = profit_ratio. + var/list/payees = list() + /datum/component/pricetag/Initialize(_owner,_profit_ratio) if(!isobj(parent)) //Has to account for both objects and sellable structures like crates. return COMPONENT_INCOMPATIBLE - owner = _owner if(_profit_ratio) - profit_ratio = _profit_ratio + payees[_owner] = _profit_ratio + else + payees[_owner] = default_profit_ratio RegisterSignal(parent, COMSIG_ITEM_SOLD, .proc/split_profit) RegisterSignal(parent, COMSIG_STRUCTURE_UNWRAPPED, .proc/Unwrapped) RegisterSignal(parent, COMSIG_ITEM_UNWRAPPED, .proc/Unwrapped) @@ -19,10 +23,13 @@ /datum/component/pricetag/proc/split_profit(var/item_value) var/price = item_value if(price) - var/adjusted_value = price*(profit_ratio/100) - owner.adjust_money(adjusted_value) - owner.bank_card_talk("Sale recorded. [adjusted_value] credits added to account.") + for(var/datum/bank_account/payee in payees) + var/profit_ratio = payees[payee] + var/adjusted_value = price * profit_ratio + var/datum/bank_account/bank_account = payee + bank_account.adjust_money(adjusted_value) + bank_account.bank_card_talk("Sale of [parent] recorded. [adjusted_value] credits added to account.") return TRUE /datum/component/pricetag/proc/return_ratio() - return profit_ratio + return default_profit_ratio diff --git a/code/game/machinery/civilian_bountys.dm b/code/game/machinery/civilian_bountys.dm index 9c913ee9cf..36ce96ea7e 100644 --- a/code/game/machinery/civilian_bountys.dm +++ b/code/game/machinery/civilian_bountys.dm @@ -98,12 +98,7 @@ inserted_scan_id.registered_account.reset_bounty() SSeconomy.civ_bounty_tracker++ var/obj/item/bounty_cube/reward = new /obj/item/bounty_cube(drop_location()) - reward.bounty_value = curr_bounty.reward - reward.bounty_name = curr_bounty.name - reward.bounty_holder = inserted_scan_id.registered_name - reward.name = "\improper [reward.bounty_value] cr [reward.name]" - reward.desc += " The tag indicates it was [reward.bounty_holder]'s reward for completing the [reward.bounty_name] bounty and that it was created at [station_time_timestamp(format = "hh:mm")]." - reward.AddComponent(/datum/component/pricetag, inserted_scan_id.registered_account, CIV_BOUNTY_SPLIT) + reward.set_up(curr_bounty, inserted_scan_id) pad.visible_message("[pad] activates!") flick(pad.sending_state,pad) pad.icon_state = pad.idle_state @@ -245,6 +240,92 @@ var/bounty_holder ///What the bounty was for. var/bounty_name + ///Multiplier for the bounty payout received by the Supply budget if the cube is sent without having to nag. + var/speed_bonus = 0.2 + ///Multiplier for the bounty payout received by the person who completed the bounty. + var/holder_cut = 0.3 + ///Multiplier for the bounty payout received by the person who claims the handling tip. + var/handler_tip = 0.1 + ///Time between nags. + var/nag_cooldown = 5 MINUTES + ///How much the time between nags extends each nag. + var/nag_cooldown_multiplier = 1.25 + ///Next world tick to nag Supply listeners. + var/next_nag_time + ///What job the bounty holder had. + var/bounty_holder_job + ///Bank account of the person who receives the handling tip. + var/datum/bank_account/bounty_handler_account + ///Bank account of the person who completed the bounty. + var/datum/bank_account/bounty_holder_account + ///Our internal radio. + var/obj/item/radio/radio + ///The key our internal radio uses. + var/radio_key = /obj/item/encryptionkey/headset_cargo + +/obj/item/bounty_cube/Initialize() + . = ..() + radio = new(src) + radio.keyslot = new radio_key + radio.listening = FALSE + radio.recalculateChannels() + +/obj/item/bounty_cube/Destroy() + QDEL_NULL(radio) + . = ..() + +/obj/item/bounty_cube/examine() + . = ..() + if(speed_bonus) + . += "[time2text(next_nag_time - world.time,"mm:ss")] remains until [bounty_value * speed_bonus] credit speedy delivery bonus lost." + if(handler_tip && !bounty_handler_account) + . += "Scan this in the cargo shuttle with an export scanner to register your bank account for the [bounty_value * handler_tip] credit handling tip." + +/obj/item/bounty_cube/process(delta_time) + if(COOLDOWN_FINISHED(src, next_nag_time)) + if(!is_centcom_level(z) && !is_reserved_level(z)) //don't send message if we're on Centcom or in transit + radio.talk_into(src, "Unsent in [get_area(src)].[speed_bonus ? " Speedy delivery bonus of [bounty_value * speed_bonus] credit\s lost." : ""]", RADIO_CHANNEL_SUPPLY) + speed_bonus = 0 + bounty_holder_account.bank_card_talk("\The [src] is unsent in [get_area(src)].") + if(bounty_handler_account) + bounty_handler_account.bank_card_talk("\The [src] is unsent in [get_area(src)].") + nag_cooldown = nag_cooldown * nag_cooldown_multiplier + COOLDOWN_START(src, next_nag_time, nag_cooldown) + +/obj/item/bounty_cube/proc/set_up(datum/bounty/my_bounty, obj/item/card/id/holder_id) + bounty_value = my_bounty.reward + bounty_name = my_bounty.name + bounty_holder = holder_id.registered_name + bounty_holder_job = holder_id.assignment + bounty_holder_account = holder_id.registered_account + name = "\improper [bounty_value] cr [name]" + desc += " The sales tag indicates it was [bounty_holder] ([bounty_holder_job])'s reward for completing the [bounty_name] bounty." + AddComponent(/datum/component/pricetag, holder_id.registered_account, holder_cut) + START_PROCESSING(SSobj, src) + COOLDOWN_START(src, next_nag_time, nag_cooldown) + radio.talk_into(src,"Created in [get_area(src)] by [bounty_holder] ([bounty_holder_job]). Speedy delivery bonus lost in [time2text(next_nag_time - world.time,"mm:ss")].", RADIO_CHANNEL_SUPPLY) + +//for when you need a REAL bounty cube to test with and don't want to do a bounty each time your code changes +/obj/item/bounty_cube/test_cube + name = "debug bounty cube" + desc = "Use in-hand to set it up with a random bounty. Requires an ID it can detect with a bank account attached. \ + This will alert Supply over the radio with your name and location, and cargo techs will be dispatched to your location with kill on sight clearance." + var/set_up = FALSE + +/obj/item/bounty_cube/test_cube/attack_self(mob/user) + if(!isliving(user)) + to_chat(user, "You aren't eligible to use this!") + return ..() + + if(!set_up) + var/mob/living/squeezer = user + if(squeezer.get_bank_account()) + set_up(random_bounty(), squeezer.get_idcard()) + set_up = TRUE + return ..() + to_chat(user, "It can't detect your bank account.") + + return ..() ///Beacon to launch a new bounty setup when activated. diff --git a/code/modules/cargo/export_scanner.dm b/code/modules/cargo/export_scanner.dm index 80fd05cf8c..dcb476c459 100644 --- a/code/modules/cargo/export_scanner.dm +++ b/code/modules/cargo/export_scanner.dm @@ -43,5 +43,24 @@ to_chat(user, "Scanned [O], value: [price] credits[O.contents.len ? " (contents included)" : ""].") else to_chat(user, "Scanned [O], no export value.") - if(bounty_ship_item_and_contents(O, dry_run=TRUE)) - to_chat(user, "Scanned item is eligible for one or more bounties.") + + + if(ishuman(user)) + var/mob/living/carbon/human/scan_human = user + if(istype(O, /obj/item/bounty_cube)) + var/obj/item/bounty_cube/cube = O + + if(!istype(get_area(cube), /area/shuttle/supply)) + to_chat(user, "Shuttle placement not detected. Handling tip not registered.") + + else if(cube.bounty_handler_account) + to_chat(user, "Bank account for handling tip already registered!") + + else if(scan_human.get_bank_account() && cube.GetComponent(/datum/component/pricetag)) + var/datum/component/pricetag/pricetag = cube.GetComponent(/datum/component/pricetag) + cube.bounty_handler_account = scan_human.get_bank_account() + pricetag.payees[cube.bounty_handler_account] += cube.handler_tip + cube.bounty_handler_account.bank_card_talk("Bank account for [price ? "[price * cube.handler_tip] credit " : ""]handling tip successfully registered.") + cube.bounty_holder_account.bank_card_talk("[cube] was scanned in \the [get_area(cube)] by [scan_human] ([scan_human.job]).") + else + to_chat(user, "Bank account not detected. Handling tip not registered.") diff --git a/code/modules/cargo/exports/civilain_bounty.dm b/code/modules/cargo/exports/civilain_bounty.dm index 3d443fbad0..58486f176b 100644 --- a/code/modules/cargo/exports/civilain_bounty.dm +++ b/code/modules/cargo/exports/civilain_bounty.dm @@ -5,4 +5,4 @@ export_types = list(/obj/item/bounty_cube) /datum/export/bounty_box/get_cost(obj/item/bounty_cube/cube, allowed_categories, apply_elastic) - return cube.bounty_value + return cube.bounty_value + (cube.bounty_value * (cube.speed_bonus / 100)) diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index a3c6294aec..470eb626ae 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -123,16 +123,21 @@ to_chat(src, span_warning("You can't bring yourself to use a ranged weapon!")) return FALSE -/mob/living/carbon/human/proc/get_bank_account() +//Returns the bank account of an ID the user may be holding. +/mob/living/proc/get_bank_account() RETURN_TYPE(/datum/bank_account) var/datum/bank_account/account var/obj/item/card/id/I = get_idcard() - if(I && I.registered_account) + if(I?.registered_account) account = I.registered_account return account - return FALSE +/mob/living/proc/toggle_resting() + set name = "Rest" + set category = "IC" + + set_resting(!resting, FALSE) /mob/living/carbon/human/can_see_reagents() . = ..()