Merge pull request #12390 from Ghommie/Ghommie-cit800

Porting brain trauma updates: Curse of madness, cloning traumas, random brain trauma event.
This commit is contained in:
Putnam3145
2020-06-29 12:44:33 -07:00
committed by GitHub
51 changed files with 314 additions and 141 deletions

View File

@@ -432,6 +432,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
//text files
#define BRAIN_DAMAGE_FILE "traumas.json"
#define ION_FILE "ion_laws.json"
#define REDPILL_FILE "redpill.json"
#define PIRATE_NAMES_FILE "pirates.json"

View File

@@ -98,6 +98,7 @@
#define BRAIN_TRAUMA_MILD /datum/brain_trauma/mild
#define BRAIN_TRAUMA_SEVERE /datum/brain_trauma/severe
#define BRAIN_TRAUMA_SPECIAL /datum/brain_trauma/special
#define BRAIN_TRAUMA_MAGIC /datum/brain_trauma/magic
#define TRAUMA_RESILIENCE_BASIC 1 //Curable with chems
#define TRAUMA_RESILIENCE_SURGERY 2 //Curable with brain surgery

View File

@@ -168,12 +168,14 @@
/datum/config_entry/flag/join_with_mutant_humans //players can pick mutant bodyparts for humans before joining the game
/datum/config_entry/flag/no_summon_guns //No
/datum/config_entry/flag/no_summon_guns //No
/datum/config_entry/flag/no_summon_magic //Fun
/datum/config_entry/flag/no_summon_events //Allowed
/datum/config_entry/flag/no_summon_traumas //!
/datum/config_entry/flag/no_intercept_report //Whether or not to send a communications intercept report roundstart. This may be overridden by gamemodes.
/datum/config_entry/number/arrivals_shuttle_dock_window //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station

View File

@@ -12,7 +12,7 @@ SUBSYSTEM_DEF(events)
var/frequency_upper = 6000 //10 minutes upper bound. Basically an event will happen every 3 to 10 minutes.
var/list/holidays //List of all holidays occuring today or null if no holidays
var/wizardmode = 0
var/wizardmode = FALSE
/datum/controller/subsystem/events/Initialize(time, zlevel)
for(var/type in typesof(/datum/round_event_control))
@@ -91,6 +91,7 @@ SUBSYSTEM_DEF(events)
if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0
E.max_occurrences = 0
else if(. == EVENT_READY)
E.random = TRUE
E.runEvent(TRUE)
//allows a client to trigger an event

View File

@@ -5,6 +5,61 @@
/datum/brain_trauma/magic
resilience = TRAUMA_RESILIENCE_LOBOTOMY
/datum/brain_trauma/magic/lumiphobia
name = "Lumiphobia"
desc = "Patient has an inexplicable adverse reaction to light."
scan_desc = "light hypersensitivity"
gain_text = "<span class='warning'>You feel a craving for darkness.</span>"
lose_text = "<span class='notice'>Light no longer bothers you.</span>"
var/next_damage_warning = 0
/datum/brain_trauma/magic/lumiphobia/on_life()
..()
var/turf/T = owner.loc
if(istype(T))
var/light_amount = T.get_lumcount()
if(light_amount > SHADOW_SPECIES_LIGHT_THRESHOLD) //if there's enough light, start dying
if(world.time > next_damage_warning)
to_chat(owner, "<span class='warning'><b>The light burns you!</b></span>")
next_damage_warning = world.time + 100 //Avoid spamming
owner.take_overall_damage(0,3)
/datum/brain_trauma/magic/poltergeist
name = "Poltergeist"
desc = "Patient appears to be targeted by a violent invisible entity."
scan_desc = "paranormal activity"
gain_text = "<span class='warning'>You feel a hateful presence close to you.</span>"
lose_text = "<span class='notice'>You feel the hateful presence fade away.</span>"
/datum/brain_trauma/magic/poltergeist/on_life()
..()
if(prob(4))
var/most_violent = -1 //So it can pick up items with 0 throwforce if there's nothing else
var/obj/item/throwing
for(var/obj/item/I in view(5, get_turf(owner)))
if(I.anchored)
continue
if(I.throwforce > most_violent)
most_violent = I.throwforce
throwing = I
if(throwing)
throwing.throw_at(owner, 8, 2)
/datum/brain_trauma/magic/antimagic
name = "Athaumasia"
desc = "Patient is completely inert to magical forces."
scan_desc = "thaumic blank"
gain_text = "<span class='notice'>You realize that magic cannot be real.</span>"
lose_text = "<span class='notice'>You realize that magic might be real.</span>"
/datum/brain_trauma/magic/antimagic/on_gain()
ADD_TRAIT(owner, TRAIT_ANTIMAGIC, TRAUMA_TRAIT)
..()
/datum/brain_trauma/magic/antimagic/on_lose()
REMOVE_TRAIT(owner, TRAIT_ANTIMAGIC, TRAUMA_TRAIT)
..()
/datum/brain_trauma/magic/stalker
name = "Stalking Phantom"
desc = "Patient is stalked by a phantom only they can see."

View File

@@ -119,8 +119,9 @@
/datum/brain_trauma/severe/paralysis/spinesnapped
random_gain = FALSE
clonable = FALSE
paralysis_type = "legs"
resilience = TRAUMA_RESILIENCE_LOBOTOMY
resilience = TRAUMA_RESILIENCE_LOBOTOMY // It shouldn't fix severed spinal cords really, but there is no specific surgery for that yet.
/datum/brain_trauma/severe/narcolepsy
name = "Narcolepsy"

View File

@@ -42,6 +42,7 @@
school = "evocation"
charge_max = 600
clothes_req = NONE
antimagic_allowed = TRUE
range = 20
base_icon_state = "fireball"
action_icon_state = "fireball0"
@@ -122,6 +123,7 @@
desc = "A rare genome that attracts odd forces not usually observed. May sometimes pull you in randomly."
school = "evocation"
clothes_req = NONE
antimagic_allowed = TRUE
charge_max = 600
invocation = "DOOOOOOOOOOOOOOOOOOOOM!!!"
invocation_type = "shout"
@@ -155,6 +157,7 @@
dropmessage = "You let the electricity from your hand dissipate."
hand_path = /obj/item/melee/touch_attack/shock
charge_max = 400
antimagic_allowed = TRUE
clothes_req = NONE
action_icon_state = "zap"
@@ -212,6 +215,7 @@
desc = "Get a scent off of the item you're currently holding to track it. With an empty hand, you'll track the scent you've remembered."
charge_max = 100
clothes_req = NONE
antimagic_allowed = TRUE
range = -1
include_user = TRUE
action_icon_state = "nose"
@@ -290,6 +294,7 @@
name = "Drop a limb"
desc = "Concentrate to make a random limb pop right off your body."
clothes_req = NONE
antimagic_allowed = TRUE
charge_max = 100
action_icon_state = "autotomy"
@@ -327,6 +332,7 @@
name = "Lay Web"
desc = "Drops a web. Only you will be able to traverse your web easily, making it pretty good for keeping you safe."
clothes_req = NONE
antimagic_allowed = TRUE
charge_max = 4 SECONDS //the same time to lay a web
action_icon = 'icons/mob/actions/actions_genetic.dmi'
action_icon_state = "lay_web"
@@ -368,6 +374,7 @@
name = "Launch spike"
desc = "Shoot your tongue out in the direction you're facing, embedding it and dealing damage until they remove it."
clothes_req = NONE
antimagic_allowed = TRUE
charge_max = 100
action_icon = 'icons/mob/actions/actions_genetic.dmi'
action_icon_state = "spike"

View File

@@ -51,4 +51,4 @@
H.dna.add_mutation(CLOWNMUT)
H.dna.add_mutation(SMILE)
H.gain_trauma(/datum/brain_trauma/mild/phobia, TRAUMA_RESILIENCE_LOBOTOMY, "clowns") //MWA HA HA
H.gain_trauma(/datum/brain_trauma/mild/phobia/clowns, TRAUMA_RESILIENCE_LOBOTOMY) //MWA HA HA

View File

@@ -134,7 +134,7 @@
return examine(user)
//Start growing a human clone in the pod!
/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, mutation_index, mindref, datum/species/mrace, list/features, factions, list/quirks, datum/bank_account/insurance)
/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, mutation_index, mindref, datum/species/mrace, list/features, factions, list/quirks, datum/bank_account/insurance, list/traumas)
if(panel_open)
return FALSE
if(mess || attempting)
@@ -209,6 +209,12 @@
var/datum/quirk/Q = new V(H)
Q.on_clone(quirks[V])
for(var/t in traumas)
var/datum/brain_trauma/BT = t
var/datum/brain_trauma/cloned_trauma = BT.on_clone()
if(cloned_trauma)
H.gain_trauma(cloned_trauma, BT.resilience)
H.set_cloned_appearance()
H.give_genitals(TRUE)
@@ -271,9 +277,6 @@
var/obj/item/bodypart/BP = I
BP.attach_limb(mob_occupant)
//Premature clones may have brain damage.
mob_occupant.adjustOrganLoss(ORGAN_SLOT_BRAIN, -((speed_coeff / 2) * dmg_mult))
use_power(7500) //This might need tweaking.
else if((mob_occupant && mob_occupant.cloneloss <= (100 - heal_level)))
@@ -399,6 +402,8 @@
to_chat(occupant, "<span class='notice'><b>There is a bright flash!</b><br><i>You feel like a new being.</i></span>")
mob_occupant.flash_act()
mob_occupant.adjustOrganLoss(ORGAN_SLOT_BRAIN, mob_occupant.getCloneLoss())
occupant.forceMove(T)
update_icon()
mob_occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest.
@@ -474,10 +479,9 @@
unattached_flesh.Cut()
H.setCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health
//H.setOrganLoss(ORGAN_SLOT_BRAIN, CLONE_INITIAL_DAMAGE)
// In addition to being cellularly damaged and having barely any
// brain function, they also have no limbs or internal organs.
// In addition to being cellularly damaged, they also have no limbs or internal organs.
// Applying brainloss is done when the clone leaves the pod, so application of traumas can happen.
// based on the level of damage sustained.
if(!HAS_TRAIT(H, TRAIT_NODISMEMBER))
var/static/list/zones = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)

View File

@@ -73,7 +73,7 @@
if(pod.occupant)
continue //how though?
if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"], R.fields["bank_account"]))
if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"], R.fields["bank_account"], R.fields["traumas"]))
temp = "[R.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
records -= R
@@ -442,14 +442,17 @@
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
var/datum/dna/dna
var/datum/bank_account/has_bank_account
// Do not use unless you know what they are.
var/mob/living/carbon/C = mob_occupant
var/mob/living/brain/B = mob_occupant
if(ishuman(mob_occupant))
var/mob/living/carbon/C = mob_occupant
dna = C.has_dna()
var/obj/item/card/id/I = C.get_idcard()
if(I)
has_bank_account = I.registered_account
if(isbrain(mob_occupant))
var/mob/living/brain/B = mob_occupant
dna = B.stored_dna
if(!istype(dna))
@@ -497,11 +500,17 @@
R.fields["features"] = dna.features
R.fields["factions"] = mob_occupant.faction
R.fields["quirks"] = list()
R.fields["bank_account"] = has_bank_account
for(var/V in mob_occupant.roundstart_quirks)
var/datum/quirk/T = V
R.fields["quirks"][T.type] = T.clone_data()
R.fields["traumas"] = list()
if(ishuman(mob_occupant))
R.fields["traumas"] = C.get_traumas()
if(isbrain(mob_occupant))
R.fields["traumas"] = B.get_traumas()
R.fields["bank_account"] = has_bank_account
if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning.
R.fields["mind"] = "[REF(mob_occupant.mind)]"

View File

@@ -370,6 +370,14 @@
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/breast_enlargement(src)
/obj/item/storage/pill_bottle/neurine
name = "bottle of neurine pills"
desc = "Contains pills to treat non-severe mental traumas."
/obj/item/storage/pill_bottle/neurine/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/neurine(src)
/////////////
//Organ Box//
/////////////

View File

@@ -560,6 +560,27 @@
. += "You cast it [times] times.<br>"
return .
/datum/spellbook_entry/summon/curse_of_madness
name = "Curse of Madness"
desc = "Curses the station, warping the minds of everyone inside, causing lasting traumas. Warning: this spell can affect you if not cast from a safe distance."
cost = 4
/datum/spellbook_entry/summon/curse_of_madness/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
active = TRUE
var/message = stripped_input(user, "Whisper a secret truth to drive your victims to madness.", "Whispers of Madness")
if(!message)
return FALSE
curse_of_madness(user, message)
to_chat(user, "<span class='notice'>You have cast the curse of insanity!</span>")
playsound(user, 'sound/magic/mandswap.ogg', 50, 1)
return TRUE
/datum/spellbook_entry/summon/curse_of_madness/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return FALSE
return (!CONFIG_GET(flag/no_summon_traumas) && ..())
/obj/item/spellbook
name = "spell book"
desc = "An unearthly tome that glows with power."

View File

@@ -238,7 +238,7 @@
item_state = "foilhat"
armor = list("melee" = 0, "bullet" = 0, "laser" = -5,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = -5, "fire" = 0, "acid" = 0)
equip_delay_other = 140
var/datum/brain_trauma/mild/phobia/paranoia
var/datum/brain_trauma/mild/phobia/conspiracies/paranoia
var/warped = FALSE
clothing_flags = IGNORE_HAT_TOSS
@@ -255,7 +255,8 @@
return
if(paranoia)
QDEL_NULL(paranoia)
paranoia = new("conspiracies")
paranoia = new()
paranoia.clonable = FALSE
user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC)
to_chat(user, "<span class='warning'>As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. </span>")

View File

@@ -17,9 +17,9 @@
var/holidayID = "" //string which should be in the SSeventss.holidays list if you wish this event to be holiday-specific
//anything with a (non-null) holidayID which does not match holiday, cannot run.
var/wizardevent = 0
var/alertadmins = 1 //should we let the admins know this event is firing
var/wizardevent = FALSE
var/random = FALSE //If the event has occured randomly, or if it was forced by an admin or in-game occurance
var/alert_observers = TRUE //should we let the ghosts and admins know this event is firing
//should be disabled on events that fire a lot
var/list/gamemode_blacklist = list() // Event won't happen in these gamemodes
@@ -33,7 +33,7 @@
min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1)
/datum/round_event_control/wizard
wizardevent = 1
wizardevent = TRUE
var/can_be_midround_wizard = TRUE
// Checks if the event can be spawned. Used by event controller and "false alarm" event.
@@ -67,7 +67,7 @@
return EVENT_CANT_RUN
triggering = TRUE
if (alertadmins)
if (alert_observers)
message_admins("Random Event triggering in 10 seconds: [name] (<a href='?src=[REF(src)];cancel=1'>CANCEL</a>)")
sleep(100)
var/gamemode = SSticker.mode.config_tag
@@ -92,7 +92,7 @@
log_admin_private("[key_name(usr)] cancelled event [name].")
SSblackbox.record_feedback("tally", "event_admin_cancelled", 1, typepath)
/datum/round_event_control/proc/runEvent(random)
/datum/round_event_control/proc/runEvent()
var/datum/round_event/E = new typepath()
E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
E.control = src
@@ -101,10 +101,9 @@
testing("[time2text(world.time, "hh:mm:ss")] [E.type]")
if(random)
if(alertadmins)
deadchat_broadcast("<span class='deadsay'><b>[name]</b> has just been randomly triggered!</span>") //STOP ASSUMING IT'S BADMINS!
log_game("Random Event triggering: [name] ([typepath])")
if (alert_observers)
deadchat_broadcast("<span class='deadsay'><b>[name]</b> has just been[random ? " randomly" : ""] triggered!</span>") //STOP ASSUMING IT'S BADMINS!
return E
//Special admins setup
@@ -140,6 +139,17 @@
/datum/round_event/proc/start()
return
/**
* Called after something followable has been spawned by an event
* Provides ghosts a follow link to an atom if possible
* Only called once.
*/
/datum/round_event/proc/announce_to_ghosts(atom/atom_of_interest)
if(control.alert_observers)
if (atom_of_interest)
notify_ghosts("[control.name] has an object of interest: [atom_of_interest]!", source=atom_of_interest, action=NOTIFY_ORBIT, header="Something's Interesting!")
return
//Called when the tick is equal to the announceWhen variable.
//Allows you to announce before starting or vice versa.
//Only called once.

View File

@@ -8,7 +8,7 @@
/datum/round_event/anomaly
var/area/impact_area
var/obj/effect/anomaly/newAnomaly
var/obj/effect/anomaly/anomaly_path = /obj/effect/anomaly/flux
announceWhen = 1
@@ -27,7 +27,7 @@
//Subtypes from the above that actually should explode.
var/list/unsafe_area_subtypes = typecacheof(list(/area/engine/break_room))
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
return safepick(typecache_filter_list(GLOB.sortedAreas,allowed_areas))
@@ -44,6 +44,9 @@
priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
/datum/round_event/anomaly/start()
var/turf/T = safepick(get_area_turfs(impact_area))
var/turf/T = pick(get_area_turfs(impact_area))
var/newAnomaly
if(T)
newAnomaly = new /obj/effect/anomaly/flux(T)
newAnomaly = new anomaly_path(T)
if (newAnomaly)
announce_to_ghosts(newAnomaly)

View File

@@ -1,6 +1,7 @@
/datum/round_event_control/anomaly/anomaly_bluespace
name = "Anomaly: Bluespace"
typepath = /datum/round_event/anomaly/anomaly_bluespace
max_occurrences = 1
weight = 5
gamemode_blacklist = list("dynamic")
@@ -8,15 +9,10 @@
/datum/round_event/anomaly/anomaly_bluespace
startWhen = 3
announceWhen = 10
anomaly_path = /obj/effect/anomaly/bluespace
/datum/round_event/anomaly/anomaly_bluespace/announce(fake)
if(prob(90))
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
else
print_command_report("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Unstable bluespace anomaly")
/datum/round_event/anomaly/anomaly_bluespace/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/bluespace(T)

View File

@@ -10,14 +10,10 @@
/datum/round_event/anomaly/anomaly_flux
startWhen = 10
announceWhen = 3
anomaly_path = /obj/effect/anomaly/flux
/datum/round_event/anomaly/anomaly_flux/announce(fake)
if(prob(90))
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
else
print_command_report("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].","Localized hyper-energetic flux wave")
/datum/round_event/anomaly/anomaly_flux/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/flux(T)

View File

@@ -1,6 +1,7 @@
/datum/round_event_control/anomaly/anomaly_grav
name = "Anomaly: Gravitational"
typepath = /datum/round_event/anomaly/anomaly_grav
max_occurrences = 5
weight = 20
gamemode_blacklist = list("dynamic")
@@ -9,14 +10,10 @@
/datum/round_event/anomaly/anomaly_grav
startWhen = 3
announceWhen = 20
anomaly_path = /obj/effect/anomaly/grav
/datum/round_event/anomaly/anomaly_grav/announce(fake)
if(prob(90))
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
else
print_command_report("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Gravitational anomaly")
/datum/round_event/anomaly/anomaly_grav/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/grav(T)

View File

@@ -1,6 +1,7 @@
/datum/round_event_control/anomaly/anomaly_pyro
name = "Anomaly: Pyroclastic"
typepath = /datum/round_event/anomaly/anomaly_pyro
max_occurrences = 5
weight = 20
gamemode_blacklist = list("dynamic")
@@ -8,14 +9,10 @@
/datum/round_event/anomaly/anomaly_pyro
startWhen = 3
announceWhen = 10
anomaly_path = /obj/effect/anomaly/pyro
/datum/round_event/anomaly/anomaly_pyro/announce(fake)
if(prob(90))
priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
else
print_command_report("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Pyroclastic anomaly")
/datum/round_event/anomaly/anomaly_pyro/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/pyro(T)

View File

@@ -10,14 +10,10 @@
/datum/round_event/anomaly/anomaly_vortex
startWhen = 10
announceWhen = 3
anomaly_path = /obj/effect/anomaly/bhole
/datum/round_event/anomaly/anomaly_vortex/announce(fake)
if(prob(90))
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
else
print_command_report("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name].","Vortex anomaly")
/datum/round_event/anomaly/anomaly_vortex/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/bhole(T)

View File

@@ -30,4 +30,4 @@
BRAIN_TRAUMA_SPECIAL = 10
))
H.gain_trauma_type(trauma_type, resistance)
H.gain_trauma_type(trauma_type, resistance)

View File

@@ -54,6 +54,7 @@
vendingMachines.Remove(originMachine)
originMachine.shut_up = 0
originMachine.shoot_inventory = 1
announce_to_ghosts(originMachine)
/datum/round_event/brand_intelligence/tick()

View File

@@ -3,7 +3,7 @@
typepath = /datum/round_event/camera_failure
weight = 100
max_occurrences = 20
alertadmins = 0
alert_observers = FALSE
/datum/round_event/camera_failure
fakeable = FALSE

View File

@@ -10,6 +10,7 @@
/datum/round_event/carp_migration
announceWhen = 3
startWhen = 50
var/hasAnnounced = FALSE
/datum/round_event/carp_migration/setup()
startWhen = rand(40, 60)
@@ -22,10 +23,16 @@
/datum/round_event/carp_migration/start()
var/mob/living/simple_animal/hostile/carp/fish
for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
if(prob(95))
new /mob/living/simple_animal/hostile/carp(C.loc)
fish = new (C.loc)
else
new /mob/living/simple_animal/hostile/carp/megacarp(C.loc)
fish = new /mob/living/simple_animal/hostile/carp/megacarp(C.loc)
fishannounce(fish) //Prefer to announce the megacarps over the regular fishies
fishannounce(fish)
/datum/round_event/carp_migration/proc/fishannounce(atom/fish)
if (!hasAnnounced)
announce_to_ghosts(fish) //Only anounce the first fish
hasAnnounced = TRUE

View File

@@ -4,7 +4,7 @@
weight = 200
max_occurrences = 1000
earliest_start = 0 MINUTES
alertadmins = 0
alert_observers = FALSE
gamemode_blacklist = list("dynamic")
/datum/round_event/space_dust

View File

@@ -4,7 +4,7 @@
earliest_start = 10 MINUTES
min_players = 5
weight = 40
alertadmins = 0
alert_observers = FALSE
gamemode_blacklist = list("dynamic")
/datum/round_event/electrical_storm

View File

@@ -37,7 +37,10 @@
signing up.")
else if(status == SUCCESSFUL_SPAWN)
message_admins("[role_name] spawned successfully.")
if(!spawned_mobs.len)
if(spawned_mobs.len)
for(var/mob/M in spawned_mobs)
announce_to_ghosts(M)
else
message_admins("No mobs found in the `spawned_mobs` list, this is \
a bug.")
else

View File

@@ -20,4 +20,4 @@
var/mob/living/carbon/human/winner = pickweight(heart_attack_contestants)
var/datum/disease/D = new /datum/disease/heart_failure()
winner.ForceContractDisease(D, FALSE, TRUE)
notify_ghosts("[winner] is beginning to have a heart attack!", enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>", source=winner, action=NOTIFY_ORBIT)
announce_to_ghosts(winner)

View File

@@ -35,7 +35,8 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
var/z = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
var/turf/startT = spaceDebrisStartLoc(startside, z)
var/turf/endT = spaceDebrisFinishLoc(startside, z)
new /obj/effect/immovablerod(startT, endT, C.special_target)
var/atom/rod = new /obj/effect/immovablerod(startT, endT, C.special_target)
announce_to_ghosts(rod)
/obj/effect/immovablerod
name = "immovable rod"
@@ -61,10 +62,6 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
z_original = z
destination = end
special_target = aimed_at
if(notify)
notify_ghosts("\A [src] is inbound!",
enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>",
source=src, action=NOTIFY_ORBIT)
GLOB.poi_list += src
var/special_target_valid = FALSE

View File

@@ -80,8 +80,9 @@
var/mob/M = candidates[1]
spawner.create(M.ckey)
candidates -= M
announce_to_ghosts(M)
else
notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
announce_to_ghosts(spawner)
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") //CITADEL EDIT also metabreak here too

View File

@@ -30,6 +30,7 @@
/datum/round_event/processor_overload/start()
for(var/obj/machinery/telecomms/processor/P in GLOB.telecomms_list)
if(prob(10))
announce_to_ghosts(P)
// Damage the surrounding area to indicate that it popped
explosion(get_turf(P), 0, 0, 2)
// Only a level 1 explosion actually damages the machine

View File

@@ -383,7 +383,9 @@
/datum/spacevine_controller/New(turf/location, list/muts, potency, production, datum/round_event/event = null)
vines = list()
growth_queue = list()
spawn_spacevine_piece(location, null, muts)
var/obj/structure/spacevine/SV = spawn_spacevine_piece(location, null, muts)
if (event)
event.announce_to_ghosts(SV)
START_PROCESSING(SSobj, src)
vine_mutations_list = list()
init_subtypes(/datum/spacevine_mutation/, vine_mutations_list)

View File

@@ -35,6 +35,6 @@
var/spawn_type = /obj/structure/spider/spiderling
if(prob(66))
spawn_type = /obj/structure/spider/spiderling/nurse
spawn_atom_to_turf(spawn_type, vent, 1, FALSE)
announce_to_ghosts(spawn_atom_to_turf(spawn_type, vent, 1, FALSE))
vents -= vent
spawncount--

View File

@@ -0,0 +1,28 @@
/datum/round_event_control/wizard/madness
name = "Curse of Madness"
weight = 1
typepath = /datum/round_event/wizard/madness
earliest_start = 0 MINUTES
var/forced_secret
/datum/round_event_control/wizard/madness/admin_setup()
if(!check_rights(R_FUN))
return
var/suggested = pick(strings(REDPILL_FILE, "redpill_questions"))
forced_secret = (input(usr, "What horrifying truth will you reveal?", "Curse of Madness", sortList(suggested)) as text|null) || suggested
/datum/round_event/wizard/madness/start()
var/datum/round_event_control/wizard/madness/C = control
var/horrifying_truth
if(C.forced_secret)
horrifying_truth = C.forced_secret
C.forced_secret = null
else
horrifying_truth = pick(strings(REDPILL_FILE, "redpill_questions"))
curse_of_madness(null, horrifying_truth)

View File

@@ -412,6 +412,8 @@
give_guns(humanc)
if(GLOB.summon_magic_triggered)
give_magic(humanc)
if(GLOB.curse_of_madness_triggered)
give_madness(humanc, GLOB.curse_of_madness_triggered)
GLOB.joined_player_list += character.ckey
GLOB.latejoiners += character

View File

@@ -100,3 +100,9 @@
client.mouse_pointer_icon = M.mouse_pointer
if (client && ranged_ability && ranged_ability.ranged_mousepointer)
client.mouse_pointer_icon = ranged_ability.ranged_mousepointer
/mob/living/brain/proc/get_traumas()
. = list()
if(istype(loc, /obj/item/organ/brain))
var/obj/item/organ/brain/B = loc
. = B.traumas

View File

@@ -265,46 +265,3 @@
if(update)
update_damage_overlays()
update_stamina()
/* TO_REMOVE
/mob/living/carbon/getOrganLoss(ORGAN_SLOT_BRAIN)
. = 0
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
. = B.get_brain_damage()
//Some sources of brain damage shouldn't be deadly
/mob/living/carbon/adjustOrganLoss(ORGAN_SLOT_BRAIN, amount, maximum = BRAIN_DAMAGE_DEATH)
if(status_flags & GODMODE)
return FALSE
var/prev_brainloss = getOrganLoss(ORGAN_SLOT_BRAIN)
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(!B)
return
B.adjust_brain_damage(amount, maximum)
if(amount <= 0) //cut this early
return
var/brainloss = getOrganLoss(ORGAN_SLOT_BRAIN)
if(brainloss > BRAIN_DAMAGE_MILD)
if(prob(amount * ((2 * (100 + brainloss - BRAIN_DAMAGE_MILD)) / 100))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 2%
gain_trauma_type(BRAIN_TRAUMA_MILD)
if(brainloss > BRAIN_DAMAGE_SEVERE)
if(prob(amount * ((2 * (100 + brainloss - BRAIN_DAMAGE_SEVERE)) / 100))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 2%
if(prob(20))
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
else
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
if(prev_brainloss < BRAIN_DAMAGE_MILD && brainloss >= BRAIN_DAMAGE_MILD)
to_chat(src, "<span class='warning'>You feel lightheaded.</span>")
else if(prev_brainloss < BRAIN_DAMAGE_SEVERE && brainloss >= BRAIN_DAMAGE_SEVERE)
to_chat(src, "<span class='warning'>You feel less in control of your thoughts.</span>")
else if(prev_brainloss < (BRAIN_DAMAGE_DEATH - 20) && brainloss >= (BRAIN_DAMAGE_DEATH - 20))
to_chat(src, "<span class='warning'>You can feel your mind flickering on and off...</span>")
/mob/living/carbon/setBrainLoss(amount)
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
var/adjusted_amount = amount - B.get_brain_damage()
B.adjust_brain_damage(adjusted_amount, null)
*/

View File

@@ -349,7 +349,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
/mob/proc/reagent_check(datum/reagent/R) // utilized in the species code
return 1
/proc/notify_ghosts(message, ghost_sound, enter_link, atom/source, mutable_appearance/alert_overlay, action = NOTIFY_JUMP, flashwindow = TRUE, ignore_mapload = TRUE, ignore_key, ignore_dnr_observers = FALSE) //Easy notification of ghosts.
/proc/notify_ghosts(message, ghost_sound, enter_link, atom/source, mutable_appearance/alert_overlay, action = NOTIFY_JUMP, flashwindow = TRUE, ignore_mapload = TRUE, ignore_key, ignore_dnr_observers = FALSE, header) //Easy notification of ghosts.
if(ignore_mapload && SSatoms.initialized != INITIALIZATION_INNEW_REGULAR) //don't notify for objects created during a map load
return
for(var/mob/dead/observer/O in GLOB.player_list)
@@ -366,6 +366,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
if(A)
if(O.client.prefs && O.client.prefs.UI_style)
A.icon = ui_style2icon(O.client.prefs.UI_style)
if (header)
A.name = header
A.desc = message
A.action = action
A.target = source

View File

@@ -9,7 +9,7 @@
fire_sound = 'sound/weapons/emitter.ogg'
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_HUGE
var/checks_antimagic = FALSE
var/checks_antimagic = TRUE
var/max_charges = 6
var/charges = 0
var/recharge_rate = 4

View File

@@ -11,8 +11,8 @@
grind_results = list()
var/apply_type = INGEST
var/apply_method = "swallow"
var/roundstart = 0
var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills
var/roundstart = FALSE
var/self_delay = FALSE //pills are instant, this is because patches inheret their aplication from pills
var/dissolvable = TRUE
/obj/item/reagent_containers/pill/Initialize()
@@ -83,119 +83,126 @@
desc = "Highly toxic."
icon_state = "pill5"
list_reagents = list(/datum/reagent/toxin = 50)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/cyanide
name = "cyanide pill"
desc = "Don't swallow this."
icon_state = "pill5"
list_reagents = list(/datum/reagent/toxin/cyanide = 50)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/adminordrazine
name = "adminordrazine pill"
desc = "It's magic. We don't have to explain it."
icon_state = "pill16"
list_reagents = list(/datum/reagent/medicine/adminordrazine = 50)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/morphine
name = "morphine pill"
desc = "Commonly used to treat insomnia."
icon_state = "pill8"
list_reagents = list(/datum/reagent/medicine/morphine = 30)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/stimulant
name = "stimulant pill"
desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!"
icon_state = "pill19"
list_reagents = list(/datum/reagent/medicine/ephedrine = 10, /datum/reagent/medicine/antihol = 10, /datum/reagent/consumable/coffee = 30)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/salbutamol
name = "salbutamol pill"
desc = "Used to treat oxygen deprivation."
icon_state = "pill16"
list_reagents = list(/datum/reagent/medicine/salbutamol = 30)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/charcoal
name = "charcoal pill"
desc = "Neutralizes many common toxins."
icon_state = "pill17"
list_reagents = list(/datum/reagent/medicine/charcoal = 10)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/epinephrine
name = "epinephrine pill"
desc = "Used to stabilize patients."
icon_state = "pill5"
list_reagents = list(/datum/reagent/medicine/epinephrine = 15)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/mannitol
name = "mannitol pill"
desc = "Used to treat brain damage."
icon_state = "pill17"
list_reagents = list(/datum/reagent/medicine/mannitol = 25)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/mutadone
name = "mutadone pill"
desc = "Used to treat genetic damage."
icon_state = "pill20"
list_reagents = list(/datum/reagent/medicine/mutadone = 25)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/salicyclic
name = "salicylic acid pill"
desc = "Used to dull pain."
icon_state = "pill9"
list_reagents = list(/datum/reagent/medicine/sal_acid = 24)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/oxandrolone
name = "oxandrolone pill"
desc = "Used to stimulate burn healing."
icon_state = "pill11"
list_reagents = list(/datum/reagent/medicine/oxandrolone = 24)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/insulin
name = "insulin pill"
desc = "Handles hyperglycaemic coma."
icon_state = "pill18"
list_reagents = list(/datum/reagent/medicine/insulin = 50)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/psicodine
name = "psicodine pill"
desc = "Used to treat mental instability and traumas."
desc = "Used to treat mental instability and phobias."
list_reagents = list(/datum/reagent/medicine/psicodine = 10)
icon_state = "pill22"
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/antirad
name = "potassium iodide pill"
desc = "Used to treat radition used to counter radiation poisoning."
icon_state = "pill18"
list_reagents = list(/datum/reagent/medicine/potass_iodide = 50)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/antirad_plus
name = "prussian blue pill"
desc = "Used to treat heavy radition poisoning."
icon_state = "prussian_blue"
list_reagents = list(/datum/reagent/medicine/prussian_blue = 25)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/mutarad
name = "radiation treatment deluxe pill"
desc = "Used to treat heavy radition poisoning and genetic defects."
icon_state = "anit_rad_fixgene"
list_reagents = list(/datum/reagent/medicine/prussian_blue = 10, /datum/reagent/medicine/potass_iodide = 10, /datum/reagent/medicine/mutadone = 5)
roundstart = 1
roundstart = TRUE
/obj/item/reagent_containers/pill/neurine
name = "neurine pill"
desc = "Used to treat non-severe mental traumas."
list_reagents = list("neurine" = 10)
icon_state = "pill22"
roundstart = TRUE
///////////////////////////////////////// this pill is used only in a legion mob drop
/obj/item/reagent_containers/pill/shadowtoxin

View File

@@ -120,7 +120,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
var/list/mobs_blacklist //The opposite of the above.
var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells
var/phase_allowed = 0 // If true, the spell can be cast while phased, eg. blood crawling, ethereal jaunting
var/antimagic_allowed = TRUE // If false, the spell cannot be cast while under the effect of antimagic
var/antimagic_allowed = FALSE // If false, the spell cannot be cast while under the effect of antimagic
var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell
var/invocation_emote_self = null
var/invocation_type = "none" //can be none, whisper, emote and shout

View File

@@ -0,0 +1,37 @@
GLOBAL_VAR_INIT(curse_of_madness_triggered, FALSE)
/proc/curse_of_madness(mob/user, message)
if(user) //in this case either someone holding a spellbook or a badmin
to_chat(user, "<span class='warning'>You sent a curse of madness with the message \"[message]\"!</span>")
message_admins("[ADMIN_LOOKUPFLW(user)] sent a curse of madness with the message \"[message]\"!")
log_game("[key_name(user)] sent a curse of madness with the message \"[message]\"!")
GLOB.curse_of_madness_triggered = message // So latejoiners are also afflicted.
deadchat_broadcast("<span class='deadsay'>A <span class='name'>Curse of Madness</span> has stricken the station, shattering their minds with the awful secret: \"<span class='big hypnophrase'>[message]</span>\"</span>")
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(H.stat == DEAD)
continue
var/turf/T = get_turf(H)
if(T && !is_station_level(T.z))
continue
if(H.anti_magic_check(TRUE, FALSE, TRUE))
to_chat(H, "<span class='notice'>You have a strange feeling for a moment, but then it passes.</span>")
continue
give_madness(H, message)
/proc/give_madness(mob/living/carbon/human/H, message)
H.playsound_local(H,'sound/magic/curse.ogg',40,1)
to_chat(H, "<span class='reallybig hypnophrase'>[message]</span>")
to_chat(H, "<span class='warning'>Your mind shatters!</span>")
switch(rand(1,10))
if(1 to 3)
H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY)
H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY)
if(4 to 6)
H.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
if(7 to 8)
H.gain_trauma_type(BRAIN_TRAUMA_MAGIC, TRAUMA_RESILIENCE_LOBOTOMY)
if(9 to 10)
H.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, TRAUMA_RESILIENCE_LOBOTOMY)

View File

@@ -12,6 +12,7 @@
range = 0
cast_sound = null
mobs_whitelist = list(/mob/living/carbon/human)
antimagic_allowed = TRUE
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
@@ -40,6 +41,7 @@
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
antimagic_allowed = TRUE
/obj/effect/proc_holder/spell/targeted/mime/speak/Trigger(mob/user, skip_can_cast = TRUE)
if(user.mind?.miming)
@@ -76,6 +78,7 @@
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
antimagic_allowed = TRUE
/obj/effect/proc_holder/spell/targeted/forcewall/mime/Trigger(mob/user, skip_can_cast = TRUE)
if(user.mind)
@@ -107,6 +110,7 @@
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
base_icon_state = "mime"
antimagic_allowed = TRUE
/obj/effect/proc_holder/spell/aimed/finger_guns/Trigger(mob/user, skip_can_cast = TRUE)
@@ -137,6 +141,7 @@
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
hand_path = /obj/item/melee/touch_attack/mimerope
antimagic_allowed = TRUE
/obj/effect/proc_holder/spell/targeted/touch/mimerope/Trigger(mob/user, skip_can_cast = TRUE)
if(user.mind)

View File

@@ -13,3 +13,4 @@
summon_type = list("/obj/item/a_gift")
summon_lifespan = 0
summon_amt = 5
antimagic_allowed = TRUE

View File

@@ -12,6 +12,7 @@
action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
action_icon_state = "ninja_cloak"
action_background_icon_state = "bg_alien"
antimagic_allowed = TRUE
/obj/effect/proc_holder/spell/targeted/shadowwalk/cast(list/targets,mob/living/user = usr)
var/L = user.loc

View File

@@ -10,6 +10,7 @@
cooldown_min = 30
action_icon = 'icons/obj/food/piecake.dmi'
action_icon_state = "pie"
antimagic_allowed = TRUE
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -24,6 +25,7 @@
range = 7
selection_type = "view"
projectile_type = null
antimagic_allowed = TRUE
active_msg = "You focus, your mind reaching to the clown dimension, ready to make a peel matrialize wherever you want!"
deactive_msg = "You relax, the peel remaining right in the \"thin air\" it would appear out of."
@@ -62,6 +64,7 @@
charge_max = 100
clothes_req = NONE
cooldown_min = 100
antimagic_allowed = TRUE
action_icon = 'icons/mecha/mecha_equipment.dmi'
action_icon_state = "mecha_honker"
@@ -76,6 +79,7 @@
charge_max = 450
clothes_req = NONE
cooldown_min = 450
antimagic_allowed = TRUE
action_icon = 'icons/obj/food/piecake.dmi'
action_icon_state = "frostypie"

View File

@@ -8,6 +8,7 @@
action_icon = 'icons/mob/actions/actions_revenant.dmi'
action_icon_state = "r_transmit"
action_background_icon_state = "bg_spell"
antimagic_allowed = TRUE
var/notice = "notice"
var/boldnotice = "boldnotice"
var/magic_check = FALSE

View File

@@ -5,6 +5,7 @@
cooldown_min = 0
level_max = 1
clothes_req = NONE
antimagic_allowed = TRUE
action_icon = 'icons/mob/actions/actions_items.dmi'
action_icon_state = "voice_of_god"
var/command

View File

@@ -306,6 +306,7 @@
sound = 'sound/magic/tail_swing.ogg'
charge_max = 150
clothes_req = NONE
antimagic_allowed = TRUE
range = 2
cooldown_min = 150
invocation_type = "none"

View File

@@ -525,7 +525,7 @@ GLOBAL_LIST_EMPTY(vending_products)
if(4) // paralyze this binch
// the new paraplegic gets like 4 lines of losing their legs so skip them
visible_message("<span class='danger'>[C]'s spinal cord is obliterated with a sickening crunch!</span>", ignored_mobs = list(C))
C.gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic)
C.gain_trauma(/datum/brain_trauma/severe/paralysis/spinesnapped)
if(5) // skull squish!
var/obj/item/bodypart/head/O = C.get_bodypart(BODY_ZONE_HEAD)
if(O)