Skip to content

Commit

Permalink
[Ready] Fermichem part 2.3 Adds a new reagent: Eigenstasium (#56918)
Browse files Browse the repository at this point in the history
Co-authored-by: Rohesie <rohesie@gmail.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
  • Loading branch information
3 people committed Mar 27, 2021
1 parent b8a7dd9 commit 0500771
Show file tree
Hide file tree
Showing 30 changed files with 850 additions and 184 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/colors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@
#define COLOR_THEME_GLASS "#75A4C4"
#define COLOR_THEME_CLOCKWORK "#CFBA47"

///Colors for eigenstates
#define COLOR_PERIWINKLEE "#9999FF"
/**
* Some defines to generalise colours used in lighting.
*
Expand Down
10 changes: 10 additions & 0 deletions code/__DEFINES/dcs/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,16 @@
///from [/obj/structure/closet/supplypod/proc/preOpen]:
#define COMSIG_SUPPLYPOD_LANDED "supplypodgoboom"

///Closets
///From base of [/obj/structure/closet/proc/insert]: (atom/movable/inserted)
#define COMSIG_CLOSET_INSERT "closet_insert"
///used to interrupt insertion
#define COMPONENT_CLOSET_INSERT_INTERRUPT (1<<0)

///Eigenstasium
///From base of [/datum/controller/subsystem/eigenstates/proc/use_eigenlinked_atom]: (var/target)
#define COMSIG_EIGENSTATE_ACTIVATE "eigenstate_activate"

// /obj signals for economy
///called when the payment component tries to charge an account.
#define COMSIG_OBJ_ATTEMPT_CHARGE "obj_attempt_simple_charge"
Expand Down
8 changes: 8 additions & 0 deletions code/__DEFINES/status_effects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@

#define STATUS_EFFECT_REFRESH 3 // if it only allows one, and new instances just instead refresh the timer

///Processing flags - used to define the speed at which the status will work
///This is fast - 0.2s between ticks (I believe!)
#define STATUS_EFFECT_FAST_PROCESS 0
///This is slower and better for more intensive status effects - 1s between ticks
#define STATUS_EFFECT_NORMAL_PROCESS 1

///////////
// BUFFS //
///////////
Expand Down Expand Up @@ -127,6 +133,8 @@
#define STATUS_EFFECT_HIGHFIVE /datum/status_effect/high_fiving // you are angling for a high five

#define STATUS_EFFECT_SURRENDER /datum/status_effect/grouped/surrender // gives an alert to quickly surrender

#define STATUS_EFFECT_EIGEN /datum/status_effect/eigenstasium
/////////////
// SLIME //
/////////////
Expand Down
112 changes: 112 additions & 0 deletions code/controllers/subsystem/eigenstate.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
///Subsystem used to teleport people to a linked web of itterative entries. If one entry is deleted, the 2 around it will forge a link instead.
SUBSYSTEM_DEF(eigenstates)
name = "Eigenstates"
flags = SS_NO_INIT | SS_NO_FIRE
///The list of objects that something is linked to indexed by UID
var/list/eigen_targets = list()
///UID to object reference
var/list/eigen_id = list()
///Unique id counter
var/id_counter = 1
///Limit the number of sparks created when teleporting multiple atoms to 1
var/spark_time = 0

///Creates a new link of targets unique to their own id
/datum/controller/subsystem/eigenstates/proc/create_new_link(targets)
if(length(targets) <= 1)
return FALSE
for(var/atom/target as anything in targets) //Clear out any connected
var/already_linked = eigen_id[target]
if(!already_linked)
continue
if(length(eigen_targets[already_linked]) > 1) //Eigenstates are notorious for having cliques!
target.visible_message("[target] fizzes, it's already linked to something else!")
targets -= target
continue
target.visible_message("[target] fizzes, collapsing it's unique wavefunction into the others!") //If we're in a eigenlink all on our own and are open to new friends
remove_eigen_entry(target) //clearup for new stuff
//Do we still have targets?
if(!length(targets))
return FALSE
var/atom/visible_atom = targets[1] //The object that'll handle the messages
if(length(targets) == 1)
visible_atom.visible_message("[targets[1]] fizzes, there's nothing it can link to!")
return FALSE

eigen_targets["[id_counter]"] = list() //Add to the master list
for(var/atom/target as anything in targets)
eigen_targets["[id_counter]"] += target
eigen_id[target] = "[id_counter]"
RegisterSignal(target, COMSIG_CLOSET_INSERT, .proc/use_eigenlinked_atom)
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/remove_eigen_entry)
RegisterSignal(target, COMSIG_ATOM_TOOL_ACT(TOOL_WELDER), .proc/tool_interact)
target.RegisterSignal(target, COMSIG_EIGENSTATE_ACTIVATE, /obj/structure/closet/proc/bust_open)
var/obj/item = target
if(item)
item.color = COLOR_PERIWINKLEE //Tint the locker slightly.
item.alpha = 200
do_sparks(3, FALSE, item)

visible_atom.visible_message("The items shimmer and fizzle, turning a shade of violet blue.")
id_counter++
return TRUE

///reverts everything back to start
/datum/controller/subsystem/eigenstates/Destroy()
for(var/index in 1 to id_counter)
for(var/entry in eigen_targets["[index]"])
remove_eigen_entry(entry)
eigen_targets = null
eigen_id = null
id_counter = 1
return ..()

///removes an object reference from the master list
/datum/controller/subsystem/eigenstates/proc/remove_eigen_entry(atom/entry)
var/id = eigen_id[entry]
eigen_targets[id] -= entry
eigen_id -= entry
entry.color = COLOR_WHITE
entry.alpha = 255
UnregisterSignal(entry, list(
COMSIG_PARENT_QDELETING,
COMSIG_CLOSET_INSERT,
COMSIG_ATOM_TOOL_ACT(TOOL_WELDER),
))
entry.UnregisterSignal(entry, COMSIG_EIGENSTATE_ACTIVATE) //This is a signal on the object itself so we have to call it from that
///Remove the current entry if we're empty
for(var/targets in eigen_targets)
if(!length(eigen_targets[targets]))
eigen_targets -= targets

///Finds the object within the master list, then sends the thing to the object's location
/datum/controller/subsystem/eigenstates/proc/use_eigenlinked_atom(atom/object_sent_from, atom/movable/thing_to_send)
var/id = eigen_id[object_sent_from]
if(!id)
stack_trace("[object_sent_from] attempted to eigenlink to something that didn't have a valid id!")
return FALSE
var/list/items = eigen_targets[id]
var/index = (items.Find(object_sent_from))+1 //index + 1
if(!index)
stack_trace("[object_sent_from] attempted to eigenlink to something that didn't contain it!")
return FALSE
if(index > length(eigen_targets[id]))//If we're at the end of the list (or we're 1 length long)
index = 1
var/atom/eigen_target = eigen_targets[id][index]
if(!eigen_target)
stack_trace("No eigen target set for the eigenstate component!")
return FALSE
thing_to_send.forceMove(get_turf(eigen_target))
//Create ONE set of sparks for ALL times in iteration
if(spark_time != world.time)
do_sparks(5, FALSE, eigen_target)
do_sparks(5, FALSE, object_sent_from)
spark_time = world.time
//Calls a special proc for the atom if needed (closets use bust_open())
SEND_SIGNAL(eigen_target, COMSIG_EIGENSTATE_ACTIVATE)
return COMPONENT_CLOSET_INSERT_INTERRUPT

///Prevents tool use on the item
/datum/controller/subsystem/eigenstates/proc/tool_interact(atom/source, mob/user, obj/item/item)
to_chat(user, "<span class='notice'>The unstable nature of [source] makes it impossible to use [item] on [source.p_them()]!</span>")
return COMPONENT_BLOCK_TOOL_ATTACK
68 changes: 68 additions & 0 deletions code/controllers/subsystem/processing/quirks.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#define EXP_ASSIGN_WAYFINDER 1200
#define RANDOM_QUIRK_BONUS 3
#define MINIMUM_RANDOM_QUIRKS 3
//Used to process and handle roundstart quirks
// - Quirk strings are used for faster checking in code
// - Quirk datums are stored and hold different effects, as well as being a vector for applying trait string
Expand Down Expand Up @@ -65,3 +67,69 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
// Assign wayfinding pinpointer granting quirk if they're new
if(cli.get_exp_living(TRUE) < EXP_ASSIGN_WAYFINDER && !user.has_quirk(/datum/quirk/needswayfinder))
user.add_quirk(/datum/quirk/needswayfinder, TRUE)

/*
*Randomises the quirks for a specified mob
*/
/datum/controller/subsystem/processing/quirks/proc/randomise_quirks(mob/living/user)
var/bonus_quirks = max((length(user.roundstart_quirks) + rand(-RANDOM_QUIRK_BONUS, RANDOM_QUIRK_BONUS)), MINIMUM_RANDOM_QUIRKS)
var/added_quirk_count = 0 //How many we've added
var/list/quirks_to_add = list() //Quirks we're adding
var/good_count = 0 //Maximum of 6 good perks
var/score //What point score we're at
///Cached list of possible quirks
var/list/possible_quirks = quirks.Copy()
//Create a random list of stuff to start with
while(bonus_quirks > added_quirk_count)
var/quirk = pick(possible_quirks) //quirk is a string
if(quirk in quirk_blacklist) //prevent blacklisted
possible_quirks -= quirk
continue
if(quirk_points[quirk] > 0)
good_count++
score += quirk_points[quirk]
quirks_to_add += quirk
possible_quirks -= quirk
added_quirk_count++

//But lets make sure we're balanced
while(score > 0)
if(!length(possible_quirks))//Lets not get stuck
break
var/quirk = pick(quirks)
if(quirk in quirk_blacklist) //prevent blacklisted
possible_quirks -= quirk
continue
if(!quirk_points[quirk] < 0)//negative only
possible_quirks -= quirk
continue
good_count++
score += quirk_points[quirk]
quirks_to_add += quirk

//And have benefits too
while(score < 0 && good_count <= MAX_QUIRKS)
if(!length(possible_quirks))//Lets not get stuck
break
var/quirk = pick(quirks)
if(quirk in quirk_blacklist) //prevent blacklisted
possible_quirks -= quirk
continue
if(!quirk_points[quirk] > 0) //positive only
possible_quirks -= quirk
continue
good_count++
score += quirk_points[quirk]
quirks_to_add += quirk

for(var/datum/quirk/quirk as anything in user.roundstart_quirks)
if(quirk.name in quirks_to_add) //Don't delete ones we keep
quirks_to_add -= quirk.name //Already there, no need to add.
continue
user.remove_quirk(quirk.type) //these quirks are objects

for(var/datum/quirk/quirk as anything in quirks_to_add)
user.add_quirk(quirks[quirk], spawn_effects = TRUE)//these are typepaths converted from string

#undef RANDOM_QUIRK_BONUS
#undef MINIMUM_RANDOM_QUIRKS
17 changes: 17 additions & 0 deletions code/datums/mood_events/drug_events.dm
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,23 @@
mood_change = 6
timeout = 3 MINUTES

#define EIGENTRIP_MOOD_RANGE 10

/datum/mood_event/eigentrip
description = "<span class='nicegreen'>I swapped places with an alternate reality version of myself!</span>\n"
mood_change = 0
timeout = 10 MINUTES

/datum/mood_event/eigentrip/add_effects(param)
var/value = rand(-EIGENTRIP_MOOD_RANGE,EIGENTRIP_MOOD_RANGE)
mood_change = value
if(value < 0)
description = "<span class='warning'>I swapped places with an alternate reality version of myself! I want to go home!</span>\n"
else
description = "<span class='nicegreen'>I swapped places with an alternate reality version of myself! Though, this place is much better than my old life.</span>\n"

#undef EIGENTRIP_MOOD_RANGE

/datum/mood_event/nicotine_withdrawal_moderate
description = "<span class='warning'>Haven't had a smoke in a while. Feeling a little on edge... </span>\n"
mood_change = -5
Expand Down
10 changes: 1 addition & 9 deletions code/datums/status_effects/buffs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,7 @@
id = "Exercised"
duration = 1200
alert_type = null

/datum/status_effect/exercised/on_creation(mob/living/new_owner, ...)
. = ..()
STOP_PROCESSING(SSfastprocess, src)
START_PROCESSING(SSprocessing, src) //this lasts 20 minutes, so SSfastprocess isn't needed.

/datum/status_effect/exercised/Destroy()
. = ..()
STOP_PROCESSING(SSprocessing, src)
processing_speed = STATUS_EFFECT_NORMAL_PROCESS

//Hippocratic Oath: Applied when the Rod of Asclepius is activated.
/datum/status_effect/hippocratic_oath
Expand Down

0 comments on commit 0500771

Please sign in to comment.