diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 5a063b883a8..377a32af6ad 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -84,3 +84,6 @@ GLOBAL_LIST_INIT(heretic_start_knowledge,list(/datum/eldritch_knowledge/spell/ba #define PATH_RUST "Rust" #define PATH_FLESH "Flesh" #define PATH_VOID "Void" + +/// How much does it cost to reroll strains? +#define BLOB_REROLL_COST 40 diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index ebdadf4ac33..c22c060b6c0 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -93,17 +93,17 @@ /atom/movable/screen/blob/readapt_strain icon_state = "ui_chemswap" - name = "Readapt Strain (40)" + name = "Readapt Strain" desc = "Allows you to choose a new strain from 4 random choices for 40 resources." /atom/movable/screen/blob/readapt_strain/MouseEntered(location,control,params) if(hud?.mymob && isovermind(hud.mymob)) var/mob/camera/blob/B = hud.mymob if(B.free_strain_rerolls) - name = "Readapt Strain (FREE)" + name = "[initial(name)] (FREE)" desc = "Randomly rerolls your strain for free." else - name = initial(name) + name = "[initial(name)] ([BLOB_REROLL_COST])" desc = initial(desc) ..() diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 4391b24591f..7176c4c373d 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -51,9 +51,18 @@ GLOBAL_LIST_EMPTY(radial_menus) parent.finished = TRUE /datum/radial_menu - var/list/choices = list() //List of choice id's - var/list/choices_icons = list() //choice_id -> icon - var/list/choices_values = list() //choice_id -> choice + /// List of choice IDs + var/list/choices = list() + + /// choice_id -> icon + var/list/choices_icons = list() + + /// choice_id -> choice + var/list/choices_values = list() + + /// choice_id -> /datum/radial_menu_choice + var/list/choice_datums = list() + var/list/page_data = list() //list of choices per page @@ -188,6 +197,7 @@ GLOBAL_LIST_EMPTY(radial_menus) E.alpha = 255 E.mouse_opacity = MOUSE_OPACITY_ICON E.cut_overlays() + E.vis_contents.Cut() if(choice_id == NEXT_PAGE_ID) E.name = "Next Page" E.next_page = TRUE @@ -206,6 +216,12 @@ GLOBAL_LIST_EMPTY(radial_menus) E.next_page = FALSE if(choices_icons[choice_id]) E.add_overlay(choices_icons[choice_id]) + if (choice_datums[choice_id]) + var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id] + if (choice_datum.info) + var/obj/effect/abstract/info/info_button = new(E, choice_datum.info) + info_button.layer = ABOVE_HUD_LAYER + E.vis_contents += info_button /datum/radial_menu/New() close_button = new @@ -234,11 +250,17 @@ GLOBAL_LIST_EMPTY(radial_menus) var/I = extract_image(new_choices[E]) if(I) choices_icons[id] = I + + if (istype(new_choices[E], /datum/radial_menu_choice)) + choice_datums[id] = new_choices[E] setup_menu(use_tooltips) +/datum/radial_menu/proc/extract_image(to_extract_from) + if (istype(to_extract_from, /datum/radial_menu_choice)) + var/datum/radial_menu_choice/choice = to_extract_from + to_extract_from = choice.image -/datum/radial_menu/proc/extract_image(E) - var/mutable_appearance/MA = new /mutable_appearance(E) + var/mutable_appearance/MA = new /mutable_appearance(to_extract_from) if(MA) MA.layer = ABOVE_HUD_LAYER MA.appearance_flags |= RESET_TRANSFORM @@ -321,3 +343,15 @@ GLOBAL_LIST_EMPTY(radial_menus) if(!custom_check.Invoke()) return return answer + +/// Can be provided to choices in radial menus if you want to provide more information +/datum/radial_menu_choice + /// Required -- what to display for this button + var/image + + /// If provided, will display an info button that will put this text in your chat + var/info + +/datum/radial_menu_choice/Destroy(force, ...) + . = ..() + QDEL_NULL(image) diff --git a/code/game/objects/effects/info.dm b/code/game/objects/effects/info.dm new file mode 100644 index 00000000000..23f341c8a3c --- /dev/null +++ b/code/game/objects/effects/info.dm @@ -0,0 +1,26 @@ +/// An info button that, when clicked, puts some text in the user's chat +/obj/effect/abstract/info + name = "info" + icon = 'icons/effects/effects.dmi' + icon_state = "info" + + /// What should the info button display when clicked? + var/info_text + +/obj/effect/abstract/info/Initialize(mapload, info_text) + . = ..() + + if (!isnull(info_text)) + src.info_text = info_text + +/obj/effect/abstract/info/Click() + . = ..() + to_chat(usr, info_text) + +/obj/effect/abstract/info/MouseEntered() + . = ..() + icon_state = "info_hovered" + +/obj/effect/abstract/info/MouseExited() + . = ..() + icon_state = initial(icon_state) diff --git a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm index 5a2d9b5edef..4fa454a85e2 100644 --- a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm +++ b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm @@ -8,7 +8,7 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/ var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects var/effectdesc = null //any long, blob-tile specific effects var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp." - var/analyzerdesceffect = "N/A" + var/analyzerdesceffect var/blobbernaut_message = "slams" //blobbernaut attack verb var/message = "The blob strikes you" //message sent to any mob hit by the blob var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index cc71fbe536e..85abedf7e3a 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -43,6 +43,9 @@ GLOBAL_LIST_EMPTY(blob_nodes) var/announcement_time var/has_announced = FALSE + /// The list of strains the blob can reroll for. + var/list/strain_choices + /mob/camera/blob/Initialize(mapload, starting_points = 60) validate_location() blob_points = starting_points @@ -182,6 +185,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) BM.overmind = null BM.update_icons() GLOB.overminds -= src + QDEL_LIST_ASSOC_VAL(strain_choices) SSshuttle.clearHostileEnvironment(src) STOP_PROCESSING(SSobj, src) diff --git a/code/modules/antagonists/blob/powers.dm b/code/modules/antagonists/blob/powers.dm index e3cd629847c..e5388d1c8dc 100644 --- a/code/modules/antagonists/blob/powers.dm +++ b/code/modules/antagonists/blob/powers.dm @@ -1,3 +1,6 @@ +#define BLOB_REROLL_CHOICES 6 +#define BLOB_REROLL_RADIUS 60 + /mob/camera/blob/proc/can_buy(cost = 15) if(blob_points < cost) to_chat(src, "You cannot afford this, you need at least [cost] resources!") @@ -349,25 +352,54 @@ set category = "Blob" set name = "Reactive Strain Adaptation (40)" set desc = "Replaces your strain with a random, different one." - if(!rerolling && (free_strain_rerolls || can_buy(40))) - rerolling = TRUE - reroll_strain() - rerolling = FALSE - if(free_strain_rerolls) - free_strain_rerolls-- - last_reroll_time = world.time -/mob/camera/blob/proc/reroll_strain() - var/list/choices = list() - while (length(choices) < 6) - var/datum/blobstrain/bs = pick((GLOB.valid_blobstrains)) - choices[initial(bs.name)] = bs + if (!free_strain_rerolls && blob_points < BLOB_REROLL_COST) + to_chat(src, "You need at least [BLOB_REROLL_COST] resources to reroll your strain again!") + return - var/choice = input(usr, "Please choose a new strain","Strain") as anything in sortList(choices, /proc/cmp_typepaths_asc) - if (choice && choices[choice] && !QDELETED(src)) - var/datum/blobstrain/bs = choices[choice] - set_strain(bs) + open_reroll_menu() +/// Open the menu to reroll strains +/mob/camera/blob/proc/open_reroll_menu() + if (!strain_choices) + strain_choices = list() + + var/list/new_strains = GLOB.valid_blobstrains.Copy() + for (var/_ in 1 to BLOB_REROLL_CHOICES) + var/datum/blobstrain/strain = pick_n_take(new_strains) + + var/image/strain_icon = image('icons/mob/blob.dmi', "blob_core") + strain_icon.color = initial(strain.color) + + var/info_text = "[initial(strain.name)]" + info_text += "
[initial(strain.analyzerdescdamage)]" + if (!isnull(initial(strain.analyzerdesceffect))) + info_text += "
[initial(strain.analyzerdesceffect)]" + + var/datum/radial_menu_choice/choice = new + choice.image = strain_icon + choice.info = info_text + + strain_choices[initial(strain.name)] = choice + + var/strain_result = show_radial_menu(src, src, strain_choices, radius = BLOB_REROLL_RADIUS, tooltips = TRUE) + if (isnull(strain_result)) + return + + if (!free_strain_rerolls && !can_buy(BLOB_REROLL_COST)) + return + + for (var/_other_strain in GLOB.valid_blobstrains) + var/datum/blobstrain/other_strain = _other_strain + if (initial(other_strain.name) == strain_result) + set_strain(other_strain) + + if (free_strain_rerolls) + free_strain_rerolls -= 1 + + last_reroll_time = world.time + + return /mob/camera/blob/verb/blob_help() set category = "Blob" @@ -392,3 +424,6 @@ if(!placed && autoplace_max_time <= world.time) to_chat(src, "You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)].") to_chat(src, "You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen.") + +#undef BLOB_REROLL_CHOICES +#undef BLOB_REROLL_RADIUS diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm index 1d868f38cbe..027cbeef870 100644 --- a/code/modules/antagonists/blob/structures/_blob.dm +++ b/code/modules/antagonists/blob/structures/_blob.dm @@ -235,7 +235,7 @@ if(overmind) . += list("Material: [overmind.blobstrain.name].", "Material Effects: [overmind.blobstrain.analyzerdescdamage]", - "Material Properties: [overmind.blobstrain.analyzerdesceffect]") + "Material Properties: [overmind.blobstrain.analyzerdesceffect || "N/A"]") else . += "No Material Detected!" diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 017556c5725..4df910d6ec5 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/tgstation.dme b/tgstation.dme index a5a08dbcbb7..b03a47a0761 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -927,6 +927,7 @@ #include "code\game\objects\effects\effects.dm" #include "code\game\objects\effects\forcefields.dm" #include "code\game\objects\effects\glowshroom.dm" +#include "code\game\objects\effects\info.dm" #include "code\game\objects\effects\landmarks.dm" #include "code\game\objects\effects\mines.dm" #include "code\game\objects\effects\misc.dm"