Cargo bounty cube incentives (#56375)

Bounty cube announces its creation over Supply with its creator and
area, starting the speedy delivery bonus countdown
20% bonus for cargo if you send the cube within 5 minutes of its
creation.

Using an export scanner on it in the supply shuttle awards a 10%
personal handling tip when it reaches Centcom.

Cube nags at five minutes over Supply if it's not sent and cargo bonus
is lost.

All nags tell you the cube's area

Co-authored-by: coiax <yellowbounder@gmail.com>
This commit is contained in:
cacogen
2021-02-10 10:17:11 +00:00
committed by GitHub
co-authored by coiax
parent f9fe234cd1
commit 29bc9174bd
4 changed files with 127 additions and 16 deletions
+16 -8
View File
@@ -1,13 +1,18 @@
/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, list(COMSIG_ITEM_SOLD), .proc/split_profit)
RegisterSignal(parent, list(COMSIG_STRUCTURE_UNWRAPPED, COMSIG_ITEM_UNWRAPPED), .proc/Unwrapped)
RegisterSignal(parent, list(COMSIG_ITEM_SPLIT_PROFIT, COMSIG_ITEM_SPLIT_PROFIT_DRY), .proc/return_ratio)
@@ -22,10 +27,13 @@
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
+89 -6
View File
@@ -100,13 +100,10 @@
status_report += "Bounty completed! Please give your bounty cube to cargo for your automated payout shortly."
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 <i>[reward.bounty_name]</i> 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("<span class='notice'>[pad] activates!</span>")
flick(pad.sending_state,pad)
pad.icon_state = pad.idle_state
@@ -247,10 +244,96 @@
icon_state = "bounty_cube"
///Value of the bounty that this bounty cube sells for.
var/bounty_value = 0
///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
///Who completed the bounty.
var/bounty_holder
///What job the bounty holder had.
var/bounty_holder_job
///What the bounty was for.
var/bounty_name
///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)
. += "<span class='notice'><b>[time2text(next_nag_time - world.time,"mm:ss")]</b> remains until <b>[bounty_value * speed_bonus]</b> credit speedy delivery bonus lost.</span>"
if(handler_tip && !bounty_handler_account)
. += "<span class='notice'>Scan this in the cargo shuttle with an export scanner to register your bank account for the <b>[bounty_value * handler_tip]</b> credit handling tip.</span>"
/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 <b>[get_area(src)]</b>.")
if(bounty_handler_account)
bounty_handler_account.bank_card_talk("\The [src] is unsent in <b>[get_area(src)]</b>.")
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 <i>[bounty_holder] ([bounty_holder_job])</i>'s reward for completing the <i>[bounty_name]</i> 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, "<span class='warning'>You aren't eligible to use this!</span>")
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, "<span class='notice'>It can't detect your bank account.</span>")
return ..()
///Beacon to launch a new bounty setup when activated.
/obj/item/civ_bounty_beacon
+21 -1
View File
@@ -13,9 +13,9 @@
. = ..()
if(!istype(O) || !proximity)
return
// Before you fix it:
// yes, checking manifests is a part of intended functionality.
var/datum/export_report/ex = export_item_and_contents(O, dry_run=TRUE)
var/price = 0
for(var/x in ex.total_amount)
@@ -24,3 +24,23 @@
to_chat(user, "<span class='notice'>Scanned [O], value: <b>[price]</b> credits[O.contents.len ? " (contents included)" : ""].</span>")
else
to_chat(user, "<span class='warning'>Scanned [O], no export value.</span>")
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, "<span class='warning'>Shuttle placement not detected. Handling tip not registered.</span>")
else if(cube.bounty_handler_account)
to_chat(user, "<span class='warning'>Bank account for handling tip already registered!</span>")
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 ? "<b>[price * cube.handler_tip]</b> credit " : ""]handling tip successfully registered.")
cube.bounty_holder_account.bank_card_talk("<b>[cube]</b> was scanned in \the <b>[get_area(cube)]</b> by <b>[scan_human] ([scan_human.job])</b>.")
else
to_chat(user, "<span class='warning'>Bank account not detected. Handling tip not registered.</span>")
@@ -5,4 +5,4 @@
export_types = list(/obj/item/bounty_cube)
/datum/export/bounty_box/get_cost(obj/item/bounty_cube/cube, apply_elastic)
return cube.bounty_value
return cube.bounty_value + (cube.bounty_value * (cube.speed_bonus / 100))