mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
[MIRROR] Fixes DNA Infuser's brain swapping, a little bit of qol, ui reworked [MDB IGNORE] (#17844)
* Fixes DNA Infuser's brain swapping, a little bit of qol, ui reworked * conflicts * fix the bad Co-authored-by: tralezab <40974010+tralezab@users.noreply.github.com> Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>
This commit is contained in:
co-authored by
tralezab
Tom
parent
d484d7b188
commit
c681cee605
@@ -831,6 +831,16 @@
|
||||
UNTYPED_LIST_ADD(keys, key)
|
||||
return keys
|
||||
|
||||
/// Turns an associative list into a flat list of keys, but for sprite accessories, respecting the locked variable
|
||||
/proc/assoc_to_keys_features(list/input)
|
||||
var/list/keys = list()
|
||||
for(var/key in input)
|
||||
var/datum/sprite_accessory/value = input[key]
|
||||
if(value?.locked)
|
||||
continue
|
||||
UNTYPED_LIST_ADD(keys, key)
|
||||
return keys
|
||||
|
||||
///compare two lists, returns TRUE if they are the same
|
||||
/proc/compare_list(list/l,list/d)
|
||||
if(!islist(l) || !islist(d))
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
var/atom/movable/infusing_from
|
||||
///what we're turning into
|
||||
var/datum/infuser_entry/infusing_into
|
||||
///a message for relaying that the machine is locked if someone tries to leave while it's active
|
||||
COOLDOWN_DECLARE(message_cooldown)
|
||||
|
||||
/obj/machinery/dna_infuser/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -38,11 +40,13 @@
|
||||
. += span_notice("Missing [span_bold("an infusion source")].")
|
||||
else
|
||||
. += span_notice("[span_bold(infusing_from.name)] is in the infusion slot.")
|
||||
. += span_notice("To operate: Obtain dead creature. Depending on size, drag or drop into the infuser slot.")
|
||||
. += span_notice("Subject enters the chamber, someone activates the machine. Voila! One of your organs has... changed!")
|
||||
. += span_notice("Alt-click to eject the infusion source, if one is inside.")
|
||||
|
||||
/obj/machinery/dna_infuser/interact(mob/user)
|
||||
if(user == occupant)
|
||||
balloon_alert(user, "can't reach!")
|
||||
toggle_open(user)
|
||||
return
|
||||
if(infusing)
|
||||
balloon_alert(user, "not while it's on!")
|
||||
@@ -64,6 +68,7 @@
|
||||
if(!infusing_into)
|
||||
//no valid recipe, so you get a fly mutation
|
||||
infusing_into = GLOB.infuser_entries[1]
|
||||
playsound(src, 'sound/machines/blender.ogg', 50, TRUE)
|
||||
to_chat(hoccupant, span_danger("Little needles repeatedly prick you! And with each prick, you feel yourself becoming more... [infusing_into.infusion_desc]?"))
|
||||
hoccupant.take_overall_damage(10)
|
||||
Shake(15, 15, INFUSING_TIME)
|
||||
@@ -93,7 +98,16 @@
|
||||
if(potential_new_organs.len)
|
||||
var/obj/item/organ/new_organ = pick(potential_new_organs)
|
||||
new_organ = new new_organ()
|
||||
new_organ.Insert(target, special = TRUE, drop_if_replaced = FALSE)
|
||||
if(istype(new_organ, /obj/item/organ/internal/brain))
|
||||
// brains REALLY like ghosting people. we need special tricks to avoid that, namely removing the old brain with no_id_transfer
|
||||
var/obj/item/organ/internal/brain/new_brain = new_organ
|
||||
var/obj/item/organ/internal/brain/old_brain = target.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(old_brain)
|
||||
old_brain.Remove(target, special = TRUE, no_id_transfer = TRUE)
|
||||
qdel(old_brain)
|
||||
new_brain.Insert(target, special = TRUE, drop_if_replaced = FALSE, no_id_transfer = TRUE)
|
||||
else
|
||||
new_organ.Insert(target, special = TRUE, drop_if_replaced = FALSE)
|
||||
infusing_into = null
|
||||
QDEL_NULL(infusing_from)
|
||||
|
||||
@@ -147,6 +161,21 @@
|
||||
add_infusion_item(used, user)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/dna_infuser/relaymove(mob/living/user, direction)
|
||||
if(user.stat)
|
||||
if(COOLDOWN_FINISHED(src, message_cooldown))
|
||||
COOLDOWN_START(src, message_cooldown, 4 SECONDS)
|
||||
to_chat(user, span_warning("[src]'s door won't budge!"))
|
||||
return
|
||||
if(infusing)
|
||||
if(COOLDOWN_FINISHED(src, message_cooldown))
|
||||
COOLDOWN_START(src, message_cooldown, 4 SECONDS)
|
||||
to_chat(user, span_danger("[src]'s door won't budge while all the needles are infusing you!"))
|
||||
return
|
||||
open_machine(drop = FALSE)
|
||||
//we set drop to false to manually call it with an allowlist
|
||||
dump_inventory_contents(list(occupant))
|
||||
|
||||
// mostly good for dead mobs that turn into items like dead mice (smack to add)
|
||||
/obj/machinery/dna_infuser/proc/add_infusion_item(obj/item/target, mob/user)
|
||||
if(!is_valid_infusion(target, user))
|
||||
@@ -163,6 +192,11 @@
|
||||
if(user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || !ISADVANCEDTOOLUSER(user))
|
||||
return
|
||||
|
||||
if(iscarbon(target))
|
||||
if(ishuman(target))
|
||||
close_machine(target)
|
||||
return
|
||||
|
||||
if(!is_valid_infusion(target, user))
|
||||
return
|
||||
|
||||
@@ -170,6 +204,7 @@
|
||||
infusing_from.forceMove(src)
|
||||
|
||||
/obj/machinery/dna_infuser/proc/is_valid_infusion(atom/movable/target, mob/user)
|
||||
var/datum/component/edible/food_comp = IS_EDIBLE(target)
|
||||
if(infusing_from)
|
||||
balloon_alert(user, "empty the machine first!")
|
||||
return FALSE
|
||||
@@ -178,9 +213,8 @@
|
||||
if(living_target.stat != DEAD)
|
||||
balloon_alert(user, "only dead creatures!")
|
||||
return FALSE
|
||||
else if(istype(target, /obj/item/food))
|
||||
var/obj/item/food/food_target = target
|
||||
if(!(food_target.foodtypes & GORE))
|
||||
else if(food_comp)
|
||||
if(!(food_comp.foodtypes & GORE))
|
||||
balloon_alert(user, "only creatures!")
|
||||
return FALSE
|
||||
else
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/// A list of all infuser entries
|
||||
GLOBAL_LIST_INIT(infuser_entries, prepare_entries())
|
||||
|
||||
/// just clarifying that no threshold does some special stuff, since only meme mutants have it
|
||||
#define NO_THRESHOLD ""
|
||||
|
||||
/proc/prepare_entries()
|
||||
var/list/entries = list()
|
||||
//regardless of names we want the failed mutant case to show first
|
||||
@@ -24,7 +27,7 @@ GLOBAL_LIST_INIT(infuser_entries, prepare_entries())
|
||||
var/infuse_mob_name = "rejected creature"
|
||||
/// general desc
|
||||
var/desc = "For whatever reason, when the body rejects DNA, the DNA goes sour, ending up as some kind of fly-like DNA jumble."
|
||||
/// desc of what passing the threshold gets you
|
||||
/// desc of what passing the threshold gets you. if this is empty, there is no threshold, so this is also really a tally of whether this is a "meme" mutant or not
|
||||
var/threshold_desc = "the DNA mess takes over, and you become a full-fledged flyperson."
|
||||
/// various little bits
|
||||
var/list/qualities = list(
|
||||
@@ -96,11 +99,13 @@ GLOBAL_LIST_INIT(infuser_entries, prepare_entries())
|
||||
)
|
||||
infusion_desc = "nomadic"
|
||||
|
||||
// just some meme entries, these basically encourage killing staff pets but do not play with the organ bonus system
|
||||
|
||||
/datum/infuser_entry/felinid
|
||||
name = "Cat"
|
||||
infuse_mob_name = "feline"
|
||||
desc = "EVERYONE CALM DOWN! I'm not implying anything with this entry. Are we really so surprised that felinids are humans with mixed feline DNA?"
|
||||
threshold_desc = "nothing happens. I guess this is why it's a big genetic craze, feline DNA is notably stable."
|
||||
threshold_desc = NO_THRESHOLD
|
||||
qualities = list(
|
||||
"oh, let me guess, you're a big fan of those japanese tourist bots",
|
||||
)
|
||||
@@ -117,7 +122,7 @@ GLOBAL_LIST_INIT(infuser_entries, prepare_entries())
|
||||
name = "Fox"
|
||||
infuse_mob_name = "vulpini"
|
||||
desc = "Foxes are now quite rare because of the \"fox ears\" craze back in 2555. I mean, also because we're spacefarers who destroyed foxes' natural habitats ages ago, but that applies to most animals."
|
||||
threshold_desc = "nothing happens. Stable DNA."
|
||||
threshold_desc = NO_THRESHOLD
|
||||
qualities = list(
|
||||
"oh come on really",
|
||||
"you bring SHAME to all geneticists",
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
/obj/item/organ/internal/lungs/carp
|
||||
name = "mutated carp-lungs"
|
||||
desc = "Carp DNA infused into what was once some normal lungs."
|
||||
safe_oxygen_max = 16
|
||||
safe_oxygen_min = 0
|
||||
safe_oxygen_min = 0 //we don't breathe this!
|
||||
|
||||
icon = 'icons/obj/medical/organs/infuser_organs.dmi'
|
||||
icon_state = "lungs"
|
||||
@@ -54,10 +53,9 @@
|
||||
return
|
||||
var/mob/living/carbon/human/human_receiver = tongue_owner
|
||||
var/datum/species/rec_species = human_receiver.dna.species
|
||||
if(!(rec_species.no_equip_flags & ITEM_SLOT_MASK))
|
||||
rec_species.no_equip_flags += ITEM_SLOT_MASK
|
||||
rec_species.update_no_equip_flags(tongue_owner, rec_species.no_equip_flags | ITEM_SLOT_MASK)
|
||||
var/obj/item/bodypart/head/head = human_receiver.get_bodypart(BODY_ZONE_HEAD)
|
||||
head.unarmed_damage_low = 10 // Yeah, biteing is pretty weak, blame the monkey super-nerf
|
||||
head.unarmed_damage_low = 10
|
||||
head.unarmed_damage_high = 15
|
||||
head.unarmed_stun_threshold = 15
|
||||
|
||||
@@ -67,8 +65,7 @@
|
||||
return
|
||||
var/mob/living/carbon/human/human_receiver = tongue_owner
|
||||
var/datum/species/rec_species = human_receiver.dna.species
|
||||
if(!(initial(rec_species.no_equip_flags) & ITEM_SLOT_MASK))
|
||||
rec_species.no_equip_flags -= ITEM_SLOT_MASK
|
||||
rec_species.update_no_equip_flags(tongue_owner, initial(rec_species.no_equip_flags))
|
||||
var/obj/item/bodypart/head/head = human_receiver.get_bodypart(BODY_ZONE_HEAD)
|
||||
head.unarmed_damage_low = initial(head.unarmed_damage_low)
|
||||
head.unarmed_damage_high = initial(head.unarmed_damage_high)
|
||||
@@ -76,7 +73,7 @@
|
||||
|
||||
/obj/item/organ/internal/tongue/carp/on_life(delta_time, times_fired)
|
||||
. = ..()
|
||||
if(!prob(1))
|
||||
if(owner.stat != CONSCIOUS || !prob(0.1))
|
||||
return
|
||||
owner.emote("cough")
|
||||
var/turf/tooth_fairy = get_turf(owner)
|
||||
@@ -147,4 +144,8 @@
|
||||
AddElement(/datum/element/noticable_organ, "skin has small patches of scales growing...")
|
||||
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/carp)
|
||||
|
||||
#undef CARP_ORGAN_COLOR
|
||||
#undef CARP_SCLERA_COLOR
|
||||
#undef CARP_PUPIL_COLOR
|
||||
|
||||
#undef CARP_COLORS
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
icon_state = "brain-x-d"
|
||||
var/datum/action/cooldown/spell/jaunt/shadow_walk/our_jaunt
|
||||
|
||||
/obj/item/organ/internal/brain/shadow/nightmare/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
|
||||
/obj/item/organ/internal/brain/shadow/nightmare/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE)
|
||||
. = ..()
|
||||
if(M.dna.species.id != SPECIES_NIGHTMARE)
|
||||
M.set_species(/datum/species/shadow/nightmare)
|
||||
|
||||
@@ -469,6 +469,8 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
|
||||
|
||||
for (var/name in sprite_accessories)
|
||||
var/datum/sprite_accessory/sprite_accessory = sprite_accessories[name]
|
||||
if(sprite_accessory.locked)
|
||||
continue
|
||||
|
||||
var/icon/final_icon
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
relevant_species_trait = FACEHAIR
|
||||
|
||||
/datum/preference/choiced/facial_hair_gradient/init_possible_values()
|
||||
return assoc_to_keys(GLOB.facial_hair_gradients_list)
|
||||
return assoc_to_keys_features(GLOB.facial_hair_gradients_list)
|
||||
|
||||
/datum/preference/choiced/facial_hair_gradient/apply_to_human(mob/living/carbon/human/target, value)
|
||||
LAZYSETLEN(target.grad_style, GRADIENTS_LEN)
|
||||
@@ -155,7 +155,7 @@
|
||||
relevant_species_trait = HAIR
|
||||
|
||||
/datum/preference/choiced/hair_gradient/init_possible_values()
|
||||
return assoc_to_keys(GLOB.hair_gradients_list)
|
||||
return assoc_to_keys_features(GLOB.hair_gradients_list)
|
||||
|
||||
/datum/preference/choiced/hair_gradient/apply_to_human(mob/living/carbon/human/target, value)
|
||||
LAZYSETLEN(target.grad_style, GRADIENTS_LEN)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
relevant_external_organ = /obj/item/organ/external/tail/cat
|
||||
|
||||
/datum/preference/choiced/tail_human/init_possible_values()
|
||||
return assoc_to_keys(GLOB.sprite_accessories["tail"])
|
||||
return assoc_to_keys_features(GLOB.tails_list_human)
|
||||
|
||||
/datum/preference/choiced/tail_human/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["tail_cat"] = value
|
||||
@@ -24,7 +24,7 @@
|
||||
relevant_mutant_bodypart = "ears"
|
||||
|
||||
/datum/preference/choiced/ears/init_possible_values()
|
||||
return GLOB.sprite_accessories["ears"]
|
||||
return assoc_to_keys_features(GLOB.ears_list)
|
||||
|
||||
/datum/preference/choiced/ears/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["ears"] = value
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
relevant_mutant_bodypart = "legs"
|
||||
|
||||
/datum/preference/choiced/lizard_legs/init_possible_values()
|
||||
return assoc_to_keys(GLOB.legs_list)
|
||||
return assoc_to_keys_features(GLOB.legs_list)
|
||||
|
||||
/datum/preference/choiced/lizard_legs/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["legs"] = value
|
||||
@@ -123,7 +123,7 @@
|
||||
relevant_mutant_bodypart = "spines"
|
||||
|
||||
/datum/preference/choiced/lizard_spines/init_possible_values()
|
||||
return assoc_to_keys(GLOB.spines_list)
|
||||
return assoc_to_keys_features(GLOB.spines_list)
|
||||
|
||||
/datum/preference/choiced/lizard_spines/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["spines"] = value
|
||||
@@ -135,7 +135,7 @@
|
||||
relevant_external_organ = /obj/item/organ/external/tail/lizard
|
||||
|
||||
/datum/preference/choiced/lizard_tail/init_possible_values()
|
||||
return assoc_to_keys(GLOB.tails_list_lizard)
|
||||
return assoc_to_keys_features(GLOB.tails_list_lizard)
|
||||
|
||||
/datum/preference/choiced/lizard_tail/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["tail_lizard"] = value
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
for (var/antennae_name in GLOB.moth_antennae_list)
|
||||
var/datum/sprite_accessory/antennae = GLOB.moth_antennae_list[antennae_name]
|
||||
if(antennae.locked)
|
||||
continue
|
||||
|
||||
var/icon/icon_with_antennae = new(moth_head)
|
||||
icon_with_antennae.Blend(icon(antennae.icon, "m_moth_antennae_[antennae.icon_state]_FRONT"), ICON_OVERLAY)
|
||||
@@ -57,6 +59,8 @@
|
||||
|
||||
for (var/markings_name in GLOB.moth_markings_list)
|
||||
var/datum/sprite_accessory/markings = GLOB.moth_markings_list[markings_name]
|
||||
if(markings.locked)
|
||||
continue
|
||||
var/icon/icon_with_markings = new(moth_body)
|
||||
|
||||
if (markings_name != "None")
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
for (var/pod_name in GLOB.pod_hair_list)
|
||||
var/datum/sprite_accessory/pod_hair = GLOB.pod_hair_list[pod_name]
|
||||
if(pod_hair.locked)
|
||||
continue
|
||||
|
||||
var/icon/icon_with_hair = new(pod_head)
|
||||
var/icon/icon_adj = icon(pod_hair.icon, "m_pod_hair_[pod_hair.icon_state]_ADJ")
|
||||
@@ -27,7 +29,7 @@
|
||||
return values
|
||||
|
||||
/datum/preference/choiced/pod_hair/create_default_value()
|
||||
return pick(GLOB.pod_hair_list)
|
||||
return pick(assoc_to_keys_features(GLOB.pod_hair_list))
|
||||
|
||||
/datum/preference/choiced/pod_hair/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["pod_hair"] = value
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
from doing this unless you absolutely know what you are doing, and have defined a
|
||||
conversion in savefile.dm
|
||||
*/
|
||||
/proc/init_sprite_accessory_subtypes(prototype, list/L, list/male, list/female,roundstart = FALSE, add_blank)//Roundstart argument builds a specific list for roundstart parts where some parts may be locked
|
||||
/proc/init_sprite_accessory_subtypes(prototype, list/L, list/male, list/female, add_blank)//Roundstart argument builds a specific list for roundstart parts where some parts may be locked
|
||||
if(!istype(L))
|
||||
L = list()
|
||||
if(!istype(male))
|
||||
@@ -25,10 +25,6 @@
|
||||
female = list()
|
||||
|
||||
for(var/path in subtypesof(prototype))
|
||||
if(roundstart)
|
||||
var/datum/sprite_accessory/P = path
|
||||
if(initial(P.locked))
|
||||
continue
|
||||
var/datum/sprite_accessory/D = new path()
|
||||
|
||||
if(D.icon_state)
|
||||
@@ -1863,6 +1859,7 @@
|
||||
icon_state = "fox"
|
||||
hasinner = TRUE
|
||||
color_src = HAIR
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/wings/none
|
||||
name = "None"
|
||||
|
||||
@@ -433,6 +433,11 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
if(!equipped_item.mob_can_equip(wearer, equipped_item_slot, bypass_equip_delay_self = TRUE, ignore_equipped = TRUE))
|
||||
wearer.dropItemToGround(equipped_item)
|
||||
|
||||
/datum/species/proc/update_no_equip_flags(mob/living/carbon/wearer, new_flags)
|
||||
no_equip_flags = new_flags
|
||||
wearer.hud_used?.update_locked_slots()
|
||||
worn_items_fit_body_check(wearer)
|
||||
|
||||
/**
|
||||
* Proc called when a carbon becomes this species.
|
||||
*
|
||||
|
||||
@@ -230,7 +230,7 @@
|
||||
UpdateButtons()
|
||||
|
||||
|
||||
/obj/item/organ/internal/brain/primate/Insert(mob/living/carbon/primate, special = FALSE, drop_if_replaced = FALSE)
|
||||
/obj/item/organ/internal/brain/primate/Insert(mob/living/carbon/primate, special = FALSE, drop_if_replaced = FALSE, no_id_transfer = FALSE)
|
||||
. = ..()
|
||||
RegisterSignal(primate, COMSIG_MOVABLE_CROSS, PROC_REF(on_crossed), TRUE)
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
return (passed_initial_check || overriding) && part_enabled
|
||||
|
||||
/datum/preference/choiced/mutant_choice/init_possible_values()
|
||||
return assoc_to_keys(GLOB.sprite_accessories[relevant_mutant_bodypart])
|
||||
return assoc_to_keys_features(GLOB.sprite_accessories[relevant_mutant_bodypart])
|
||||
|
||||
/datum/preference/choiced/mutant_choice/create_default_value()
|
||||
return initial(default_accessory_type?.name) || "None"
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
return initial(default_accessory_type?.name) || "None"
|
||||
|
||||
/datum/preference/choiced/genital/init_possible_values()
|
||||
return assoc_to_keys(GLOB.sprite_accessories[relevant_mutant_bodypart])
|
||||
return assoc_to_keys_features(GLOB.sprite_accessories[relevant_mutant_bodypart])
|
||||
|
||||
/datum/preference/toggle/genital_skin_tone
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
/datum/preference/choiced/digitigrade_legs/init_possible_values()
|
||||
return assoc_to_keys(GLOB.sprite_accessories["legs"])
|
||||
return assoc_to_keys_features(GLOB.sprite_accessories["legs"])
|
||||
|
||||
/datum/preference/choiced/digitigrade_legs/is_accessible(datum/preferences/preferences)
|
||||
return ..() && is_usable(preferences)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#define SYNTH_EMP_BRAIN_DAMAGE_LIGHT 12
|
||||
#define SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM 75
|
||||
|
||||
/obj/item/organ/internal/brain/ipc_positron/Insert(mob/living/carbon/user, special = 0, drop_if_replaced = TRUE)
|
||||
/obj/item/organ/internal/brain/ipc_positron/Insert(mob/living/carbon/user, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE)
|
||||
..()
|
||||
if(user.stat == DEAD && ishuman(user))
|
||||
var/mob/living/carbon/human/user_human = user
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { BlockQuote, Box, Section, Stack } from '../components';
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { BlockQuote, Box, Button, Section, Stack } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
import { multiline } from 'common/string';
|
||||
|
||||
type Entry = {
|
||||
name: string;
|
||||
@@ -17,40 +18,126 @@ type DnaInfuserData = {
|
||||
export const InfuserBook = (props, context) => {
|
||||
const { data } = useBackend<DnaInfuserData>(context);
|
||||
const { entries } = data;
|
||||
const [entryIndex, setEntryIndex] = useLocalState(context, 'entry', 0);
|
||||
|
||||
const wrapEntries = (newIndex) => {
|
||||
if (newIndex < 0) {
|
||||
newIndex = entries.length - 1;
|
||||
} else if (newIndex > entries.length - 1) {
|
||||
newIndex = 0;
|
||||
}
|
||||
setEntryIndex(newIndex);
|
||||
};
|
||||
|
||||
return (
|
||||
<Window width={620} height={320}>
|
||||
<Window.Content scrollable>
|
||||
<Window title="DNA Infusion Manual" width={620} height={550}>
|
||||
<Window.Content>
|
||||
<Stack vertical>
|
||||
{entries.map((entry) => {
|
||||
return (
|
||||
<Stack.Item key={entry.name}>
|
||||
<InfuserEntry entry={entry} />
|
||||
<Stack.Item>
|
||||
<InfuserInstructions />
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<InfuserEntry entry={entries[entryIndex]} />
|
||||
</Stack.Item>
|
||||
<Stack.Item textAlign="center">
|
||||
<Stack fontSize="18px" fill>
|
||||
<Stack.Item grow={2}>
|
||||
<Button onClick={() => wrapEntries(entryIndex - 1)} fluid>
|
||||
Last Entry
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
);
|
||||
})}
|
||||
<Stack.Item grow={1}>
|
||||
<Section fitted fill pt="3px">
|
||||
Entry {entryIndex + 1}/{entries.length}
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow={2}>
|
||||
<Button onClick={() => wrapEntries(entryIndex + 1)} fluid>
|
||||
Next Entry
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
export const InfuserInstructions = (props, context) => {
|
||||
return (
|
||||
<Section title="DNA Infusion Guide">
|
||||
<Stack vertical>
|
||||
<Stack.Item fontSize="16px">What does it do?</Stack.Item>
|
||||
<Stack.Item color="label">
|
||||
DNA Infusion is the practice of integrating dead creature DNA into
|
||||
yourself, mutating one of your organs into a genetic slurry that sits
|
||||
somewhere between being yours or the creature's. While this does
|
||||
bring you further away from being human, and gives a slew of...
|
||||
unfortunate side effects, it also grants new capabilities.{' '}
|
||||
<b>
|
||||
Above all else, you have to understand that gene-mutants are usually
|
||||
very good at specific things, especially with their threshold
|
||||
bonuses.
|
||||
</b>
|
||||
</Stack.Item>
|
||||
<Stack.Item fontSize="16px">I'm sold! How do I do it?</Stack.Item>
|
||||
<Stack.Item color="label">
|
||||
1. Load a dead creature into the machine. This is what you're
|
||||
infusing from.
|
||||
<br />
|
||||
2. Enter the machine, like you would the DNA scanner.
|
||||
<br />
|
||||
3. Have someone activate the machine externally.
|
||||
<br />
|
||||
<Box inline color="white">
|
||||
And you're done! Note that the infusion source will be
|
||||
obliterated in the process.
|
||||
</Box>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
type InfuserEntryProps = {
|
||||
entry: Entry;
|
||||
};
|
||||
|
||||
const InfuserEntry = (props: InfuserEntryProps, context) => {
|
||||
const { entry } = props;
|
||||
const isLesser = !entry.threshold_desc;
|
||||
const lesserDesc = multiline`
|
||||
Lesser Mutants usually have a smaller list of potential mutations, and
|
||||
do not have bonuses for infusing many organs.
|
||||
`;
|
||||
const greaterDesc = multiline`
|
||||
Greater Mutants have more upsides and downsides in their organs, more organs
|
||||
to infuse overall, and come with special bonuses for infusing enough DNA
|
||||
into yourself.
|
||||
`;
|
||||
return (
|
||||
<Section>
|
||||
<Stack vertical>
|
||||
<Stack.Item fontSize={'18px'}>{entry.name} Mutant</Stack.Item>
|
||||
<Section
|
||||
fill
|
||||
title={entry.name + ' Mutant'}
|
||||
height="225px"
|
||||
buttons={
|
||||
<Button
|
||||
tooltip={isLesser ? lesserDesc : greaterDesc}
|
||||
icon={isLesser ? 'minus-circle' : 'plus-circle'}
|
||||
color={isLesser ? 'red' : 'green'}>
|
||||
{isLesser ? 'Lesser' : 'Greater'} Mutant
|
||||
</Button>
|
||||
}>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<BlockQuote>
|
||||
{entry.desc} If a subject infuses with enough DNA,{' '}
|
||||
{entry.threshold_desc}
|
||||
{entry.desc}{' '}
|
||||
{!isLesser && (
|
||||
<>If a subject infuses with enough DNA, {entry.threshold_desc}</>
|
||||
)}
|
||||
</BlockQuote>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Stack.Item grow>
|
||||
Qualities:
|
||||
{entry.qualities.map((quality) => {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user