Merge pull request #4828 from Citadel-Station-13/upstream-merge-34246

[MIRROR] Added tooltips to roundend traitor purchase logs
This commit is contained in:
deathride58
2018-01-15 02:09:44 +00:00
committed by GitHub
4 changed files with 295 additions and 270 deletions

View File

@@ -1,203 +1,188 @@
GLOBAL_LIST_EMPTY(uplinks)
/**
* Uplinks
*
* All /obj/item(s) have a hidden_uplink var. By default it's null. Give the item one with 'new(src') (it must be in it's contents). Then add 'uses.'
* Use whatever conditionals you want to check that the user has an uplink, and then call interact() on their uplink.
* You might also want the uplink menu to open if active. Check if the uplink is 'active' and then interact() with it.
**/
/datum/component/uplink
dupe_mode = COMPONENT_DUPE_UNIQUE
var/name = "syndicate uplink"
var/active = FALSE
var/lockable = TRUE
var/locked = TRUE
var/telecrystals
var/selected_cat
var/owner = null
var/datum/game_mode/gamemode
var/datum/uplink_purchase_log/purchase_log
var/list/uplink_items
var/hidden_crystals = 0
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
GLOB.uplinks += src
uplink_items = get_uplink_items(gamemode)
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/interact)
owner = _owner
if(owner)
LAZYINITLIST(GLOB.uplink_purchase_logs_by_key)
if(GLOB.uplink_purchase_logs_by_key[owner])
purchase_log = GLOB.uplink_purchase_logs_by_key[owner]
else
purchase_log = new(owner, src)
lockable = _lockable
active = _enabled
gamemode = _gamemode
telecrystals = starting_tc
if(!lockable)
active = TRUE
locked = FALSE
/datum/component/uplink/InheritComponent(datum/component/uplink/U)
lockable |= U.lockable
active |= U.active
if(!gamemode)
gamemode = U.gamemode
telecrystals += U.telecrystals
if(purchase_log && U.purchase_log)
purchase_log.MergeWithAndDel(U.purchase_log)
/datum/component/uplink/Destroy()
GLOB.uplinks -= src
gamemode = null
return ..()
/datum/component/uplink/proc/LoadTC(mob/user, obj/item/stack/telecrystal/TC, silent = FALSE)
if(!silent)
to_chat(user, "<span class='notice'>You slot [TC] into [parent] and charge its internal uplink.</span>")
var/amt = TC.amount
telecrystals += amt
TC.use(amt)
/datum/component/uplink/proc/set_gamemode(_gamemode)
gamemode = _gamemode
uplink_items = get_uplink_items(gamemode)
/datum/component/uplink/proc/OnAttackBy(obj/item/I, mob/user)
if(!active)
return //no hitting everyone/everything just to try to slot tcs in!
if(istype(I, /obj/item/stack/telecrystal))
LoadTC(user, I)
for(var/item in subtypesof(/datum/uplink_item))
var/datum/uplink_item/UI = item
var/path = null
if(initial(UI.refund_path))
path = initial(UI.refund_path)
else
path = initial(UI.item)
var/cost = 0
if(initial(UI.refund_amount))
cost = initial(UI.refund_amount)
else
cost = initial(UI.cost)
var/refundable = initial(UI.refundable)
if(I.type == path && refundable && I.check_uplink_validity())
telecrystals += cost
purchase_log.total_spent -= cost
to_chat(user, "<span class='notice'>[I] refunded.</span>")
qdel(I)
return
/datum/component/uplink/proc/interact(mob/user)
if(locked)
return
active = TRUE
if(user)
ui_interact(user)
/datum/component/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
active = TRUE
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state)
ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input.
ui.set_style("syndicate")
ui.open()
/datum/component/uplink/ui_data(mob/user)
if(!user.mind)
return
var/list/data = list()
data["telecrystals"] = telecrystals
data["lockable"] = lockable
data["categories"] = list()
for(var/category in uplink_items)
var/list/cat = list(
"name" = category,
"items" = (category == selected_cat ? list() : null))
if(category == selected_cat)
for(var/item in uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(I.limited_stock == 0)
continue
if(I.restricted_roles.len)
var/is_inaccessible = 1
for(var/R in I.restricted_roles)
if(R == user.mind.assigned_role)
is_inaccessible = 0
if(is_inaccessible)
continue
cat["items"] += list(list(
"name" = I.name,
"cost" = I.cost,
"desc" = I.desc,
))
data["categories"] += list(cat)
return data
/datum/component/uplink/ui_act(action, params)
if(!active)
return
switch(action)
if("buy")
var/item = params["item"]
var/list/buyable_items = list()
for(var/category in uplink_items)
buyable_items += uplink_items[category]
if(item in buyable_items)
var/datum/uplink_item/I = buyable_items[item]
MakePurchase(usr, I)
. = TRUE
if("lock")
active = FALSE
locked = TRUE
telecrystals += hidden_crystals
hidden_crystals = 0
SStgui.close_uis(src)
if("select")
selected_cat = params["category"]
return TRUE
/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U)
if(!istype(U))
return
if (!user || user.incapacitated())
return
if(telecrystals < U.cost || U.limited_stock == 0)
return
telecrystals -= U.cost
var/atom/A = U.spawn_item(get_turf(user), src, user)
if(U.purchase_log_vis && purchase_log)
var/obj/item/storage/box/B = A
var/list/atom/logging = list()
if(istype(B) && B.contents.len > 0)
logging |= list(B)
else
logging |= A
for(var/atom/_logging in logging)
purchase_log.LogPurchase(_logging, U.cost)
if(U.limited_stock > 0)
U.limited_stock -= 1
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(U.name)]", "[U.cost]"))
if(ishuman(user) && istype(A, /obj/item))
var/mob/living/carbon/human/H = user
if(H.put_in_hands(A))
to_chat(H, "[A] materializes into your hands!")
else
to_chat(H, "\The [A] materializes onto the floor.")
return TRUE
GLOBAL_LIST_EMPTY(uplinks)
/**
* Uplinks
*
* All /obj/item(s) have a hidden_uplink var. By default it's null. Give the item one with 'new(src') (it must be in it's contents). Then add 'uses.'
* Use whatever conditionals you want to check that the user has an uplink, and then call interact() on their uplink.
* You might also want the uplink menu to open if active. Check if the uplink is 'active' and then interact() with it.
**/
/datum/component/uplink
dupe_mode = COMPONENT_DUPE_UNIQUE
var/name = "syndicate uplink"
var/active = FALSE
var/lockable = TRUE
var/locked = TRUE
var/telecrystals
var/selected_cat
var/owner = null
var/datum/game_mode/gamemode
var/datum/uplink_purchase_log/purchase_log
var/list/uplink_items
var/hidden_crystals = 0
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
GLOB.uplinks += src
uplink_items = get_uplink_items(gamemode)
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/interact)
owner = _owner
if(owner)
LAZYINITLIST(GLOB.uplink_purchase_logs_by_key)
if(GLOB.uplink_purchase_logs_by_key[owner])
purchase_log = GLOB.uplink_purchase_logs_by_key[owner]
else
purchase_log = new(owner, src)
lockable = _lockable
active = _enabled
gamemode = _gamemode
telecrystals = starting_tc
if(!lockable)
active = TRUE
locked = FALSE
/datum/component/uplink/InheritComponent(datum/component/uplink/U)
lockable |= U.lockable
active |= U.active
if(!gamemode)
gamemode = U.gamemode
telecrystals += U.telecrystals
if(purchase_log && U.purchase_log)
purchase_log.MergeWithAndDel(U.purchase_log)
/datum/component/uplink/Destroy()
GLOB.uplinks -= src
gamemode = null
return ..()
/datum/component/uplink/proc/LoadTC(mob/user, obj/item/stack/telecrystal/TC, silent = FALSE)
if(!silent)
to_chat(user, "<span class='notice'>You slot [TC] into [parent] and charge its internal uplink.</span>")
var/amt = TC.amount
telecrystals += amt
TC.use(amt)
/datum/component/uplink/proc/set_gamemode(_gamemode)
gamemode = _gamemode
uplink_items = get_uplink_items(gamemode)
/datum/component/uplink/proc/OnAttackBy(obj/item/I, mob/user)
if(!active)
return //no hitting everyone/everything just to try to slot tcs in!
if(istype(I, /obj/item/stack/telecrystal))
LoadTC(user, I)
for(var/item in subtypesof(/datum/uplink_item))
var/datum/uplink_item/UI = item
var/path = null
if(initial(UI.refund_path))
path = initial(UI.refund_path)
else
path = initial(UI.item)
var/cost = 0
if(initial(UI.refund_amount))
cost = initial(UI.refund_amount)
else
cost = initial(UI.cost)
var/refundable = initial(UI.refundable)
if(I.type == path && refundable && I.check_uplink_validity())
telecrystals += cost
purchase_log.total_spent -= cost
to_chat(user, "<span class='notice'>[I] refunded.</span>")
qdel(I)
return
/datum/component/uplink/proc/interact(mob/user)
if(locked)
return
active = TRUE
if(user)
ui_interact(user)
/datum/component/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
active = TRUE
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state)
ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input.
ui.set_style("syndicate")
ui.open()
/datum/component/uplink/ui_data(mob/user)
if(!user.mind)
return
var/list/data = list()
data["telecrystals"] = telecrystals
data["lockable"] = lockable
data["categories"] = list()
for(var/category in uplink_items)
var/list/cat = list(
"name" = category,
"items" = (category == selected_cat ? list() : null))
if(category == selected_cat)
for(var/item in uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(I.limited_stock == 0)
continue
if(I.restricted_roles.len)
var/is_inaccessible = 1
for(var/R in I.restricted_roles)
if(R == user.mind.assigned_role)
is_inaccessible = 0
if(is_inaccessible)
continue
cat["items"] += list(list(
"name" = I.name,
"cost" = I.cost,
"desc" = I.desc,
))
data["categories"] += list(cat)
return data
/datum/component/uplink/ui_act(action, params)
if(!active)
return
switch(action)
if("buy")
var/item = params["item"]
var/list/buyable_items = list()
for(var/category in uplink_items)
buyable_items += uplink_items[category]
if(item in buyable_items)
var/datum/uplink_item/I = buyable_items[item]
MakePurchase(usr, I)
. = TRUE
if("lock")
active = FALSE
locked = TRUE
telecrystals += hidden_crystals
hidden_crystals = 0
SStgui.close_uis(src)
if("select")
selected_cat = params["category"]
return TRUE
/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U)
if(!istype(U))
return
if (!user || user.incapacitated())
return
if(telecrystals < U.cost || U.limited_stock == 0)
return
telecrystals -= U.cost
U.purchase(user, src)
if(U.limited_stock > 0)
U.limited_stock -= 1
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(U.name)]", "[U.cost]"))
return TRUE

View File

@@ -10,7 +10,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
GLOB.uplink_items[I.category] = list()
GLOB.uplink_items[I.category][I.name] = I
/proc/get_uplink_items(var/datum/game_mode/gamemode = null)
/proc/get_uplink_items(var/datum/game_mode/gamemode = null, allow_sales = TRUE)
if(!GLOB.uplink_items.len)
initialize_global_uplink_items()
@@ -37,29 +37,29 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
if(!filtered_uplink_items[category])
filtered_uplink_items[category] = list()
filtered_uplink_items[category][item] = I
filtered_uplink_items[category][item] = new I.type()
if(I.limited_stock < 0 && !I.cant_discount && I.item && I.cost > 1)
sale_items += I
if(allow_sales)
for(var/i in 1 to 3)
var/datum/uplink_item/I = pick_n_take(sale_items)
var/datum/uplink_item/A = new I.type
var/discount = A.get_discount()
var/list/disclaimer = list("Void where prohibited.", "Not recommended for children.", "Contains small parts.", "Check local laws for legality in region.", "Do not taunt.", "Not responsible for direct, indirect, incidental or consequential damages resulting from any defect, error or failure to perform.", "Keep away from fire or flames.", "Product is provided \"as is\" without any implied or expressed warranties.", "As seen on TV.", "For recreational use only.", "Use only as directed.", "16% sales tax will be charged for orders originating within Space Nebraska.")
A.limited_stock = 1
I.refundable = FALSE //THIS MAN USES ONE WEIRD TRICK TO GAIN FREE TC, CODERS HATES HIM!
A.refundable = FALSE
if(A.cost >= 20) //Tough love for nuke ops
discount *= 0.5
A.cost = max(round(A.cost * discount),1)
A.category = "Discounted Gear"
A.name += " ([round(((initial(A.cost)-A.cost)/initial(A.cost))*100)]% off!)"
A.desc += " Normally costs [initial(A.cost)] TC. All sales final. [pick(disclaimer)]"
A.item = I.item
for(var/i in 1 to 3)
var/datum/uplink_item/I = pick_n_take(sale_items)
var/datum/uplink_item/A = new I.type
var/discount = A.get_discount()
var/list/disclaimer = list("Void where prohibited.", "Not recommended for children.", "Contains small parts.", "Check local laws for legality in region.", "Do not taunt.", "Not responsible for direct, indirect, incidental or consequential damages resulting from any defect, error or failure to perform.", "Keep away from fire or flames.", "Product is provided \"as is\" without any implied or expressed warranties.", "As seen on TV.", "For recreational use only.", "Use only as directed.", "16% sales tax will be charged for orders originating within Space Nebraska.")
A.limited_stock = 1
I.refundable = FALSE //THIS MAN USES ONE WEIRD TRICK TO GAIN FREE TC, CODERS HATES HIM!
A.refundable = FALSE
if(A.cost >= 20) //Tough love for nuke ops
discount *= 0.5
A.cost = max(round(A.cost * discount),1)
A.category = "Discounted Gear"
A.name += " ([round(((initial(A.cost)-A.cost)/initial(A.cost))*100)]% off!)"
A.desc += " Normally costs [initial(A.cost)] TC. All sales final. [pick(disclaimer)]"
A.item = I.item
if(!filtered_uplink_items[A.category])
filtered_uplink_items[A.category] = list()
filtered_uplink_items[A.category][A.name] = A
if(!filtered_uplink_items[A.category])
filtered_uplink_items[A.category] = list()
filtered_uplink_items[A.category][A.name] = A
return filtered_uplink_items
@@ -89,9 +89,26 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/proc/get_discount()
return pick(4;0.75,2;0.5,1;0.25)
/datum/uplink_item/proc/spawn_item(turf/loc, datum/component/uplink/U, mob/user)
if(item)
return new item(loc)
/datum/uplink_item/proc/purchase(mob/user, datum/component/uplink/U)
var/atom/A = spawn_item(item, user)
if(purchase_log_vis && U.purchase_log)
U.purchase_log.LogPurchase(A, src, cost)
/datum/uplink_item/proc/spawn_item(spawn_item, mob/user)
if(!spawn_item)
return
var/atom/A
if(ispath(spawn_item))
A = new spawn_item(get_turf(user))
else
A = spawn_item
if(ishuman(user) && istype(A, /obj/item))
var/mob/living/carbon/human/H = user
if(H.put_in_hands(A))
to_chat(H, "[A] materializes into your hands!")
return A
to_chat(user, "[A] materializes onto the floor.")
return A
/datum/uplink_item/Destroy()
if(src in GLOB.uplink_items)
@@ -943,15 +960,9 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
item = /obj/item/briefcase_launchpad
cost = 6
/datum/uplink_item/device_tools/briefcase_launchpad/spawn_item(turf/loc, datum/component/uplink/U, mob/user)
var/obj/item/device/launchpad_remote/L = new(loc) //free remote
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.put_in_hands(L))
to_chat(H, "[L] materializes into your hands!")
else
to_chat(H, "\The [L] materializes onto the floor.")
return ..()
/datum/uplink_item/device_tools/briefcase_launchpad/purchase(mob/user, datum/component/uplink/U)
spawn_item(/obj/item/device/launchpad_remote, user) //free remote
..()
/datum/uplink_item/device_tools/magboots
name = "Blood-Red Magboots"
@@ -1163,15 +1174,6 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
surplus = 0
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/cyber_implants/spawn_item(turf/loc, obj/item/device/uplink/U)
if(item)
if(istype(item, /obj/item/organ))
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(name)]", "[cost]"))
return new /obj/item/storage/box/cyber_implants(loc, item)
else
return ..()
/datum/uplink_item/cyber_implants/thermals
name = "Thermal Eyes"
desc = "These cybernetic eyes will give you thermal vision. Comes with a free autosurgeon."
@@ -1346,11 +1348,13 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
exclude_modes = list(/datum/game_mode/nuclear)
cant_discount = TRUE
/datum/uplink_item/badass/surplus/spawn_item(turf/loc, datum/component/uplink/U)
var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null)
/datum/uplink_item/badass/surplus/purchase(mob/user, datum/component/uplink/U)
var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null, FALSE)
var/crate_value = 50
var/obj/structure/closet/crate/C = new(loc)
var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user)
if(U.purchase_log)
U.purchase_log.LogPurchase(C, src, cost)
while(crate_value)
var/category = pick(uplink_items)
var/item = pick(uplink_items[category])
@@ -1362,9 +1366,8 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
continue
crate_value -= I.cost
var/obj/goods = new I.item(C)
U.purchase_log.LogPurchase(goods, I.cost)
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(name)]", "[cost]"))
if(U.purchase_log)
U.purchase_log.LogPurchase(goods, I, 0)
return C
/datum/uplink_item/badass/random
@@ -1374,8 +1377,8 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 0
cant_discount = TRUE
/datum/uplink_item/badass/random/spawn_item(turf/loc, datum/component/uplink/U)
var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null)
/datum/uplink_item/badass/random/purchase(mob/user, datum/component/uplink/U)
var/list/uplink_items = U.uplink_items
var/list/possible_items = list()
for(var/category in uplink_items)
for(var/item in uplink_items[category])
@@ -1384,12 +1387,11 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
continue
if(U.telecrystals < I.cost)
continue
if(I.limited_stock == 0)
continue
possible_items += I
if(possible_items.len)
var/datum/uplink_item/I = pick(possible_items)
U.telecrystals -= I.cost
U.purchase_log.total_spent += I.cost
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(I.name)]", "[cost]"))
SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name))
return new I.item(loc)
U.MakePurchase(user, I)

View File

@@ -30,12 +30,12 @@ GLOBAL_LIST(uplink_purchase_logs_by_key) //assoc key = /datum/uplink_purchase_lo
. = owner == other.owner
if(!.)
return
for(var/path in other.purchase_log)
if(!purchase_log[path])
purchase_log[path] = other.purchase_log[path]
for(var/hash in other.purchase_log)
if(!purchase_log[hash])
purchase_log[hash] = other.purchase_log[hash]
else
var/datum/uplink_purchase_entry/UPE = purchase_log[path]
var/datum/uplink_purchase_entry/UPE_O = other.purchase_log[path]
var/datum/uplink_purchase_entry/UPE = purchase_log[hash]
var/datum/uplink_purchase_entry/UPE_O = other.purchase_log[hash]
UPE.amount_purchased += UPE_O.amount_purchased
qdel(other)
@@ -44,23 +44,36 @@ GLOBAL_LIST(uplink_purchase_logs_by_key) //assoc key = /datum/uplink_purchase_lo
/datum/uplink_purchase_log/proc/generate_render(show_key = TRUE)
. = ""
for(var/path in purchase_log)
var/datum/uplink_purchase_entry/UPE = purchase_log[path]
. += "<big>\[[UPE.icon_b64][show_key?"([owner])":""]\]</big>"
for(var/hash in purchase_log)
var/datum/uplink_purchase_entry/UPE = purchase_log[hash]
. += "<span class='tooltip_container'>\[[UPE.icon_b64][show_key?"([owner])":""]<span class='tooltip_hover'><b>[UPE.name]</b><br>[UPE.spent_cost ? "[UPE.spent_cost] TC" : "[UPE.base_cost] TC<br>(Surplus)"]<br>[UPE.desc]</span>[(UPE.amount_purchased > 1) ? "x[UPE.amount_purchased]" : ""]\]</span>"
/datum/uplink_purchase_log/proc/LogPurchase(atom/A, cost)
/datum/uplink_purchase_log/proc/LogPurchase(atom/A, datum/uplink_item/uplink_item, spent_cost)
var/datum/uplink_purchase_entry/UPE
if(purchase_log[A.type])
UPE = purchase_log[A.type]
var/hash = hash_purchase(uplink_item, spent_cost)
if(purchase_log[hash])
UPE = purchase_log[hash]
else
UPE = new
purchase_log[A.type] = UPE
purchase_log[hash] = UPE
UPE.path = A.type
UPE.icon_b64 = "[icon2base64html(A)]"
UPE.desc = uplink_item.desc
UPE.name = uplink_item.name
UPE.base_cost = initial(uplink_item.cost)
UPE.spent_cost = spent_cost
UPE.amount_purchased++
total_spent += cost
total_spent += spent_cost
/datum/uplink_purchase_log/proc/hash_purchase(datum/uplink_item/uplink_item, spent_cost)
return "[uplink_item.type]|[uplink_item.name]|[uplink_item.cost]|[spent_cost]"
/datum/uplink_purchase_entry
var/amount_purchased = 0
var/path
var/icon_b64
var/desc
var/base_cost
var/spent_cost
var/name

View File

@@ -64,4 +64,29 @@ li {
body {
background-color: #272727;
color: #efefef;
}
.tooltip_container {
position: relative;
font-size: 24px;
}
.tooltip_hover {
visibility: hidden;
position: absolute;
background-color: black;
z-index: 1;
width: 220px;
font-size: 14px;
border-width: 4px;
border-style: solid;
border-color: #272727;
background: #363636;
color: white;
top: 100%;
left: 30px;
}
.tooltip_container:hover .tooltip_hover {
visibility: visible;
}