Merge branch 'master' into upstream-merge-26386
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user