Merge branch 'master' into upstream-merge-26386

This commit is contained in:
LetterJay
2017-05-01 15:27:25 -05:00
committed by GitHub
267 changed files with 15247 additions and 8768 deletions
+33 -6
View File
@@ -1,10 +1,12 @@
//Dead mobs can exist whenever. This is needful
/mob/dead/New(loc)
..()
if(!initialized)
args[1] = FALSE
Initialize(arglist(args)) //EXIST DAMN YOU!!!
INITIALIZE_IMMEDIATE(/mob/dead)
/mob/dead/Initialize()
. = ..()
if(config.cross_allowed)
verbs += /mob/dead/proc/server_hop
/mob/dead/dust() //ghosts can't be vaporised.
return
@@ -12,4 +14,29 @@
return
/mob/dead/ConveyorMove() //lol
return
return
/mob/dead/proc/server_hop()
set category = "OOC"
set name = "Server Hop!"
set desc= "Jump to the other server"
if(notransform)
return
if(!config.cross_allowed)
verbs -= /mob/dead/proc/server_hop
to_chat(src, "<span class='notice'>Server Hop has been disabled.</span>")
return
if (alert(src, "Jump to server running at [config.cross_address]?", "Server Hop", "Yes", "No") != "Yes")
return 0
if (client && config.cross_allowed)
to_chat(src, "<span class='notice'>Sending you to [config.cross_address].</span>")
new /obj/screen/splash(client)
notransform = TRUE
sleep(29) //let the animation play
notransform = FALSE
winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources
client << link(config.cross_address + "?server_hop=[key]")
else
to_chat(src, "<span class='error'>There is no other server configured!</span>")
@@ -30,6 +30,7 @@
loc = pick(GLOB.newplayer_start)
else
loc = locate(1,1,1)
return INITIALIZE_HINT_NORMAL
/mob/dead/new_player/proc/new_player_panel()
@@ -48,11 +49,11 @@
output += "<p><a href='byond://?src=\ref[src];observe=1'>Observe</A></p>"
if(!IsGuestKey(src.key))
if (SSdbcore.Connect())
if (SSdbcore.Connect())
var/isadmin = 0
if(src.client && src.client.holder)
isadmin = 1
var/datum/DBQuery/query_get_new_polls = SSdbcore.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
var/datum/DBQuery/query_get_new_polls = SSdbcore.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
if(!query_get_new_polls.Execute())
return
var/newpoll = 0
@@ -302,7 +303,7 @@
if(!IsJobAvailable(rank))
alert(src, "[rank] is not available. Please try another.")
return 0
if(SSticker.late_join_disabled)
alert(src, "An administrator has disabled late join spawning.")
return FALSE
@@ -0,0 +1,9 @@
diff a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm (rejected hunks)
@@ -30,6 +30,7 @@
loc = pick(newplayer_start)
else
loc = locate(1,1,1)
+ return INITIALIZE_HINT_NORMAL
/mob/dead/new_player/proc/new_player_panel()
+7 -29
View File
@@ -58,9 +58,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
verbs += /mob/dead/observer/proc/dead_tele
if(config.cross_allowed)
verbs += /mob/dead/observer/proc/server_hop
if(icon_state in GLOB.ghost_forms_with_directions_list)
ghostimage_default = image(src.icon,src,src.icon_state + "_nodir")
else
@@ -355,9 +352,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(!isobserver(usr))
to_chat(usr, "Not when you're not dead!")
return
var/A
A = input("Area to jump to", "BOOYEA", A) as null|anything in GLOB.sortedAreas
var/area/thearea = A
var/list/filtered = list()
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(!A.hidden)
filtered += A
var/area/thearea = input("Area to jump to", "BOOYEA") as null|anything in filtered
if(!thearea)
return
@@ -586,29 +587,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
target.faction = list("neutral")
return 1
/mob/dead/observer/proc/server_hop()
set category = "Ghost"
set name = "Server Hop!"
set desc= "Jump to the other server"
if(notransform)
return
if(!config.cross_allowed)
verbs -= /mob/dead/observer/proc/server_hop
to_chat(src, "<span class='notice'>Server Hop has been disabled.</span>")
return
if (alert(src, "Jump to server running at [config.cross_address]?", "Server Hop", "Yes", "No") != "Yes")
return 0
if (client && config.cross_allowed)
to_chat(src, "<span class='notice'>Sending you to [config.cross_address].</span>")
new /obj/screen/splash(client)
notransform = TRUE
sleep(29) //let the animation play
notransform = FALSE
winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources
client << link(config.cross_address + "?server_hop=[key]")
else
to_chat(src, "<span class='error'>There is no other server configured!</span>")
/proc/show_server_hop_transfer_screen(expected_key)
//only show it to incoming ghosts
for(var/mob/dead/observer/O in GLOB.player_list)
+4 -1
View File
@@ -50,7 +50,8 @@
if(C.has_brain_worms())
var/mob/living/simple_animal/borer/B = C.has_brain_worms()
B.leave_victim() //Should remove borer if the brain is removed - RR
transfer_identity(C)
if(!gc_destroyed || (owner && !owner.gc_destroyed))
transfer_identity(C)
C.update_hair()
/obj/item/organ/brain/prepare_eat()
@@ -60,6 +61,8 @@
name = "[L.name]'s brain"
if(brainmob || decoy_override)
return
if(!L.mind)
return
brainmob = new(src)
brainmob.name = L.real_name
brainmob.real_name = L.real_name
+1 -1
View File
@@ -728,7 +728,7 @@
/mob/living/carbon/can_be_revived()
. = ..()
if(!getorgan(/obj/item/organ/brain))
if(!getorgan(/obj/item/organ/brain) && (!mind || !mind.changeling))
return 0
/mob/living/carbon/harvest(mob/living/user)
+5 -6
View File
@@ -1,10 +1,9 @@
/mob/living/carbon/human/say_quote(input, spans, message_mode)
/mob/living/carbon/human/say_mod(input, message_mode)
verb_say = dna.species.say_mod
. = ..()
if(src.slurring)
input = attach_spans(input, spans)
return "slurs, \"[input]\""
if(slurring)
return "slurs"
else
. = ..()
/mob/living/carbon/human/treat_message(message)
message = dna.species.handle_speech(message,src)
+70 -72
View File
@@ -67,7 +67,7 @@
//Eyes
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
//Ears
var/obj/item/organ/ears/mutantears = /obj/item/organ/ears
@@ -497,6 +497,8 @@
var/g = (H.gender == FEMALE) ? "f" : "m"
var/image/I
for(var/layer in relevant_layers)
var/layertext = mutant_bodyparts_layertext(layer)
@@ -561,9 +563,9 @@
S = /datum/sprite_accessory/slimecoon_snout*/
if(!S || S.icon_state == "none")
continue
var/mutable_appearance/accessory_overlay = mutable_appearance(S.icon, layer = -layer)
//A little rename so we don't have to use tail_lizard or tail_human when naming the sprites.
if(bodypart == "tail_lizard" || bodypart == "tail_human" || bodypart == "mam_tail" || bodypart == "slimecoontail" || bodypart == "xenotail")
bodypart = "tail"
@@ -574,11 +576,15 @@
if(bodypart == "xenohead")
bodypart = "xhead"
var/icon_string
if(S.gender_specific)
accessory_overlay.icon_state = "[g]_[bodypart]_[S.icon_state]_[layertext]"
else
accessory_overlay.icon_state = "m_[bodypart]_[S.icon_state]_[layertext]"
I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer)
if(S.center)
accessory_overlay = center_image(accessory_overlay, S.dimension_x, S.dimension_y)
@@ -624,86 +630,78 @@
inner_accessory_overlay = center_image(inner_accessory_overlay, S.dimension_x, S.dimension_y)
standing += inner_accessory_overlay
if(S.extra) //apply the extra overlay, if there is one
var/mutable_appearance/extra_accessory_overlay = mutable_appearance(S.icon, layer = -layer)
if(S.gender_specific)
extra_accessory_overlay.icon_state = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]"
icon_string = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]"
else
extra_accessory_overlay.icon_state = "m_[bodypart]_extra_[S.icon_state]_[layertext]"
icon_string = "m_[bodypart]_extra_[S.icon_state]_[layertext]"
I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer)
if(S.center)
extra_accessory_overlay.icon_state = center_image(extra_accessory_overlay, S.dimension_x, S.dimension_y)
if(!forced_colour)
switch(S.extra_color_src) //change the color of the extra overlay
if(MUTCOLORS)
if(fixed_mut_color)
extra_accessory_overlay.color = "#[fixed_mut_color]"
else
extra_accessory_overlay.color = "#[H.dna.features["mcolor"]]"
if(MUTCOLORS2)
if(fixed_mut_color2)
extra_accessory_overlay.color = "#[fixed_mut_color2]"
else
extra_accessory_overlay.color = "#[H.dna.features["mcolor2"]]"
if(MUTCOLORS3)
if(fixed_mut_color3)
extra_accessory_overlay.color = "#[fixed_mut_color3]"
else
extra_accessory_overlay.color = "#[H.dna.features["mcolor3"]]"
if(HAIR)
if(hair_color == "mutcolor")
extra_accessory_overlay.color = "#[H.dna.features["mcolor"]]"
else
extra_accessory_overlay.color = "#[H.hair_color]"
if(FACEHAIR)
extra_accessory_overlay.color = "#[H.facial_hair_color]"
if(EYECOLOR)
extra_accessory_overlay.color = "#[H.eye_color]"
else
extra_accessory_overlay.color = forced_colour
standing += extra_accessory_overlay
I = center_image(I,S.dimension_x,S.dimension_y)
switch(S.extra_color_src) //change the color of the extra overlay
if(MUTCOLORS)
if(fixed_mut_color)
I.color = "#[fixed_mut_color]"
else
I.color = "#[H.dna.features["mcolor"]]"
if(MUTCOLORS2)
if(fixed_mut_color2)
I.color = "#[fixed_mut_color2]"
else
I.color = "#[H.dna.features["mcolor2"]]"
if(MUTCOLORS3)
if(fixed_mut_color3)
I.color = "#[fixed_mut_color3]"
else
I.color = "#[H.dna.features["mcolor3"]]"
if(HAIR)
if(hair_color == "mutcolor")
I.color = "#[H.dna.features["mcolor"]]"
else
I.color = "#[H.hair_color]"
if(FACEHAIR)
I.color = "#[H.facial_hair_color]"
if(EYECOLOR)
I.color = "#[H.eye_color]"
standing += I
if(S.extra2) //apply the extra overlay, if there is one
var/mutable_appearance/extra2_accessory_overlay = mutable_appearance(S.icon, layer = -layer)
if(S.gender_specific)
extra2_accessory_overlay.icon_state = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]"
icon_string = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]"
else
extra2_accessory_overlay.icon_state = "m_[bodypart]_extra2_[S.icon_state]_[layertext]"
icon_string = "m_[bodypart]_extra2_[S.icon_state]_[layertext]"
I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer)
if(S.center)
extra2_accessory_overlay.icon_state = center_image(extra2_accessory_overlay, S.dimension_x, S.dimension_y)
if(!forced_colour)
switch(S.extra_color_src) //change the color of the extra overlay
if(MUTCOLORS)
if(fixed_mut_color)
extra2_accessory_overlay.color = "#[fixed_mut_color]"
else
extra2_accessory_overlay.color = "#[H.dna.features["mcolor"]]"
if(MUTCOLORS2)
if(fixed_mut_color2)
extra2_accessory_overlay.color = "#[fixed_mut_color2]"
else
extra2_accessory_overlay.color = "#[H.dna.features["mcolor2"]]"
if(MUTCOLORS3)
if(fixed_mut_color3)
extra2_accessory_overlay.color = "#[fixed_mut_color3]"
else
extra2_accessory_overlay.color = "#[H.dna.features["mcolor3"]]"
if(HAIR)
if(hair_color == "mutcolor")
extra2_accessory_overlay.color = "#[H.dna.features["mcolor"]]"
else
extra2_accessory_overlay.color = "#[H.hair_color]"
if(FACEHAIR)
extra2_accessory_overlay.color = "#[H.facial_hair_color]"
if(EYECOLOR)
extra2_accessory_overlay.color = "#[H.eye_color]"
else
extra2_accessory_overlay.color = forced_colour
standing += extra2_accessory_overlay
I = center_image(I,S.dimension_x,S.dimension_y)
switch(S.extra2_color_src) //change the color of the extra overlay
if(MUTCOLORS)
if(fixed_mut_color)
I.color = "#[fixed_mut_color]"
else
I.color = "#[H.dna.features["mcolor"]]"
if(MUTCOLORS2)
if(fixed_mut_color2)
I.color = "#[fixed_mut_color2]"
else
I.color = "#[H.dna.features["mcolor2"]]"
if(MUTCOLORS3)
if(fixed_mut_color3)
I.color = "#[fixed_mut_color3]"
else
I.color = "#[H.dna.features["mcolor3"]]"
if(HAIR)
if(hair_color == "mutcolor")
I.color = "#[H.dna.features["mcolor"]]"
else
I.color = "#[H.hair_color]"
standing += I
H.overlays_standing[layer] = standing.Copy()
standing = list()
+7
View File
@@ -29,6 +29,13 @@
med_hud_set_status()
/mob/living/Destroy()
if(LAZYLEN(status_effects))
for(var/s in status_effects)
var/datum/status_effect/S = s
if(S.on_remove_on_mob_delete) //the status effect calls on_remove when its mob is deleted
qdel(S)
else
S.be_replaced()
if(ranged_ability)
ranged_ability.remove_ranged_ability(src)
if(buckled)
+12 -13
View File
@@ -423,18 +423,17 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 3
return 0
/mob/living/say_quote(input, list/spans, message_mode)
var/tempinput = attach_spans(input, spans)
/mob/living/say_mod(input, message_mode)
if(message_mode == MODE_WHISPER)
return "[verb_whisper], \"[tempinput]\""
if(message_mode == MODE_WHISPER_CRIT)
return "[verb_whisper] in [p_their()] last breath, \"[tempinput]\""
if (stuttering)
return "stammers, \"[tempinput]\""
if (getBrainLoss() >= 60)
return "gibbers, \"[tempinput]\""
return ..()
. = verb_whisper
else if(message_mode == MODE_WHISPER_CRIT)
. = "[verb_whisper] in [p_their()] last breath"
else if(stuttering)
. = "stammers"
else if(getBrainLoss() >= 60)
. = "gibbers"
else
. = ..()
/mob/living/get_default_language()
if(selected_default_language)
@@ -448,5 +447,5 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
/mob/living/proc/open_language_menu(mob/user)
language_menu.ui_interact(user)
/mob/living/whisper(message as text)
say("#[message]")
/mob/living/whisper(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null)
say("#[message]", bubble_type, spans, sanitize, language)
+2 -2
View File
@@ -238,7 +238,7 @@
else if(icontype == "Angel")
icon_state = "ai-angel"
//else
//usr <<"You can only change your display once!"
//to_chat(usr, "You can only change your display once!")
//return
/mob/living/silicon/ai/Stat()
@@ -351,7 +351,7 @@
if(isAI(usr))
var/mob/living/silicon/ai/AI = src
if(AI.control_disabled)
src << "Wireless control is disabled!"
to_chat(src, "Wireless control is disabled!")
return
SSshuttle.cancelEvac(src)
return
@@ -271,6 +271,7 @@
/obj/item/roller/robo,
/obj/item/borg/cyborghug/medical,
/obj/item/stack/medical/gauze/cyborg,
/obj/item/weapon/organ_storage,
/obj/item/borg/lollipop)
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/hacked)
ratvar_modules = list(
@@ -22,7 +22,7 @@
ventcrawler = VENTCRAWLER_ALWAYS
var/datum/mind/origin
var/egg_lain = 0
gold_core_spawnable = 1 //are you sure about this??
// gold_core_spawnable = 1 //are you sure about this??
/mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim)
var/obj/item/organ/body_egg/changeling_egg/egg = new(victim)
@@ -46,7 +46,7 @@ Difficulty: Very Hard
del_on_death = 1
medal_type = MEDAL_PREFIX
score_type = COLOSSUS_SCORE
loot = list(/obj/machinery/anomalous_crystal/random, /obj/item/organ/vocal_cords/colossus)
loot = list(/obj/effect/spawner/lootdrop/anomalous_crystal, /obj/item/organ/vocal_cords/colossus)
butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
deathmessage = "disintegrates, leaving a glowing core in its wake."
death_sound = 'sound/magic/demon_dies.ogg'
@@ -360,9 +360,20 @@ Difficulty: Very Hard
///Anomolous Crystal///
#define ACTIVATE_TOUCH "touch"
#define ACTIVATE_SPEECH "speech"
#define ACTIVATE_HEAT "heat"
#define ACTIVATE_BULLET "bullet"
#define ACTIVATE_ENERGY "energy"
#define ACTIVATE_BOMB "bomb"
#define ACTIVATE_MOB_BUMP "bumping"
#define ACTIVATE_WEAPON "weapon"
#define ACTIVATE_MAGIC "magic"
/obj/machinery/anomalous_crystal
name = "anomalous crystal"
desc = "A strange chunk of crystal, being in the presence of it fills you with equal parts excitement and dread."
var/observer_desc = "Anomalous crystals have descriptions that only observers can see. But this one hasn't been changed from the default."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "anomaly_crystal"
light_range = 8
@@ -370,66 +381,78 @@ Difficulty: Very Hard
use_power = 0
density = 1
flags = HEAR
var/activation_method = "touch"
var/activation_method
var/list/possible_methods = list(ACTIVATE_TOUCH, ACTIVATE_SPEECH, ACTIVATE_HEAT, ACTIVATE_BULLET, ACTIVATE_ENERGY, ACTIVATE_BOMB, ACTIVATE_MOB_BUMP, ACTIVATE_WEAPON, ACTIVATE_MAGIC)
var/activation_damage_type = null
var/last_use_timer = 0
var/cooldown_add = 30
var/list/affected_targets = list()
var/activation_sound = 'sound/effects/break_stone.ogg'
/obj/machinery/anomalous_crystal/New()
activation_method = pick("touch","laser","bullet","energy","bomb","mob_bump","heat","weapon","speech")
..()
/obj/machinery/anomalous_crystal/Initialize(mapload)
. = ..()
if(!activation_method)
activation_method = pick(possible_methods)
/obj/machinery/anomalous_crystal/examine(mob/user)
. = ..()
if(isobserver(user))
to_chat(user, observer_desc)
to_chat(user, "It is activated by [activation_method].")
/obj/machinery/anomalous_crystal/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans)
..()
if(isliving(speaker))
ActivationReaction(speaker,"speech")
ActivationReaction(speaker, ACTIVATE_SPEECH)
/obj/machinery/anomalous_crystal/attack_hand(mob/user)
..()
ActivationReaction(user,"touch")
ActivationReaction(user, ACTIVATE_TOUCH)
/obj/machinery/anomalous_crystal/attackby(obj/item/I, mob/user, params)
if(I.is_hot())
ActivationReaction(user,"heat")
ActivationReaction(user, ACTIVATE_HEAT)
else
ActivationReaction(user,"weapon")
ActivationReaction(user, ACTIVATE_WEAPON)
..()
/obj/machinery/anomalous_crystal/bullet_act(obj/item/projectile/P, def_zone)
..()
if(istype(P, /obj/item/projectile/magic))
ActivationReaction(P.firer, "magic", P.damage_type)
ActivationReaction(P.firer, ACTIVATE_MAGIC, P.damage_type)
return
ActivationReaction(P.firer, P.flag, P.damage_type)
/obj/machinery/anomalous_crystal/proc/ActivationReaction(mob/user, method, damtype)
if(world.time < last_use_timer)
return 0
return FALSE
if(activation_damage_type && activation_damage_type != damtype)
return 0
return FALSE
if(method != activation_method)
return 0
return FALSE
last_use_timer = (world.time + cooldown_add)
playsound(user, activation_sound, 100, 1)
return 1
return TRUE
/obj/machinery/anomalous_crystal/Bumped(atom/AM as mob|obj)
..()
if(ismob(AM))
ActivationReaction(AM,"mob_bump")
ActivationReaction(AM, ACTIVATE_MOB_BUMP)
/obj/machinery/anomalous_crystal/ex_act()
ActivationReaction(null,"bomb")
ActivationReaction(null, ACTIVATE_BOMB)
/obj/machinery/anomalous_crystal/random/New()//Just a random crysal spawner for loot
var/random_crystal = pick(typesof(/obj/machinery/anomalous_crystal) - /obj/machinery/anomalous_crystal/random - /obj/machinery/anomalous_crystal)
new random_crystal(loc)
qdel(src)
/obj/effect/spawner/lootdrop/anomalous_crystal
name = "anomalous crystal spawner"
/obj/effect/spawner/lootdrop/anomalous_crystal/Initialize()
loot = subtypesof(/obj/machinery/anomalous_crystal)
. = ..()
/obj/machinery/anomalous_crystal/honk //Strips and equips you as a clown. I apologize for nothing
activation_method = "mob_bump"
observer_desc = "This crystal strips and equips its targets as clowns."
possible_methods = list(ACTIVATE_MOB_BUMP, ACTIVATE_SPEECH)
activation_sound = 'sound/items/bikehorn.ogg'
/obj/machinery/anomalous_crystal/honk/ActivationReaction(mob/user)
@@ -442,12 +465,9 @@ Difficulty: Very Hard
qdel(C)
affected_targets.Add(H)
/obj/machinery/anomalous_crystal/honk/New()
..()
activation_method = pick("mob_bump","speech")
/obj/machinery/anomalous_crystal/theme_warp //Warps the area you're in to look like a new one
activation_method = "touch"
observer_desc = "This crystal warps the area around it to a theme."
activation_method = ACTIVATE_TOUCH
cooldown_add = 200
var/terrain_theme = "winter"
var/NewTerrainFloors
@@ -457,9 +477,11 @@ Difficulty: Very Hard
var/list/NewFlora = list()
var/florachance = 8
/obj/machinery/anomalous_crystal/theme_warp/New()
..()
/obj/machinery/anomalous_crystal/theme_warp/Initialize()
. = ..()
terrain_theme = pick("lavaland","winter","jungle","ayy lmao")
observer_desc = "This crystal changes the area around it to match the theme of \"[terrain_theme]\"."
switch(terrain_theme)
if("lavaland")//Depressurizes the place... and free cult metal, I guess.
NewTerrainFloors = /turf/open/floor/grass/snow/basalt
@@ -518,15 +540,19 @@ Difficulty: Very Hard
affected_targets += A
/obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with
activation_method = "touch"
observer_desc = "This crystal generates a projectile when activated."
activation_method = ACTIVATE_TOUCH
cooldown_add = 50
var/generated_projectile = /obj/item/projectile/beam/emitter
var/obj/item/projectile/generated_projectile = /obj/item/projectile/beam/emitter
/obj/machinery/anomalous_crystal/emitter/New()
..()
/obj/machinery/anomalous_crystal/emitter/Initialize()
. = ..()
generated_projectile = pick(/obj/item/projectile/magic/aoe/fireball/infernal,/obj/item/projectile/magic/aoe/lightning,/obj/item/projectile/magic/spellblade,
/obj/item/projectile/bullet/meteorshot, /obj/item/projectile/beam/xray, /obj/item/projectile/colossus)
var/proj_name = initial(generated_projectile.name)
observer_desc = "This crystal generates \a [proj_name] when activated."
/obj/machinery/anomalous_crystal/emitter/ActivationReaction(mob/user, method)
if(..())
var/obj/item/projectile/P = new generated_projectile(get_turf(src))
@@ -547,7 +573,8 @@ Difficulty: Very Hard
P.fire()
/obj/machinery/anomalous_crystal/dark_reprise //Revives anyone nearby, but turns them into shadowpeople and renders them uncloneable, so the crystal is your only hope of getting up again if you go down.
activation_method = "touch"
observer_desc = "When activated, this crystal revives anyone nearby, but turns them into Shadowpeople and makes them unclonable, making the crystal their only hope of getting up again."
activation_method = ACTIVATE_TOUCH
activation_sound = 'sound/hallucinations/growl1.ogg'
/obj/machinery/anomalous_crystal/dark_reprise/ActivationReaction(mob/user, method)
@@ -565,13 +592,20 @@ Difficulty: Very Hard
H.grab_ghost(force = TRUE)
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
activation_method = "touch"
var/ready_to_deploy = 0
observer_desc = "This crystal allows ghosts to turn into a fragile creature that can heal people."
activation_method = ACTIVATE_TOUCH
activation_sound = 'sound/effects/ghost2.ogg'
var/ready_to_deploy = FALSE
/obj/machinery/anomalous_crystal/helpers/Destroy()
GLOB.poi_list -= src
. = ..()
/obj/machinery/anomalous_crystal/helpers/ActivationReaction(mob/user, method)
if(..() && !ready_to_deploy)
ready_to_deploy = 1
notify_ghosts("An anomalous crystal has been activated in [get_area(src)]! This crystal can always be used by ghosts hereafter.", enter_link = "<a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
GLOB.poi_list |= src
ready_to_deploy = TRUE
notify_ghosts("An anomalous crystal has been activated in [get_area(src)]! This crystal can always be used by ghosts hereafter.", enter_link = "<a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>", ghost_sound = 'sound/effects/ghost2.ogg', source = src, action = NOTIFY_ATTACK)
/obj/machinery/anomalous_crystal/helpers/attack_ghost(mob/dead/observer/user)
..()
@@ -613,10 +647,12 @@ Difficulty: Very Hard
verb_ask = "floats inquisitively"
verb_exclaim = "zaps"
verb_yell = "bangs"
initial_languages = list(/datum/language/common, /datum/language/slime)
only_speaks_language = /datum/language/slime
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
light_range = 4
faction = list("neutral")
del_on_death = 1
del_on_death = TRUE
unsuitable_atmos_damage = 0
movement_type = FLYING
minbodytemp = 0
@@ -638,7 +674,7 @@ Difficulty: Very Hard
. = ..()
if(isliving(target) && target != src)
var/mob/living/L = target
if(L.stat < DEAD)
if(L.stat != DEAD)
L.heal_overall_damage(heal_power, heal_power)
new /obj/effect/overlay/temp/heal(get_turf(target), "#80F5FF")
@@ -649,13 +685,14 @@ Difficulty: Very Hard
/obj/machinery/anomalous_crystal/refresher //Deletes and recreates a copy of the item, "refreshing" it.
activation_method = "touch"
observer_desc = "This crystal \"refreshes\" items that it affects, rendering them as new."
activation_method = ACTIVATE_TOUCH
cooldown_add = 50
activation_sound = 'sound/magic/TIMEPARADOX2.ogg'
var/list/banned_items_typecache = list(/obj/item/weapon/storage, /obj/item/weapon/implant, /obj/item/weapon/implanter, /obj/item/weapon/disk/nuclear, /obj/item/projectile, /obj/item/weapon/spellbook)
/obj/machinery/anomalous_crystal/refresher/New()
..()
/obj/machinery/anomalous_crystal/refresher/Initialize()
. = ..()
banned_items_typecache = typecacheof(banned_items_typecache)
@@ -675,7 +712,8 @@ Difficulty: Very Hard
qdel(CHOSEN)
/obj/machinery/anomalous_crystal/possessor //Allows you to bodyjack small animals, then exit them at your leisure, but you can only do this once per activation. Because they blow up. Also, if the bodyjacked animal dies, SO DO YOU.
activation_method = "touch"
observer_desc = "When activated, this crystal allows you to take over small animals, and then exit them at the possessors leisure. Exiting the animal kills it, and if you die while possessing the animal, you die as well."
activation_method = ACTIVATE_TOUCH
/obj/machinery/anomalous_crystal/possessor/ActivationReaction(mob/user, method)
if(..())
@@ -770,4 +808,14 @@ Difficulty: Very Hard
target_mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
#undef ACTIVATE_TOUCH
#undef ACTIVATE_SPEECH
#undef ACTIVATE_HEAT
#undef ACTIVATE_BULLET
#undef ACTIVATE_ENERGY
#undef ACTIVATE_BOMB
#undef ACTIVATE_MOB_BUMP
#undef ACTIVATE_WEAPON
#undef ACTIVATE_MAGIC
#undef MEDAL_PREFIX
@@ -127,9 +127,11 @@
stuttering = 0
/mob/living/simple_animal/proc/handle_automated_action()
set waitfor = FALSE
return
/mob/living/simple_animal/proc/handle_automated_movement()
set waitfor = FALSE
if(!stop_automated_movement && wander)
if((isturf(src.loc) || allow_movement_on_non_turfs) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
turns_since_move++
@@ -142,6 +144,7 @@
return 1
/mob/living/simple_animal/proc/handle_automated_speech(var/override)
set waitfor = FALSE
if(speak_chance)
if(prob(speak_chance) || override)
if(speak && speak.len)
@@ -251,10 +254,10 @@
if(icon_gib)
new /obj/effect/overlay/temp/gib_animation/animal(loc, icon_gib)
/mob/living/simple_animal/say_quote(input, list/spans)
/mob/living/simple_animal/say_mod(input, message_mode)
if(speak_emote && speak_emote.len)
verb_say = pick(speak_emote)
return ..()
. = ..()
/mob/living/simple_animal/emote(act, m_type=1, message = null)
if(stat)
+2
View File
@@ -3,6 +3,7 @@
GLOB.dead_mob_list -= src
GLOB.living_mob_list -= src
GLOB.all_clockwork_mobs -= src
GLOB.mob_directory -= tag
if(observers && observers.len)
for(var/M in observers)
var/mob/dead/observe = M
@@ -22,6 +23,7 @@
/mob/Initialize()
tag = "mob_[next_mob_id++]"
GLOB.mob_list += src
GLOB.mob_directory[tag] = src
if(stat == DEAD)
GLOB.dead_mob_list += src
else
+1 -1
View File
@@ -396,7 +396,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
A.action = action
A.target = source
if(!alert_overlay)
alert_overlay = new(src)
alert_overlay = new(source)
alert_overlay.layer = FLOAT_LAYER
alert_overlay.plane = FLOAT_PLANE
A.add_overlay(alert_overlay)
+27 -16
View File
@@ -13,12 +13,6 @@
stored_implants += IMP
IMP.removed(src, 1, 1)
if (tr_flags & TR_KEEPORGANS)
for(var/X in internal_organs)
var/obj/item/organ/I = X
int_organs += I
I.Remove(src, 1)
var/list/missing_bodyparts_zones = get_missing_limbs()
var/obj/item/cavity_object
@@ -92,10 +86,21 @@
var/obj/item/weapon/implant/IMP = Y
IMP.implant(O, null, 1)
//re-add organs to new mob
//re-add organs to new mob. this order prevents moving the mind to a brain at any point
if(tr_flags & TR_KEEPORGANS)
for(var/X in O.internal_organs)
qdel(X)
var/obj/item/organ/I = X
I.Remove(O, 1)
if(mind)
mind.transfer_to(O)
if(O.mind.changeling)
O.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
for(var/X in internal_organs)
var/obj/item/organ/I = X
int_organs += I
I.Remove(src, 1)
for(var/X in int_organs)
var/obj/item/organ/I = X
@@ -118,7 +123,7 @@
qdel(G) //we lose the organs in the missing limbs
qdel(BP)
//transfer mind and delete old mob
//transfer mind if we didn't yet
if(mind)
mind.transfer_to(O)
if(O.mind.changeling)
@@ -154,12 +159,6 @@
stored_implants += IMP
IMP.removed(src, 1, 1)
if (tr_flags & TR_KEEPORGANS)
for(var/X in internal_organs)
var/obj/item/organ/I = X
int_organs += I
I.Remove(src, 1)
var/list/missing_bodyparts_zones = get_missing_limbs()
var/obj/item/cavity_object
@@ -244,7 +243,19 @@
if(tr_flags & TR_KEEPORGANS)
for(var/X in O.internal_organs)
qdel(X)
var/obj/item/organ/I = X
I.Remove(O, 1)
if(mind)
mind.transfer_to(O)
if(O.mind.changeling)
for(var/obj/effect/proc_holder/changeling/humanform/HF in O.mind.changeling.purchasedpowers)
mind.changeling.purchasedpowers -= HF
for(var/X in internal_organs)
var/obj/item/organ/I = X
int_organs += I
I.Remove(src, 1)
for(var/X in int_organs)
var/obj/item/organ/I = X