mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-19 20:15:47 +01:00
Rerolling blob strains now uses a radial menu, and lets you see what the strain does before picking it (#55559)
Also provides a generic, forward proof way to provide information to radial menu choices.
Why It's Good For The Game
input is old and crummy.
Blob is a very wiki reliant mechanic. This moves a bit of it into the game itself to fix that.
Provides a real cancel option, whereas the old one had none. This is not a balance change, but a QoL one--everyone just moved the input window off to the side.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, "<span class='warning'>You cannot afford this, you need at least [cost] resources!</span>")
|
||||
@@ -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, "<span class='warning'>You need at least [BLOB_REROLL_COST] resources to reroll your strain again!</span>")
|
||||
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 = "<span class='boldnotice'>[initial(strain.name)]</span>"
|
||||
info_text += "<br><span class='notice'>[initial(strain.analyzerdescdamage)]</span>"
|
||||
if (!isnull(initial(strain.analyzerdesceffect)))
|
||||
info_text += "<br><span class='notice'>[initial(strain.analyzerdesceffect)]</span>"
|
||||
|
||||
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, "<span class='big'><font color=\"#EE4000\">You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)].</font></span>")
|
||||
to_chat(src, "<span class='big'><font color=\"#EE4000\">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.</font></span>")
|
||||
|
||||
#undef BLOB_REROLL_CHOICES
|
||||
#undef BLOB_REROLL_RADIUS
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
if(overmind)
|
||||
. += list("<b>Material: <font color=\"[overmind.blobstrain.color]\">[overmind.blobstrain.name]</font><span class='notice'>.</span></b>",
|
||||
"<b>Material Effects:</b> <span class='notice'>[overmind.blobstrain.analyzerdescdamage]</span>",
|
||||
"<b>Material Properties:</b> <span class='notice'>[overmind.blobstrain.analyzerdesceffect]</span>")
|
||||
"<b>Material Properties:</b> <span class='notice'>[overmind.blobstrain.analyzerdesceffect || "N/A"]</span>")
|
||||
else
|
||||
. += "<b>No Material Detected!</b>"
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 886 KiB After Width: | Height: | Size: 886 KiB |
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user