mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 08:34:16 +01:00
fixes merge conflict
This commit is contained in:
@@ -53,7 +53,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
if(ismob(body))
|
||||
T = get_turf(body) //Where is the body located?
|
||||
attack_log_old = body.attack_log_old //preserve our attack logs by copying them to our ghost
|
||||
logs = body.logs.Copy()
|
||||
|
||||
var/mutable_appearance/MA = copy_appearance(body)
|
||||
if(body.mind && body.mind.name)
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
/mob/dead/observer/say(var/message)
|
||||
/mob/dead/observer/say(message)
|
||||
message = sanitize(copytext(message, 1, MAX_MESSAGE_LEN))
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
log_ghostsay(message, src)
|
||||
|
||||
if(src.client)
|
||||
if(src.client.prefs.muted & MUTE_DEADCHAT)
|
||||
to_chat(src, "<span class='warning'>You cannot talk in deadchat (muted).</span>")
|
||||
return
|
||||
|
||||
if(src.client.handle_spam_prevention(message,MUTE_DEADCHAT))
|
||||
return
|
||||
|
||||
. = src.say_dead(message)
|
||||
return say_dead(message)
|
||||
|
||||
|
||||
/mob/dead/observer/emote(act, type, message, force)
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
. = trim(. + trim(msg))
|
||||
. += "\""
|
||||
|
||||
/mob/proc/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency)
|
||||
/mob/proc/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency, use_voice = TRUE)
|
||||
if(!client)
|
||||
return 0
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
return 0
|
||||
|
||||
var/speaker_name = speaker.name
|
||||
if(ishuman(speaker))
|
||||
if(use_voice && ishuman(speaker))
|
||||
var/mob/living/carbon/human/H = speaker
|
||||
speaker_name = H.GetVoice()
|
||||
|
||||
@@ -99,9 +99,9 @@
|
||||
if(speaker == src)
|
||||
to_chat(src, "<span class='warning'>You cannot hear yourself speak!</span>")
|
||||
else
|
||||
to_chat(src, "<span class='name'>[speaker_name]</span>[speaker.GetAltName()] talks but you cannot hear [speaker.p_them()].")
|
||||
to_chat(src, "<span class='name'>[speaker.name]</span> talks but you cannot hear [speaker.p_them()].")
|
||||
else
|
||||
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[speaker.GetAltName()] [track][message]</span>")
|
||||
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[use_voice ? speaker.GetAltName() : ""] [track][message]</span>")
|
||||
if(speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z))
|
||||
var/turf/source = speaker? get_turf(speaker) : get_turf(src)
|
||||
playsound_local(source, speech_sound, sound_vol, 1, sound_frequency)
|
||||
@@ -171,7 +171,14 @@
|
||||
|
||||
to_chat(src, heard)
|
||||
|
||||
/mob/proc/hear_holopad_talk(list/message_pieces, var/verb = "says", var/mob/speaker = null)
|
||||
/mob/proc/hear_holopad_talk(list/message_pieces, verb = "says", mob/speaker = null)
|
||||
if(sleeping || stat == UNCONSCIOUS)
|
||||
hear_sleep(multilingual_to_message(message_pieces))
|
||||
return
|
||||
|
||||
if(!can_hear())
|
||||
return
|
||||
|
||||
var/message = combine_message(message_pieces, verb, speaker)
|
||||
|
||||
var/name = speaker.name
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
if(prob(80))
|
||||
new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]"
|
||||
else
|
||||
new_name += ..(gender,1)
|
||||
new_name += " [..(gender,1)]"
|
||||
return new_name
|
||||
|
||||
/datum/language/vulpkanin
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
/mob/living/carbon/alien/larva/show_inv(mob/user as mob)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
|
||||
/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
|
||||
return FALSE
|
||||
|
||||
/* Commented out because it's duplicated in life.dm
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
return
|
||||
polling = 1
|
||||
spawn()
|
||||
var/list/candidates = pollCandidates("Do you want to play as an alien?", ROLE_ALIEN, 0)
|
||||
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as an alien?", ROLE_ALIEN, FALSE, source = /mob/living/carbon/alien/larva)
|
||||
var/mob/C = null
|
||||
|
||||
// To stop clientless larva, we will check that our host has a client
|
||||
|
||||
@@ -538,6 +538,8 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
|
||||
take_organ_damage(10)
|
||||
if(iscarbon(hit_atom) && hit_atom != src)
|
||||
var/mob/living/carbon/victim = hit_atom
|
||||
if(victim.flying)
|
||||
return
|
||||
if(hurt)
|
||||
victim.take_organ_damage(10)
|
||||
take_organ_damage(10)
|
||||
|
||||
@@ -301,14 +301,13 @@
|
||||
else if(nutrition >= NUTRITION_LEVEL_FAT)
|
||||
msg += "[p_they(TRUE)] [p_are()] quite chubby.\n"
|
||||
|
||||
if(!ismachineperson(src) && blood_volume < BLOOD_VOLUME_SAFE)
|
||||
if(blood_volume < BLOOD_VOLUME_SAFE)
|
||||
msg += "[p_they(TRUE)] [p_have()] pale skin.\n"
|
||||
|
||||
if(bleedsuppress)
|
||||
msg += "[p_they(TRUE)] [p_are()] bandaged with something.\n"
|
||||
else if(bleed_rate)
|
||||
var/bleed_message = !ismachineperson(src) ? "bleeding" : "leaking"
|
||||
msg += "<B>[p_they(TRUE)] [p_are()] [bleed_message]!</B>\n"
|
||||
msg += "<B>[p_they(TRUE)] [p_are()] bleeding!</B>\n"
|
||||
|
||||
if(reagents.has_reagent("teslium"))
|
||||
msg += "[p_they(TRUE)] [p_are()] emitting a gentle blue glow!\n"
|
||||
|
||||
@@ -1447,12 +1447,13 @@
|
||||
var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes)
|
||||
var/obj/item/organ/internal/cyberimp/eyes/eye_implant = get_int_organ(/obj/item/organ/internal/cyberimp/eyes)
|
||||
if(istype(dna.species) && dna.species.eyes)
|
||||
var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', dna.species.eyes)
|
||||
var/icon/eyes_icon
|
||||
if(eye_implant) //Eye implants override native DNA eye colo(u)r
|
||||
eyes_icon = eye_implant.generate_icon()
|
||||
else if(eyes)
|
||||
eyes_icon = eyes.generate_icon()
|
||||
else //Error 404: Eyes not found!
|
||||
eyes_icon = new('icons/mob/human_face.dmi', dna.species.eyes)
|
||||
eyes_icon.Blend("#800000", ICON_ADD)
|
||||
|
||||
return eyes_icon
|
||||
|
||||
@@ -572,41 +572,34 @@ emp_act
|
||||
if(M.a_intent == INTENT_HARM)
|
||||
if(w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/damage = rand(15, 30)
|
||||
var/damage = prob(90) ? 20 : 0
|
||||
if(!damage)
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, TRUE, -1)
|
||||
visible_message("<span class='danger'>[M] has lunged at [src]!</span>")
|
||||
return 0
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_selected))
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
var/armor_block = run_armor_check(affecting, "melee", armour_penetration = 10)
|
||||
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, TRUE, -1)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
if(damage >= 25)
|
||||
visible_message("<span class='danger'>[M] has wounded [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has wounded [src]!</span>")
|
||||
apply_effect(4, WEAKEN, armor_block)
|
||||
add_attack_logs(M, src, "Alien attacked")
|
||||
add_attack_logs(M, src, "Alien attacked")
|
||||
updatehealth("alien attack")
|
||||
|
||||
if(M.a_intent == INTENT_DISARM)
|
||||
if(prob(80))
|
||||
if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stun instead.
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(I && unEquip(I))
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 25, TRUE, -1)
|
||||
visible_message("<span class='danger'>[M] disarms [src]!</span>", "<span class='userdanger'>[M] disarms you!</span>", "<span class='hear'>You hear aggressive shuffling!</span>")
|
||||
to_chat(M, "<span class='danger'>You disarm [src]!</span>")
|
||||
else
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_selected))
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
apply_effect(5, WEAKEN, run_armor_check(affecting, "melee"))
|
||||
add_attack_logs(M, src, "Alien tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>")
|
||||
else
|
||||
if(prob(99)) //this looks fucking stupid but it was previously 'var/randn = rand(1, 100); if(randn <= 99)'
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
drop_item()
|
||||
visible_message("<span class='danger'>[M] disarmed [src]!</span>")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has tried to disarm [src]!</span>")
|
||||
|
||||
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
|
||||
. = ..()
|
||||
|
||||
@@ -74,6 +74,10 @@
|
||||
..()
|
||||
H.gender = NEUTER
|
||||
|
||||
/datum/species/diona/on_species_loss(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
H.clear_alert("nolight")
|
||||
|
||||
/datum/species/diona/handle_reagents(mob/living/carbon/human/H, datum/reagent/R)
|
||||
if(R.id == "glyphosate" || R.id == "atrazine")
|
||||
H.adjustToxLoss(3) //Deal aditional damage
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
death_message = "gives a short series of shrill beeps, their chassis shuddering before falling limp, nonfunctional."
|
||||
death_sounds = list('sound/voice/borg_deathsound.ogg') //I've made this a list in the event we add more sounds for dead robots.
|
||||
|
||||
species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_INTORGANS, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NO_GERMS, NO_DECAY, NOTRANSSTING) //Computers that don't decay? What a lie!
|
||||
species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_SCAN, NO_INTORGANS, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NO_GERMS, NO_DECAY, NOTRANSSTING) //Computers that don't decay? What a lie!
|
||||
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
|
||||
bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS
|
||||
dietflags = 0 //IPCs can't eat, so no diet
|
||||
@@ -30,10 +30,6 @@
|
||||
blood_color = "#1F181F"
|
||||
flesh_color = "#AAAAAA"
|
||||
|
||||
blood_color = "#3C3C3C"
|
||||
exotic_blood = "oil"
|
||||
blood_damage_type = STAMINA
|
||||
|
||||
//Default styles for created mobs.
|
||||
default_hair = "Blue IPC Screen"
|
||||
dies_at_threshold = TRUE
|
||||
|
||||
@@ -273,11 +273,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
|
||||
overlays_standing[UNDERWEAR_LAYER] = mutable_appearance(underwear_standing, layer = -UNDERWEAR_LAYER)
|
||||
apply_overlay(UNDERWEAR_LAYER)
|
||||
|
||||
if(lip_style && (LIPS in dna.species.species_traits))
|
||||
var/mutable_appearance/lips = mutable_appearance('icons/mob/human_face.dmi', "lips_[lip_style]_s")
|
||||
lips.color = lip_color
|
||||
standing += lips
|
||||
|
||||
overlays_standing[BODY_LAYER] = standing
|
||||
apply_overlay(BODY_LAYER)
|
||||
//tail
|
||||
@@ -1303,6 +1298,11 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
|
||||
else
|
||||
. += "#000000"
|
||||
|
||||
if(lip_color && (LIPS in dna.species.species_traits))
|
||||
. += "[lip_color]"
|
||||
else
|
||||
. += "#000000"
|
||||
|
||||
for(var/organ_tag in dna.species.has_limbs)
|
||||
var/obj/item/organ/external/part = bodyparts_by_name[organ_tag]
|
||||
if(isnull(part))
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
if(changed)
|
||||
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
|
||||
handle_transform_change()
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
|
||||
floating = FALSE // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
|
||||
|
||||
/mob/living/carbon/proc/handle_transform_change()
|
||||
return
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
set waitfor = FALSE
|
||||
set invisibility = 0
|
||||
|
||||
if(flying) //TODO: Better floating
|
||||
animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING)
|
||||
animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING)
|
||||
if(flying && !floating) //TODO: Better floating
|
||||
float(TRUE)
|
||||
|
||||
if(client || registered_z) // This is a temporary error tracker to make sure we've caught everything
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -3,8 +3,29 @@
|
||||
var/datum/atom_hud/data/human/medical/advanced/medhud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
medhud.add_to_hud(src)
|
||||
faction += "\ref[src]"
|
||||
determine_move_and_pull_forces()
|
||||
GLOB.mob_living_list += src
|
||||
|
||||
// Used to determine the forces dependend on the mob size
|
||||
// Will only change the force if the force was not set in the mob type itself
|
||||
/mob/living/proc/determine_move_and_pull_forces()
|
||||
var/value
|
||||
switch(mob_size)
|
||||
if(MOB_SIZE_TINY)
|
||||
value = MOVE_FORCE_EXTREMELY_WEAK
|
||||
if(MOB_SIZE_SMALL)
|
||||
value = MOVE_FORCE_WEAK
|
||||
if(MOB_SIZE_HUMAN)
|
||||
value = MOVE_FORCE_NORMAL
|
||||
if(MOB_SIZE_LARGE)
|
||||
value = MOVE_FORCE_NORMAL // For now
|
||||
if(!move_force)
|
||||
move_force = value
|
||||
if(!pull_force)
|
||||
pull_force = value
|
||||
if(!move_resist)
|
||||
move_resist = value
|
||||
|
||||
/mob/living/prepare_huds()
|
||||
..()
|
||||
prepare_data_huds()
|
||||
@@ -203,7 +224,7 @@
|
||||
set category = "Object"
|
||||
|
||||
if(istype(AM) && Adjacent(AM))
|
||||
start_pulling(AM)
|
||||
start_pulling(AM, show_message = TRUE)
|
||||
else
|
||||
stop_pulling()
|
||||
|
||||
@@ -737,16 +758,17 @@
|
||||
/mob/living/proc/float(on)
|
||||
if(throwing)
|
||||
return
|
||||
var/fixed = 0
|
||||
var/fixed = FALSE
|
||||
if(anchored || (buckled && buckled.anchored))
|
||||
fixed = 1
|
||||
fixed = TRUE
|
||||
if(on && !floating && !fixed)
|
||||
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
|
||||
floating = 1
|
||||
sleep(10)
|
||||
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
|
||||
floating = TRUE
|
||||
else if(((!on || fixed) && floating))
|
||||
var/final_pixel_y = get_standard_pixel_y_offset(lying)
|
||||
animate(src, pixel_y = final_pixel_y, time = 10)
|
||||
floating = 0
|
||||
animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10)
|
||||
floating = FALSE
|
||||
|
||||
/mob/living/proc/can_use_vents()
|
||||
return "You can't fit into that vent."
|
||||
@@ -821,15 +843,17 @@
|
||||
if(!used_item)
|
||||
used_item = get_active_hand()
|
||||
..()
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
floating = FALSE // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
|
||||
/mob/living/proc/do_jitter_animation(jitteriness, loop_amount = 6)
|
||||
var/amplitude = min(4, (jitteriness/100) + 1)
|
||||
var/amplitude = min(4, (jitteriness / 100) + 1)
|
||||
var/pixel_x_diff = rand(-amplitude, amplitude)
|
||||
var/pixel_y_diff = rand(-amplitude/3, amplitude/3)
|
||||
var/pixel_y_diff = rand(-amplitude / 3, amplitude / 3)
|
||||
var/final_pixel_x = get_standard_pixel_x_offset(lying)
|
||||
var/final_pixel_y = get_standard_pixel_y_offset(lying)
|
||||
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = loop_amount)
|
||||
animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y) , time = 2)
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2)
|
||||
floating = FALSE // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
|
||||
|
||||
/mob/living/proc/get_temperature(datum/gas_mixture/environment)
|
||||
@@ -921,10 +945,10 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, supress_message = FALSE)
|
||||
/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
|
||||
if(!AM || !src)
|
||||
return FALSE
|
||||
if(!(AM.can_be_pulled(src, state, force)))
|
||||
if(!(AM.can_be_pulled(src, state, force, show_message)))
|
||||
return FALSE
|
||||
if(incapacitated())
|
||||
return
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
fire_stacks += L.fire_stacks
|
||||
IgniteMob()
|
||||
|
||||
/mob/living/can_be_pulled(user, grab_state, force)
|
||||
/mob/living/can_be_pulled(user, grab_state, force, show_message = FALSE)
|
||||
return ..() && !(buckled && buckled.buckle_prevents_pull)
|
||||
|
||||
/mob/living/water_act(volume, temperature, source, method = REAGENT_TOUCH)
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
pressure_resistance = 10
|
||||
|
||||
// Will be determined based on mob size if left null. Done in living/proc/determine_move_and_pull_forces()
|
||||
move_resist = null
|
||||
move_force = null
|
||||
pull_force = null
|
||||
|
||||
//Health and life related vars
|
||||
var/maxHealth = 100 //Maximum health that should be possible.
|
||||
var/health = 100 //A mob's health
|
||||
@@ -28,7 +33,7 @@
|
||||
var/on_fire = 0 //The "Are we on fire?" var
|
||||
var/fire_stacks = 0 //Tracks how many stacks of fire we have on, max is usually 20
|
||||
|
||||
var/floating = 0
|
||||
var/floating = FALSE
|
||||
var/mob_size = MOB_SIZE_HUMAN
|
||||
var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature..
|
||||
var/digestion_ratio = 1 //controls how quickly reagents metabolize; largely governered by species attributes.
|
||||
|
||||
@@ -351,8 +351,6 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return
|
||||
|
||||
if(stat)
|
||||
if(stat == DEAD)
|
||||
return say_dead(message_pieces)
|
||||
return
|
||||
|
||||
if(is_muzzled())
|
||||
@@ -451,14 +449,14 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
var/speech_bubble_test = say_test(message)
|
||||
|
||||
for(var/mob/M in listening)
|
||||
M.hear_say(message_pieces, verb, italics, src)
|
||||
M.hear_say(message_pieces, verb, italics, src, use_voice = FALSE)
|
||||
if(M.client)
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
|
||||
if(eavesdropping.len)
|
||||
stars_all(message_pieces) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
|
||||
for(var/mob/M in eavesdropping)
|
||||
M.hear_say(message_pieces, verb, italics, src)
|
||||
M.hear_say(message_pieces, verb, italics, src, use_voice = FALSE)
|
||||
if(M.client)
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
var/list/connected_robots = list()
|
||||
var/aiRestorePowerRoutine = 0
|
||||
//var/list/laws = list()
|
||||
var/alarms = list("Motion" = list(), "Fire" = list(), "Atmosphere" = list(), "Power" = list(), "Camera" = list())
|
||||
alarms_listend_for = list("Motion", "Fire", "Atmosphere", "Power", "Camera", "Burglar")
|
||||
var/viewalerts = 0
|
||||
var/icon/holo_icon//Default is assigned when AI is created.
|
||||
var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye.
|
||||
@@ -173,19 +173,19 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
add_language("Galactic Common", 1)
|
||||
add_language("Sol Common", 1)
|
||||
add_language("Tradeband", 1)
|
||||
add_language("Neo-Russkiya", 0)
|
||||
add_language("Gutter", 0)
|
||||
add_language("Sinta'unathi", 0)
|
||||
add_language("Siik'tajr", 0)
|
||||
add_language("Canilunzt", 0)
|
||||
add_language("Skrellian", 0)
|
||||
add_language("Vox-pidgin", 0)
|
||||
add_language("Orluum", 0)
|
||||
add_language("Rootspeak", 0)
|
||||
add_language("Neo-Russkiya", 1)
|
||||
add_language("Gutter", 1)
|
||||
add_language("Sinta'unathi", 1)
|
||||
add_language("Siik'tajr", 1)
|
||||
add_language("Canilunzt", 1)
|
||||
add_language("Skrellian", 1)
|
||||
add_language("Vox-pidgin", 1)
|
||||
add_language("Orluum", 1)
|
||||
add_language("Rootspeak", 1)
|
||||
add_language("Trinary", 1)
|
||||
add_language("Chittin", 0)
|
||||
add_language("Bubblish", 0)
|
||||
add_language("Clownish", 0)
|
||||
add_language("Chittin", 1)
|
||||
add_language("Bubblish", 1)
|
||||
add_language("Clownish", 1)
|
||||
|
||||
if(!safety)//Only used by AIize() to successfully spawn an AI.
|
||||
if(!B)//If there is no player/brain inside.
|
||||
@@ -242,6 +242,46 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
return
|
||||
show_borg_info()
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_alerts()
|
||||
var/list/dat = list("<HEAD><TITLE>Current Station Alerts</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n")
|
||||
dat += "<A HREF='?src=[UID()];mach_close=aialerts'>Close</A><BR><BR>"
|
||||
var/list/list/temp_alarm_list = SSalarm.alarms.Copy()
|
||||
for(var/cat in temp_alarm_list)
|
||||
if(!(cat in alarms_listend_for))
|
||||
continue
|
||||
dat += text("<B>[]</B><BR>\n", cat)
|
||||
var/list/list/L = temp_alarm_list[cat].Copy()
|
||||
for(var/alarm in L)
|
||||
var/list/list/alm = L[alarm].Copy()
|
||||
var/area_name = alm[1]
|
||||
var/C = alm[2]
|
||||
var/list/list/sources = alm[3].Copy()
|
||||
for(var/thing in sources)
|
||||
var/atom/A = locateUID(thing)
|
||||
if(A && A.z != z)
|
||||
L -= alarm
|
||||
continue
|
||||
dat += "<NOBR>"
|
||||
if(C && islist(C))
|
||||
var/dat2 = ""
|
||||
for(var/cam in C)
|
||||
var/obj/machinery/camera/I = locateUID(cam)
|
||||
if(!QDELETED(I))
|
||||
dat2 += text("[]<A HREF=?src=[UID()];switchcamera=[cam]>[]</A>", (dat2 == "") ? "" : " | ", I.c_tag)
|
||||
dat += text("-- [] ([])", area_name, (dat2 != "") ? dat2 : "No Camera")
|
||||
else
|
||||
dat += text("-- [] (No Camera)", area_name)
|
||||
if(sources.len > 1)
|
||||
dat += text("- [] sources", sources.len)
|
||||
dat += "</NOBR><BR>\n"
|
||||
if(!L.len)
|
||||
dat += "-- All Systems Nominal<BR>\n"
|
||||
dat += "<BR>\n"
|
||||
|
||||
viewalerts = TRUE
|
||||
var/dat_text = dat.Join("")
|
||||
src << browse(dat_text, "window=aialerts&can_close=0")
|
||||
|
||||
/mob/living/silicon/ai/proc/show_borg_info()
|
||||
stat(null, text("Connected cyborgs: [connected_robots.len]"))
|
||||
for(var/thing in connected_robots)
|
||||
@@ -612,7 +652,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
if(href_list["switchcamera"])
|
||||
switchCamera(locate(href_list["switchcamera"])) in GLOB.cameranet.cameras
|
||||
if(href_list["showalerts"])
|
||||
subsystem_alarm_monitor()
|
||||
ai_alerts()
|
||||
if(href_list["show_paper"])
|
||||
if(last_paper_seen)
|
||||
src << browse(last_paper_seen, "window=show_paper")
|
||||
@@ -787,12 +827,49 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
|
||||
Bot.call_bot(src, waypoint)
|
||||
|
||||
/mob/living/silicon/ai/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
|
||||
if(!(class in alarms_listend_for))
|
||||
return
|
||||
if(alarmsource.z != z)
|
||||
return
|
||||
if(stat == DEAD)
|
||||
return TRUE
|
||||
if(O)
|
||||
var/obj/machinery/camera/C = locateUID(O[1])
|
||||
if(O.len == 1 && !QDELETED(C) && C.can_use())
|
||||
queueAlarm("--- [class] alarm detected in [A.name]! (<A HREF=?src=[UID()];switchcamera=[O[1]]>[C.c_tag]</A>)", class)
|
||||
else if(O && O.len)
|
||||
var/foo = 0
|
||||
var/dat2 = ""
|
||||
for(var/thing in O)
|
||||
var/obj/machinery/camera/I = locateUID(thing)
|
||||
if(!QDELETED(I))
|
||||
dat2 += text("[]<A HREF=?src=[UID()];switchcamera=[thing]>[]</A>", (!foo) ? "" : " | ", I.c_tag) //I'm not fixing this shit...
|
||||
foo = 1
|
||||
queueAlarm(text ("--- [] alarm detected in []! ([])", class, A.name, dat2), class)
|
||||
else
|
||||
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class)
|
||||
else
|
||||
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class)
|
||||
if(viewalerts)
|
||||
ai_alerts()
|
||||
|
||||
/mob/living/silicon/ai/alarm_cancelled(src, class, area/A, obj/origin, cleared)
|
||||
if(cleared)
|
||||
if(!(class in alarms_listend_for))
|
||||
return
|
||||
if(origin.z != z)
|
||||
return
|
||||
queueAlarm("--- [class] alarm in [A.name] has been cleared.", class, 0)
|
||||
if(viewalerts)
|
||||
ai_alerts()
|
||||
|
||||
/mob/living/silicon/ai/proc/switchCamera(obj/machinery/camera/C)
|
||||
|
||||
if(!tracking)
|
||||
cameraFollow = null
|
||||
|
||||
if(!C || stat == DEAD) //C.can_use())
|
||||
if(QDELETED(C) || stat == DEAD) //C.can_use())
|
||||
return FALSE
|
||||
|
||||
if(!eyeobj)
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
acceleration = !acceleration
|
||||
to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
|
||||
|
||||
/mob/camera/aiEye/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency)
|
||||
/mob/camera/aiEye/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency, use_voice = TRUE)
|
||||
if(relay_speech)
|
||||
if(istype(ai))
|
||||
ai.relay_speech(speaker, message_pieces, verb)
|
||||
|
||||
@@ -132,8 +132,6 @@
|
||||
sleep(50)
|
||||
theAPC = null
|
||||
|
||||
process_queued_alarms()
|
||||
|
||||
/mob/living/silicon/ai/updatehealth(reason = "none given")
|
||||
if(status_flags & GODMODE)
|
||||
health = 100
|
||||
|
||||
@@ -80,17 +80,26 @@ GLOBAL_VAR_INIT(announcing_vox, 0) // Stores the time of the last announcement
|
||||
<LI>Do not use punctuation as you would normally, if you want a pause you can use the full stop and comma characters by separating them with spaces, like so: 'Alpha . Test , Bravo'.</LI></UL>\
|
||||
<font class='bad'>WARNING:</font><BR>Misuse of the announcement system will get you job banned.<HR>"
|
||||
|
||||
var/index = 0
|
||||
for(var/word in GLOB.vox_sounds)
|
||||
index++
|
||||
dat += "<A href='?src=[UID()];say_word=[word]'>[capitalize(word)]</A>"
|
||||
if(index != GLOB.vox_sounds.len)
|
||||
dat += " / "
|
||||
// Show alert and voice sounds separately
|
||||
var/vox_words = GLOB.vox_sounds - GLOB.vox_alerts
|
||||
dat = help_format(GLOB.vox_alerts, dat)
|
||||
dat = help_format(vox_words, dat)
|
||||
|
||||
var/datum/browser/popup = new(src, "announce_help", "Announcement Help", 500, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/mob/living/silicon/ai/proc/help_format(word_list, dat)
|
||||
var/index = 0
|
||||
for(var/word in word_list)
|
||||
index++
|
||||
dat += "<A href='?src=[UID()];say_word=[word]'>[capitalize(word)]</A>"
|
||||
if(index != length(word_list))
|
||||
dat += " / "
|
||||
else
|
||||
dat += "<HR>"
|
||||
return dat
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_announcement()
|
||||
if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO))
|
||||
return
|
||||
|
||||
@@ -517,7 +517,7 @@
|
||||
/mob/living/silicon/pai/Bumped()
|
||||
return
|
||||
|
||||
/mob/living/silicon/pai/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
|
||||
/mob/living/silicon/pai/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/update_canmove(delay_action_updates = 0)
|
||||
@@ -563,6 +563,10 @@
|
||||
var/obj/item/holder/H = ..()
|
||||
if(!istype(H))
|
||||
return
|
||||
if(stat == DEAD)
|
||||
H.icon = 'icons/mob/pai.dmi'
|
||||
H.icon_state = "[chassis]_dead"
|
||||
return
|
||||
if(resting)
|
||||
icon_state = "[chassis]"
|
||||
resting = 0
|
||||
|
||||
@@ -312,8 +312,3 @@ proc/robot_healthscan(mob/user, mob/living/M)
|
||||
to_chat(user, "[capitalize(O.name)]: <font color='red'>[O.damage]</font>")
|
||||
if(!organ_found)
|
||||
to_chat(user, "<span class='warning'>No prosthetics located.</span>")
|
||||
|
||||
if(ismachineperson(H))
|
||||
to_chat(user, "<span class='notice'>Internal Fluid Level:[H.blood_volume]/[H.max_blood]</span>")
|
||||
if(H.bleed_rate)
|
||||
to_chat(user, "<span class='warning'>Warning:External component leak detected!</span>")
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
emote("deathgasp", force = TRUE)
|
||||
|
||||
if(module)
|
||||
module.handle_death(gibbed)
|
||||
module.handle_death(src, gibbed)
|
||||
|
||||
// Only execute the below if we successfully died
|
||||
. = ..(gibbed)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
ventcrawler = 2
|
||||
magpulse = 1
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
pull_force = MOVE_FORCE_VERY_WEAK // Can only drag small items
|
||||
|
||||
modules_break = FALSE
|
||||
|
||||
@@ -35,6 +36,14 @@
|
||||
var/reboot_cooldown = 60 // one minute
|
||||
var/last_reboot
|
||||
var/emagged_time
|
||||
var/list/pullable_drone_items = list(
|
||||
/obj/item/pipe,
|
||||
/obj/structure/disposalconstruct,
|
||||
/obj/item/stack/cable_coil,
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/stack/sheet,
|
||||
/obj/item/stack/tile
|
||||
)
|
||||
|
||||
holder_type = /obj/item/holder/drone
|
||||
// var/sprite[0]
|
||||
@@ -50,7 +59,7 @@
|
||||
|
||||
// Disable the microphone wire on Drones
|
||||
if(radio)
|
||||
radio.wires.CutWireIndex(RADIO_WIRE_TRANSMIT)
|
||||
radio.wires.cut(WIRE_RADIO_TRANSMIT)
|
||||
|
||||
if(camera && ("Robots" in camera.network))
|
||||
camera.network.Add("Engineering")
|
||||
@@ -69,6 +78,10 @@
|
||||
verbs -= /mob/living/silicon/robot/verb/Namepick
|
||||
module = new /obj/item/robot_module/drone(src)
|
||||
|
||||
//Allows Drones to hear the Engineering channel.
|
||||
module.channels = list("Engineering" = 1)
|
||||
radio.recalculateChannels()
|
||||
|
||||
//Grab stacks.
|
||||
stack_metal = locate(/obj/item/stack/sheet/metal/cyborg) in src.module
|
||||
stack_wood = locate(/obj/item/stack/sheet/wood) in src.module
|
||||
@@ -154,15 +167,17 @@
|
||||
return
|
||||
|
||||
else
|
||||
user.visible_message("<span class='warning'>\the [user] swipes [user.p_their()] ID card through [src], attempting to shut it down.</span>", "<span class='warning'>You swipe your ID card through \the [src], attempting to shut it down.</span>")
|
||||
var/confirm = alert("Using your ID on a Maintenance Drone will shut it down, are you sure you want to do this?", "Disable Drone", "Yes", "No")
|
||||
if(confirm == ("Yes") && (user in range(3, src)))
|
||||
user.visible_message("<span class='warning'>\the [user] swipes [user.p_their()] ID card through [src], attempting to shut it down.</span>", "<span class='warning'>You swipe your ID card through \the [src], attempting to shut it down.</span>")
|
||||
|
||||
if(emagged)
|
||||
return
|
||||
if(emagged)
|
||||
return
|
||||
|
||||
if(allowed(W))
|
||||
shut_down()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
if(allowed(W))
|
||||
shut_down()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
|
||||
return
|
||||
|
||||
@@ -321,20 +336,22 @@
|
||||
/mob/living/silicon/robot/drone/Bumped(atom/movable/AM)
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
|
||||
/mob/living/silicon/robot/drone/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
|
||||
|
||||
if(is_type_in_list(AM, pullable_drone_items))
|
||||
..(AM, force = INFINITY) // Drone power! Makes them able to drag pipes and such
|
||||
|
||||
if(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct))
|
||||
..()
|
||||
else if(istype(AM,/obj/item))
|
||||
var/obj/item/O = AM
|
||||
if(O.w_class > WEIGHT_CLASS_SMALL)
|
||||
to_chat(src, "<span class='warning'>You are too small to pull that.</span>")
|
||||
if(show_message)
|
||||
to_chat(src, "<span class='warning'>You are too small to pull that.</span>")
|
||||
return
|
||||
else
|
||||
..()
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You are too small to pull that.</span>")
|
||||
return
|
||||
if(show_message)
|
||||
to_chat(src, "<span class='warning'>You are too small to pull that.</span>")
|
||||
|
||||
/mob/living/silicon/robot/drone/add_robot_verbs()
|
||||
src.verbs |= silicon_subsystems
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
//Has a list of items that it can hold.
|
||||
var/list/can_hold = list(
|
||||
/obj/item/stock_parts/cell,
|
||||
/obj/item/firealarm_electronics,
|
||||
/obj/item/airalarm_electronics,
|
||||
/obj/item/airlock_electronics,
|
||||
@@ -24,6 +23,8 @@
|
||||
/obj/item/mounted/frame/firealarm,
|
||||
/obj/item/mounted/frame/newscaster_frame,
|
||||
/obj/item/mounted/frame/intercom,
|
||||
/obj/item/mounted/frame/extinguisher,
|
||||
/obj/item/mounted/frame/light_switch,
|
||||
/obj/item/rack_parts,
|
||||
/obj/item/camera_assembly,
|
||||
/obj/item/tank,
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
handle_robot_cell()
|
||||
process_locks()
|
||||
update_items()
|
||||
process_queued_alarms()
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/handle_robot_cell()
|
||||
@@ -46,7 +45,7 @@
|
||||
|
||||
/mob/living/silicon/robot/proc/handle_equipment()
|
||||
if(camera && !scrambledcodes)
|
||||
if(stat == DEAD || wires.IsCameraCut())
|
||||
if(stat == DEAD || wires.is_cut(WIRE_BORG_CAMERA))
|
||||
camera.status = 0
|
||||
else
|
||||
camera.status = 1
|
||||
|
||||
@@ -59,7 +59,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
var/ear_protection = 0
|
||||
var/damage_protection = 0
|
||||
var/emp_protection = FALSE
|
||||
var/xeno_disarm_chance = 85
|
||||
|
||||
var/list/force_modules = list()
|
||||
var/allow_rename = TRUE
|
||||
@@ -72,11 +71,10 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
var/list/req_access
|
||||
var/ident = 0
|
||||
//var/list/laws = list()
|
||||
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list())
|
||||
var/viewalerts = 0
|
||||
var/modtype = "Default"
|
||||
var/lower_mod = 0
|
||||
var/datum/effect_system/spark_spread/spark_system//So they can initialize sparks whenever/N
|
||||
var/datum/effect_system/spark_spread/spark_system //So they can initialize sparks whenever/N
|
||||
var/jeton = 0
|
||||
var/low_power_mode = 0 //whether the robot has no charge left.
|
||||
var/weapon_lock = 0
|
||||
@@ -112,7 +110,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
/mob/living/silicon/robot/get_cell()
|
||||
return cell
|
||||
|
||||
/mob/living/silicon/robot/New(loc, syndie = FALSE, unfinished = FALSE, alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
/mob/living/silicon/robot/New(loc, syndie = FALSE, unfinished = FALSE, alien = FALSE, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
@@ -134,13 +132,13 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
radio = new /obj/item/radio/borg(src)
|
||||
common_radio = radio
|
||||
|
||||
init(ai_to_sync_to = ai_to_sync_to)
|
||||
init(alien, connect_to_AI, ai_to_sync_to)
|
||||
|
||||
if(has_camera && !camera)
|
||||
camera = new /obj/machinery/camera(src)
|
||||
camera.c_tag = real_name
|
||||
camera.network = list("SS13","Robots")
|
||||
if(wires.IsCameraCut()) // 5 = BORG CAMERA
|
||||
if(wires.is_cut(WIRE_BORG_CAMERA)) // 5 = BORG CAMERA
|
||||
camera.status = 0
|
||||
|
||||
if(mmi == null)
|
||||
@@ -172,18 +170,20 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
scanner = new(src)
|
||||
scanner.Grant(src)
|
||||
|
||||
/mob/living/silicon/robot/proc/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
/mob/living/silicon/robot/proc/init(alien, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
|
||||
make_laws()
|
||||
additional_law_channels["Binary"] = ":b "
|
||||
if(!connect_to_AI)
|
||||
return
|
||||
var/found_ai = ai_to_sync_to
|
||||
if(!found_ai)
|
||||
found_ai = select_active_ai_with_fewest_borgs()
|
||||
if(found_ai)
|
||||
lawupdate = 1
|
||||
lawupdate = TRUE
|
||||
connect_to_ai(found_ai)
|
||||
else
|
||||
lawupdate = 0
|
||||
lawupdate = FALSE
|
||||
|
||||
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
|
||||
|
||||
@@ -270,6 +270,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO
|
||||
//Improved /N
|
||||
/mob/living/silicon/robot/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
if(mmi && mind)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside.
|
||||
var/turf/T = get_turf(loc)//To hopefully prevent run time errors.
|
||||
if(T) mmi.loc = T
|
||||
@@ -543,6 +544,43 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
src.verbs -= GLOB.robot_verbs_default
|
||||
src.verbs -= silicon_subsystems
|
||||
|
||||
/mob/living/silicon/robot/verb/cmd_robot_alerts()
|
||||
set category = "Robot Commands"
|
||||
set name = "Show Alerts"
|
||||
if(usr.stat == DEAD)
|
||||
to_chat(src, "<span class='userdanger'>Alert: You are dead.</span>")
|
||||
return //won't work if dead
|
||||
robot_alerts()
|
||||
|
||||
/mob/living/silicon/robot/proc/robot_alerts()
|
||||
var/list/dat = list()
|
||||
var/list/list/temp_alarm_list = SSalarm.alarms.Copy()
|
||||
for(var/cat in temp_alarm_list)
|
||||
if(!(cat in alarms_listend_for))
|
||||
continue
|
||||
dat += text("<B>[cat]</B><BR>\n")
|
||||
var/list/list/L = temp_alarm_list[cat].Copy()
|
||||
for(var/alarm in L)
|
||||
var/list/list/alm = L[alarm].Copy()
|
||||
var/list/list/sources = alm[3].Copy()
|
||||
var/area_name = alm[1]
|
||||
for(var/thing in sources)
|
||||
var/atom/A = locateUID(thing)
|
||||
if(A && A.z != z)
|
||||
L -= alarm
|
||||
continue
|
||||
dat += "<NOBR>"
|
||||
dat += text("-- [area_name]")
|
||||
dat += "</NOBR><BR>\n"
|
||||
if(!L.len)
|
||||
dat += "-- All Systems Nominal<BR>\n"
|
||||
dat += "<BR>\n"
|
||||
|
||||
var/datum/browser/alerts = new(usr, "robotalerts", "Current Station Alerts", 400, 410)
|
||||
var/dat_text = dat.Join("")
|
||||
alerts.set_content(dat_text)
|
||||
alerts.open()
|
||||
|
||||
/mob/living/silicon/robot/proc/ionpulse()
|
||||
if(!ionpulse_on)
|
||||
return
|
||||
@@ -604,6 +642,23 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
/mob/living/silicon/robot/InCritical()
|
||||
return low_power_mode
|
||||
|
||||
/mob/living/silicon/robot/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
|
||||
if(!(class in alarms_listend_for))
|
||||
return
|
||||
if(alarmsource.z != z)
|
||||
return
|
||||
if(stat == DEAD)
|
||||
return
|
||||
queueAlarm(text("--- [class] alarm detected in [A.name]!"), class)
|
||||
|
||||
/mob/living/silicon/robot/alarm_cancelled(src, class, area/A, obj/origin, cleared)
|
||||
if(cleared)
|
||||
if(!(class in alarms_listend_for))
|
||||
return
|
||||
if(origin.z != z)
|
||||
return
|
||||
queueAlarm("--- [class] alarm in [A.name] has been cleared.", class, 0)
|
||||
|
||||
/mob/living/silicon/robot/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
@@ -795,7 +850,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
opened = FALSE
|
||||
update_icons()
|
||||
return
|
||||
else if(wiresexposed && wires.IsAllCut())
|
||||
else if(wiresexposed && wires.is_all_cut())
|
||||
//Cell is out, wires are exposed, remove MMI, produce damaged chassis, baleet original mob.
|
||||
if(!mmi)
|
||||
to_chat(user, "[src] has no brain to remove.")
|
||||
@@ -1023,10 +1078,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
src << browse(null, t1)
|
||||
return 1
|
||||
|
||||
if(href_list["showalerts"])
|
||||
subsystem_alarm_monitor()
|
||||
return 1
|
||||
|
||||
if(href_list["mod"])
|
||||
var/obj/item/O = locate(href_list["mod"])
|
||||
if(istype(O) && (O.loc == src))
|
||||
@@ -1041,6 +1092,11 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
activate_module(O)
|
||||
installed_modules()
|
||||
|
||||
//Show alerts window if user clicked on "Show alerts" in chat
|
||||
if(href_list["showalerts"])
|
||||
robot_alerts()
|
||||
return TRUE
|
||||
|
||||
if(href_list["deact"])
|
||||
var/obj/item/O = locate(href_list["deact"])
|
||||
if(activated(O))
|
||||
@@ -1063,7 +1119,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/robot/proc/radio_menu()
|
||||
radio.interact(src)//Just use the radio's Topic() instead of bullshit special-snowflake code
|
||||
radio.interact(src)
|
||||
|
||||
/mob/living/silicon/robot/proc/control_headlamp()
|
||||
if(stat || lamp_recharging || low_power_mode)
|
||||
@@ -1233,7 +1289,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
|
||||
/mob/living/silicon/robot/proc/SetLockdown(var/state = 1)
|
||||
// They stay locked down if their wire is cut.
|
||||
if(wires.LockedCut())
|
||||
if(wires.is_cut(WIRE_BORG_LOCKED))
|
||||
state = 1
|
||||
if(state)
|
||||
throw_alert("locked", /obj/screen/alert/locked)
|
||||
@@ -1343,14 +1399,13 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
eye_protection = 2 // Immunity to flashes and the visual part of flashbangs
|
||||
ear_protection = 1 // Immunity to the audio part of flashbangs
|
||||
damage_protection = 10 // Reduce all incoming damage by this number
|
||||
xeno_disarm_chance = 20
|
||||
allow_rename = FALSE
|
||||
modtype = "Commando"
|
||||
faction = list("nanotrasen")
|
||||
is_emaggable = FALSE
|
||||
default_cell_type = /obj/item/stock_parts/cell/bluespace
|
||||
|
||||
/mob/living/silicon/robot/deathsquad/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
/mob/living/silicon/robot/deathsquad/init(alien = FALSE, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
laws = new /datum/ai_laws/deathsquad
|
||||
module = new /obj/item/robot_module/deathsquad(src)
|
||||
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
|
||||
@@ -1380,7 +1435,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
var/eprefix = "Amber"
|
||||
|
||||
|
||||
/mob/living/silicon/robot/ert/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
/mob/living/silicon/robot/ert/init(alien = FALSE, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
laws = new /datum/ai_laws/ert_override
|
||||
radio = new /obj/item/radio/borg/ert(src)
|
||||
radio.recalculateChannels()
|
||||
@@ -1413,7 +1468,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
damage_protection = 5 // Reduce all incoming damage by this number
|
||||
eprefix = "Gamma"
|
||||
magpulse = 1
|
||||
xeno_disarm_chance = 40
|
||||
|
||||
|
||||
/mob/living/silicon/robot/destroyer
|
||||
@@ -1433,11 +1487,12 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
ear_protection = 1 // Immunity to the audio part of flashbangs
|
||||
emp_protection = TRUE // Immunity to EMP, due to heavy shielding
|
||||
damage_protection = 20 // Reduce all incoming damage by this number. Very high in the case of /destroyer borgs, since it is an admin-only borg.
|
||||
xeno_disarm_chance = 10
|
||||
default_cell_type = /obj/item/stock_parts/cell/bluespace
|
||||
|
||||
/mob/living/silicon/robot/destroyer/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
..()
|
||||
/mob/living/silicon/robot/destroyer/init(alien = FALSE, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null)
|
||||
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
|
||||
additional_law_channels["Binary"] = ":b "
|
||||
laws = new /datum/ai_laws/deathsquad
|
||||
module = new /obj/item/robot_module/destroyer(src)
|
||||
module.add_languages(src)
|
||||
module.add_subsystems_and_actions(src)
|
||||
@@ -1446,6 +1501,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
qdel(radio)
|
||||
radio = new /obj/item/radio/borg/ert/specops(src)
|
||||
radio.recalculateChannels()
|
||||
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
|
||||
|
||||
/mob/living/silicon/robot/destroyer/borg_icons()
|
||||
if(base_icon == "")
|
||||
|
||||
@@ -2,19 +2,17 @@
|
||||
if(M.a_intent == INTENT_DISARM)
|
||||
if(!lying)
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
if(prob(xeno_disarm_chance))
|
||||
Stun(7)
|
||||
step(src, get_dir(M,src))
|
||||
spawn(5)
|
||||
step(src, get_dir(M,src))
|
||||
add_attack_logs(M, src, "Alien pushed over")
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has forced back [src]!</span>",\
|
||||
"<span class='userdanger'>[M] has forced back [src]!</span>")
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(I)
|
||||
uneq_active()
|
||||
visible_message("<span class='danger'>[M] disarmed [src]!</span>", "<span class='userdanger'>[M] has disabled [src]'s active module!</span>")
|
||||
add_attack_logs(M, src, "alien disarmed")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] took a swipe at [src]!</span>",\
|
||||
"<span class='userdanger'>[M] took a swipe at [src]!</span>")
|
||||
Stun(2)
|
||||
step(src, get_dir(M,src))
|
||||
add_attack_logs(M, src, "Alien pushed over")
|
||||
visible_message("<span class='danger'>[M] forces back [src]!</span>", "<span class='userdanger'>[M] forces back [src]!</span>")
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 50, TRUE, -1)
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
/obj/item/robot_module/proc/handle_custom_removal(component_id, mob/living/user, obj/item/W)
|
||||
return FALSE
|
||||
|
||||
/obj/item/robot_module/proc/handle_death(gibbed)
|
||||
/obj/item/robot_module/proc/handle_death(mob/living/silicon/robot/R, gibbed)
|
||||
return
|
||||
|
||||
/obj/item/robot_module/standard
|
||||
@@ -255,7 +255,7 @@
|
||||
|
||||
fix_modules()
|
||||
|
||||
/obj/item/robot_module/engineering/handle_death()
|
||||
/obj/item/robot_module/engineering/handle_death(mob/living/silicon/robot/R, gibbed)
|
||||
var/obj/item/gripper/G = locate(/obj/item/gripper) in modules
|
||||
if(G)
|
||||
G.drop_gripped_item(silent = TRUE)
|
||||
@@ -368,6 +368,11 @@
|
||||
R.add_language("Clownish",1)
|
||||
R.add_language("Neo-Russkiya", 1)
|
||||
|
||||
/obj/item/robot_module/butler/handle_death(mob/living/silicon/robot/R, gibbed)
|
||||
var/obj/item/storage/bag/tray/cyborg/T = locate(/obj/item/storage/bag/tray/cyborg) in modules
|
||||
if(istype(T))
|
||||
T.drop_inventory(R)
|
||||
|
||||
|
||||
/obj/item/robot_module/miner
|
||||
name = "miner robot module"
|
||||
@@ -623,7 +628,7 @@
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/robot_module/drone/handle_death()
|
||||
/obj/item/robot_module/drone/handle_death(mob/living/silicon/robot/R, gibbed)
|
||||
var/obj/item/gripper/G = locate(/obj/item/gripper) in modules
|
||||
if(G)
|
||||
G.drop_gripped_item(silent = TRUE)
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
var/list/stating_laws = list()// Channels laws are currently being stated on
|
||||
var/list/alarms_to_show = list()
|
||||
var/list/alarms_to_clear = list()
|
||||
var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
|
||||
var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
|
||||
var/list/alarms_listend_for = list("Motion", "Fire", "Atmosphere", "Power", "Camera")
|
||||
//var/list/hud_list[10]
|
||||
var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer
|
||||
var/list/alarm_handlers = list() // List of alarm handlers this silicon is registered to
|
||||
var/designation = ""
|
||||
var/obj/item/camera/siliconcam/aiCamera = null //photography
|
||||
//Used in say.dm, allows for pAIs to have different say flavor text, as well as silicons, although the latter is not implemented.
|
||||
@@ -25,9 +27,6 @@
|
||||
|
||||
//var/sensor_mode = 0 //Determines the current HUD.
|
||||
|
||||
var/next_alarm_notice
|
||||
var/list/datum/alarm/queued_alarms = new()
|
||||
|
||||
hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD)
|
||||
|
||||
|
||||
@@ -46,6 +45,8 @@
|
||||
diag_hud_set_health()
|
||||
add_language("Galactic Common")
|
||||
init_subsystems()
|
||||
RegisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM, .proc/alarm_triggered)
|
||||
RegisterSignal(SSalarm, COMSIG_CANCELLED_ALARM, .proc/alarm_cancelled)
|
||||
|
||||
/mob/living/silicon/med_hud_set_health()
|
||||
return //we use a different hud
|
||||
@@ -55,10 +56,93 @@
|
||||
|
||||
/mob/living/silicon/Destroy()
|
||||
GLOB.silicon_mob_list -= src
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.unregister(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/proc/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
|
||||
return
|
||||
|
||||
/mob/living/silicon/proc/alarm_cancelled(src, class, area/A, obj/origin, cleared)
|
||||
return
|
||||
|
||||
/mob/living/silicon/proc/queueAlarm(message, type, incoming = TRUE)
|
||||
var/in_cooldown = (alarms_to_show.len > 0 || alarms_to_clear.len > 0)
|
||||
if(incoming)
|
||||
alarms_to_show += message
|
||||
alarm_types_show[type] += 1
|
||||
else
|
||||
alarms_to_clear += message
|
||||
alarm_types_clear[type] += 1
|
||||
|
||||
if(in_cooldown)
|
||||
return
|
||||
|
||||
addtimer(CALLBACK(src, .proc/show_alarms), 3 SECONDS)
|
||||
|
||||
/mob/living/silicon/proc/show_alarms()
|
||||
if(alarms_to_show.len < 5)
|
||||
for(var/msg in alarms_to_show)
|
||||
to_chat(src, msg)
|
||||
else if(length(alarms_to_show))
|
||||
|
||||
var/list/msg = list("--- ")
|
||||
|
||||
if(alarm_types_show["Burglar"])
|
||||
msg += "BURGLAR: [alarm_types_show["Burglar"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Motion"])
|
||||
msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Fire"])
|
||||
msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Atmosphere"])
|
||||
msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Power"])
|
||||
msg += "POWER: [alarm_types_show["Power"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Camera"])
|
||||
msg += "CAMERA: [alarm_types_show["Camera"]] alarms detected. - "
|
||||
|
||||
msg += "<A href=?src=[UID()];showalerts=1'>\[Show Alerts\]</a>"
|
||||
var/msg_text = msg.Join("")
|
||||
to_chat(src, msg_text)
|
||||
|
||||
if(alarms_to_clear.len < 3)
|
||||
for(var/msg in alarms_to_clear)
|
||||
to_chat(src, msg)
|
||||
|
||||
else if(alarms_to_clear.len)
|
||||
var/list/msg = list("--- ")
|
||||
|
||||
if(alarm_types_clear["Motion"])
|
||||
msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_clear["Fire"])
|
||||
msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_clear["Atmosphere"])
|
||||
msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_clear["Power"])
|
||||
msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_show["Camera"])
|
||||
msg += "CAMERA: [alarm_types_clear["Camera"]] alarms cleared. - "
|
||||
|
||||
msg += "<A href=?src=[UID()];showalerts=1'>\[Show Alerts\]</a>"
|
||||
|
||||
var/msg_text = msg.Join("")
|
||||
to_chat(src, msg_text)
|
||||
|
||||
|
||||
alarms_to_show.Cut()
|
||||
alarms_to_clear.Cut()
|
||||
for(var/key in alarm_types_show)
|
||||
alarm_types_show[key] = 0
|
||||
for(var/key in alarm_types_clear)
|
||||
alarm_types_clear[key] = 0
|
||||
|
||||
/mob/living/silicon/rename_character(oldname, newname)
|
||||
// we actually don't want it changing minds and stuff
|
||||
if(!newname)
|
||||
@@ -283,63 +367,6 @@
|
||||
if("Disable")
|
||||
to_chat(src, "Sensor augmentations disabled.")
|
||||
|
||||
/mob/living/silicon/proc/receive_alarm(var/datum/alarm_handler/alarm_handler, var/datum/alarm/alarm, was_raised)
|
||||
if(!next_alarm_notice)
|
||||
next_alarm_notice = world.time + 10 SECONDS
|
||||
|
||||
var/list/alarms = queued_alarms[alarm_handler]
|
||||
if(was_raised)
|
||||
// Raised alarms are always set
|
||||
alarms[alarm] = 1
|
||||
else
|
||||
// Alarms that were raised but then cleared before the next notice are instead removed
|
||||
if(alarm in alarms)
|
||||
alarms -= alarm
|
||||
// And alarms that have only been cleared thus far are set as such
|
||||
else
|
||||
alarms[alarm] = -1
|
||||
|
||||
/mob/living/silicon/proc/process_queued_alarms()
|
||||
if(next_alarm_notice && (world.time > next_alarm_notice))
|
||||
next_alarm_notice = 0
|
||||
|
||||
var/alarm_raised = 0
|
||||
for(var/datum/alarm_handler/AH in queued_alarms)
|
||||
var/list/alarms = queued_alarms[AH]
|
||||
var/reported = 0
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(alarms[A] == 1)
|
||||
if(!reported)
|
||||
reported = 1
|
||||
to_chat(src, "<span class='warning'>--- [AH.category] Detected ---</span>")
|
||||
raised_alarm(A)
|
||||
|
||||
for(var/datum/alarm_handler/AH in queued_alarms)
|
||||
var/list/alarms = queued_alarms[AH]
|
||||
var/reported = 0
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(alarms[A] == -1)
|
||||
if(!reported)
|
||||
reported = 1
|
||||
to_chat(src, "<span class='notice'>--- [AH.category] Cleared ---</span>")
|
||||
to_chat(src, "\The [A.alarm_name()].")
|
||||
|
||||
if(alarm_raised)
|
||||
to_chat(src, "<A HREF=?src=[UID()];showalerts=1>\[Show Alerts\]</A>")
|
||||
|
||||
for(var/datum/alarm_handler/AH in queued_alarms)
|
||||
var/list/alarms = queued_alarms[AH]
|
||||
alarms.Cut()
|
||||
|
||||
/mob/living/silicon/proc/raised_alarm(var/datum/alarm/A)
|
||||
to_chat(src, "[A.alarm_name()]!")
|
||||
|
||||
/mob/living/silicon/ai/raised_alarm(var/datum/alarm/A)
|
||||
var/cameratext = ""
|
||||
for(var/obj/machinery/camera/C in A.cameras())
|
||||
cameratext += "[(cameratext == "")? "" : "|"]<A HREF=?src=[UID()];switchcamera=\ref[C]>[C.c_tag]</A>"
|
||||
to_chat(src, "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])")
|
||||
|
||||
/mob/living/silicon/adjustToxLoss(var/amount)
|
||||
return STATUS_UPDATE_NONE
|
||||
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
|
||||
/mob/living/silicon/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(..()) //if harm or disarm intent
|
||||
var/damage = rand(10, 20)
|
||||
var/damage = 20
|
||||
if(prob(90))
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", "<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
if(prob(8))
|
||||
flash_eyes(affect_silicon = 1)
|
||||
add_attack_logs(M, src, "Alien attacked")
|
||||
@@ -64,6 +63,6 @@
|
||||
else
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
|
||||
playsound(loc, 'sound/effects/bang.ogg', 10, 1)
|
||||
visible_message("<span class='danger'>[M] punches [src], but doesn't leave a dent.</span>", \
|
||||
"<span class='userdanger'>[M] punches [src], but doesn't leave a dent.!</span>")
|
||||
visible_message("<span class='notice'>[M] punches [src], but doesn't leave a dent.</span>", \
|
||||
"<span class='notice'>[M] punches [src], but doesn't leave a dent.</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
|
||||
/mob/living/silicon
|
||||
var/list/silicon_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/proc/subsystem_law_manager
|
||||
)
|
||||
|
||||
/mob/living/silicon/ai
|
||||
silicon_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/proc/subsystem_atmos_control,
|
||||
/mob/living/silicon/proc/subsystem_crew_monitor,
|
||||
/mob/living/silicon/proc/subsystem_law_manager,
|
||||
@@ -23,7 +21,6 @@
|
||||
|
||||
/mob/living/silicon/robot/drone
|
||||
silicon_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/proc/subsystem_law_manager,
|
||||
/mob/living/silicon/proc/subsystem_power_monitor
|
||||
)
|
||||
@@ -32,30 +29,11 @@
|
||||
register_alarms = 0
|
||||
|
||||
/mob/living/silicon/proc/init_subsystems()
|
||||
alarm_monitor = new(src)
|
||||
atmos_control = new(src)
|
||||
crew_monitor = new(src)
|
||||
law_manager = new(src)
|
||||
power_monitor = new(src)
|
||||
|
||||
if(!register_alarms)
|
||||
return
|
||||
|
||||
var/list/register_to = list(SSalarms.atmosphere_alarm, SSalarms.burglar_alarm, SSalarms.camera_alarm, SSalarms.fire_alarm, SSalarms.motion_alarm, SSalarms.power_alarm)
|
||||
for(var/datum/alarm_handler/AH in register_to)
|
||||
AH.register(src, /mob/living/silicon/proc/receive_alarm)
|
||||
queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order
|
||||
alarm_handlers |= AH
|
||||
|
||||
/********************
|
||||
* Alarm Monitor *
|
||||
********************/
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor()
|
||||
set name = "Alarm Monitor"
|
||||
set category = "Subsystems"
|
||||
|
||||
alarm_monitor.ui_interact(usr, state = GLOB.self_state)
|
||||
|
||||
/********************
|
||||
* Atmos Control *
|
||||
********************/
|
||||
|
||||
@@ -42,13 +42,18 @@
|
||||
|
||||
/mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(..()) //if harm or disarm intent.
|
||||
var/damage = rand(15, 30)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
add_attack_logs(M, src, "Alien attacked")
|
||||
attack_threshold_check(damage)
|
||||
return
|
||||
if(M.a_intent == INTENT_DISARM)
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, TRUE, -1)
|
||||
visible_message("<span class='danger'>[M] [response_disarm] [name]!</span>", "<span class='userdanger'>[M] [response_disarm] you!</span>")
|
||||
add_attack_logs(M, src, "Alien disarmed")
|
||||
else
|
||||
var/damage = rand(15, 30)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
add_attack_logs(M, src, "Alien attacked")
|
||||
attack_threshold_check(damage)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
if(..()) //successful larva bite
|
||||
|
||||
@@ -94,7 +94,6 @@
|
||||
hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_PATH_HUD = HUD_LIST_LIST)//Diagnostic HUD views
|
||||
|
||||
/obj/item/radio/headset/bot
|
||||
subspace_transmission = 1
|
||||
requires_tcomms = FALSE
|
||||
canhear_range = 0
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
RegisterSignal(src, COMSIG_CROSSED_MOVABLE, .proc/human_squish_check)
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
unload(0)
|
||||
QDEL_NULL(wires)
|
||||
QDEL_NULL(cell)
|
||||
@@ -142,7 +143,7 @@
|
||||
if(open)
|
||||
icon_state="mulebot-hatch"
|
||||
else
|
||||
icon_state = "mulebot[!wires.MobAvoid()]"
|
||||
icon_state = "mulebot[wires.is_cut(WIRE_MOB_AVOIDANCE)]"
|
||||
overlays.Cut()
|
||||
if(load && !ismob(load))//buckling handles the mob offsets
|
||||
load.pixel_y = initial(load.pixel_y) + 9
|
||||
@@ -158,9 +159,9 @@
|
||||
qdel(src)
|
||||
if(2)
|
||||
for(var/i = 1; i < 3; i++)
|
||||
wires.RandomCut()
|
||||
wires.cut_random()
|
||||
if(3)
|
||||
wires.RandomCut()
|
||||
wires.cut_random()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj)
|
||||
@@ -169,7 +170,7 @@
|
||||
unload(0)
|
||||
if(prob(25))
|
||||
visible_message("<span class='danger'>Something shorts out inside [src]!</span>")
|
||||
wires.RandomCut()
|
||||
wires.cut_random()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Topic(href, list/href_list)
|
||||
if(..())
|
||||
@@ -318,7 +319,7 @@
|
||||
|
||||
// returns true if the bot has power
|
||||
/mob/living/simple_animal/bot/mulebot/proc/has_power()
|
||||
return !open && cell && cell.charge > 0 && wires.HasPower()
|
||||
return !open && cell && cell.charge > 0 && !wires.is_cut(WIRE_MAIN_POWER1) && !wires.is_cut(WIRE_MAIN_POWER2)
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/buzz(type)
|
||||
switch(type)
|
||||
@@ -362,7 +363,7 @@
|
||||
if(istype(AM,/obj/structure/closet/crate))
|
||||
CRATE = AM
|
||||
else
|
||||
if(wires.LoadCheck())
|
||||
if(!wires.is_cut(WIRE_LOADCHECK))
|
||||
buzz(SIGH)
|
||||
return // if not hacked, only allow crates to be loaded
|
||||
|
||||
@@ -459,8 +460,7 @@
|
||||
on = 0
|
||||
return
|
||||
if(on)
|
||||
var/speed = (wires.Motor1() ? 1 : 0) + (wires.Motor2() ? 2 : 0)
|
||||
// to_chat(world, "speed: [speed]")
|
||||
var/speed = (wires.is_cut(WIRE_MOTOR1) ? 1 : 0) + (wires.is_cut(WIRE_MOTOR2) ? 2 : 0)
|
||||
var/num_steps = 0
|
||||
switch(speed)
|
||||
if(0)
|
||||
@@ -624,7 +624,7 @@
|
||||
// not loaded
|
||||
if(auto_pickup) // find a crate
|
||||
var/atom/movable/AM
|
||||
if(wires.LoadCheck()) // if hacked, load first unanchored thing we find
|
||||
if(wires.is_cut(WIRE_LOADCHECK)) // if hacked, load first unanchored thing we find
|
||||
for(var/atom/movable/A in get_step(loc, loaddir))
|
||||
if(!A.anchored)
|
||||
AM = A
|
||||
@@ -672,7 +672,7 @@
|
||||
|
||||
// called when bot bumps into anything
|
||||
/mob/living/simple_animal/bot/mulebot/Bump(atom/obs)
|
||||
if(!wires.MobAvoid()) // usually just bumps, but if avoidance disabled knock over mobs
|
||||
if(wires.is_cut(WIRE_MOB_AVOIDANCE)) // usually just bumps, but if avoidance disabled knock over mobs
|
||||
var/mob/M = obs
|
||||
if(ismob(M))
|
||||
if(istype(M,/mob/living/silicon/robot))
|
||||
@@ -736,8 +736,8 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/receive_signal(datum/signal/signal)
|
||||
if(!wires.RemoteRX() || ..())
|
||||
return 1
|
||||
if(wires.is_cut(WIRE_REMOTE_RX) || ..())
|
||||
return TRUE
|
||||
|
||||
var/recv = signal.data["command"]
|
||||
|
||||
@@ -772,7 +772,7 @@
|
||||
|
||||
// send a radio signal with multiple data key/values
|
||||
/mob/living/simple_animal/bot/mulebot/post_signal_multiple(var/freq, var/list/keyval)
|
||||
if(!wires.RemoteTX())
|
||||
if(wires.is_cut(WIRE_REMOTE_TX))
|
||||
return
|
||||
|
||||
..()
|
||||
@@ -803,7 +803,7 @@
|
||||
|
||||
//Update navigation data. Called when commanded to deliver, return home, or a route update is needed...
|
||||
/mob/living/simple_animal/bot/mulebot/proc/get_nav()
|
||||
if(!on || !wires.BeaconRX())
|
||||
if(!on || wires.is_cut(WIRE_BEACON_RX))
|
||||
return
|
||||
|
||||
for(var/obj/machinery/navbeacon/NB in GLOB.deliverybeacons)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
faction = list("cult")
|
||||
flying = 1
|
||||
flying = TRUE
|
||||
pressure_resistance = 100
|
||||
universal_speak = 1
|
||||
AIStatus = AI_OFF //normal constructs don't have AI
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
harm_intent_damage = 1
|
||||
friendly = "nudges"
|
||||
density = 0
|
||||
flying = TRUE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
ventcrawler = 2
|
||||
mob_size = MOB_SIZE_TINY
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
var/obj/item/udder/udder = null
|
||||
gender = FEMALE
|
||||
|
||||
/mob/living/simple_animal/cow/Initialize()
|
||||
udder = new()
|
||||
|
||||
@@ -85,8 +85,11 @@
|
||||
get_scooped(M)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/mouse/start_pulling(var/atom/movable/AM)//Prevents mouse from pulling things
|
||||
to_chat(src, "<span class='warning'>You are too small to pull anything.</span>")
|
||||
/mob/living/simple_animal/mouse/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)//Prevents mouse from pulling things
|
||||
if(istype(AM, /obj/item/reagent_containers/food/snacks/cheesewedge))
|
||||
return ..() // Get dem
|
||||
if(show_message)
|
||||
to_chat(src, "<span class='warning'>You are too small to pull anything except cheese.</span>")
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj, oldloc)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
mob_size = MOB_SIZE_TINY
|
||||
flying = TRUE
|
||||
harm_intent_damage = 8
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
|
||||
@@ -241,6 +241,14 @@ Difficulty: Very Hard
|
||||
AT.pixel_y += random_y
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/colossus/float(on) //we don't want this guy to float, messes up his animations
|
||||
if(throwing)
|
||||
return
|
||||
if(on && !floating)
|
||||
floating = TRUE
|
||||
else if(!on && floating)
|
||||
floating = FALSE
|
||||
|
||||
/obj/item/projectile/colossus
|
||||
name ="death bolt"
|
||||
icon_state= "chronobolt"
|
||||
|
||||
@@ -26,21 +26,34 @@
|
||||
flying = 1
|
||||
|
||||
var/carp_color = "carp" //holder for icon set
|
||||
var/list/icon_sets = list("carp", "blue", "yellow", "grape", "rust", "teal", "purple")
|
||||
var/static/list/carp_colors = list(\
|
||||
"lightpurple" = "#c3b9f1", \
|
||||
"lightpink" = "#da77a8", \
|
||||
"green" = "#70ff25", \
|
||||
"grape" = "#df0afb", \
|
||||
"swamp" = "#e5e75a", \
|
||||
"turquoise" = "#04e1ed", \
|
||||
"brown" = "#ca805a", \
|
||||
"teal" = "#20e28e", \
|
||||
"lightblue" = "#4d88cc", \
|
||||
"rusty" = "#dd5f34", \
|
||||
"beige" = "#bbaeaf", \
|
||||
"yellow" = "#f3ca4a", \
|
||||
"blue" = "#09bae1", \
|
||||
"palegreen" = "#7ef099", \
|
||||
)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/carp/Initialize(mapload)
|
||||
. = ..()
|
||||
carp_randomify()
|
||||
update_icons()
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/carp/proc/carp_randomify()
|
||||
if(prob(1))
|
||||
carp_color = pick("white", "black")
|
||||
else
|
||||
carp_color = pick(icon_sets)
|
||||
icon_state = "[carp_color]"
|
||||
icon_living = "[carp_color]"
|
||||
icon_dead = "[carp_color]_dead"
|
||||
/mob/living/simple_animal/hostile/retaliate/carp/proc/carp_randomify(rarechance)
|
||||
// Simplified version of: /mob/living/simple_animal/hostile/carp/proc/carp_randomify(rarechance)
|
||||
var/our_color
|
||||
our_color = pick(carp_colors)
|
||||
add_atom_colour(carp_colors[our_color], FIXED_COLOUR_PRIORITY)
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/carp/koi
|
||||
name = "space koi"
|
||||
@@ -61,13 +74,15 @@
|
||||
maxbodytemp = 1500
|
||||
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
var/randomize_icon = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/carp/koi/Initialize(mapload)
|
||||
. = ..()
|
||||
var/koinum = rand(1, 4)
|
||||
icon_state = "koi[koinum]"
|
||||
icon_living = "koi[koinum]"
|
||||
icon_dead = "koi[koinum]-dead"
|
||||
if(randomize_icon)
|
||||
var/koinum = rand(1, 4)
|
||||
icon_state = "koi[koinum]"
|
||||
icon_living = "koi[koinum]"
|
||||
icon_dead = "koi[koinum]-dead"
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/carp/koi/Process_Spacemove(var/movement_dir)
|
||||
return TRUE
|
||||
@@ -76,3 +91,4 @@
|
||||
icon_state = "koi5"
|
||||
icon_living = "koi5"
|
||||
icon_dead = "koi5-dead"
|
||||
randomize_icon = FALSE
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
flying = TRUE
|
||||
pressure_resistance = 300
|
||||
gold_core_spawnable = NO_SPAWN //too spooky for science
|
||||
faction = list("undead") // did I mention ghost
|
||||
|
||||
@@ -362,7 +362,7 @@
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
mob_size = MOB_SIZE_TINY
|
||||
flying = 1
|
||||
flying = TRUE
|
||||
bubble_icon = "syndibot"
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
del_on_death = 1
|
||||
|
||||
@@ -51,6 +51,10 @@
|
||||
if(!(eggtype in eggtypes))
|
||||
to_chat(src, "<span class='danger'>Unrecognized egg type.</span>")
|
||||
return 0
|
||||
if(fed < feedings_to_lay)
|
||||
// We have to check this again after the popup, to account for people spam-clicking the button, then doing all the popups at once.
|
||||
to_chat(src, "<span class='warning'>You must wrap more humanoid prey before you can do this!</span>")
|
||||
return
|
||||
visible_message("<span class='notice'>[src] lays a cluster of eggs.</span>")
|
||||
if(eggtype == TS_DESC_RED)
|
||||
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 1)
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/purple/Life(seconds, times_fired)
|
||||
. = ..()
|
||||
if(.) // if mob is NOT dead
|
||||
if(stat != DEAD) // Can't use if(.) for this due to the fact it can sometimes return FALSE even when mob is alive.
|
||||
if(!degenerate && spider_myqueen)
|
||||
if(dcheck_counter >= 10)
|
||||
dcheck_counter = 0
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/queen/Life(seconds, times_fired)
|
||||
. = ..()
|
||||
if(.) // if mob is NOT dead
|
||||
if(stat != DEAD) // Can't use if(.) for this due to the fact it can sometimes return FALSE even when mob is alive.
|
||||
if(ckey && canlay < 12 && hasnested) // max 12 eggs worth stored at any one time, realistically that's tons.
|
||||
if(world.time > (spider_lastspawn + spider_spawnfrequency))
|
||||
if(eggslaid >= 20)
|
||||
@@ -287,6 +287,10 @@
|
||||
if(eggtype == null || numlings == null)
|
||||
to_chat(src, "<span class='danger'>Cancelled.</span>")
|
||||
return
|
||||
if(canlay < numlings)
|
||||
// We have to check this again after the popups, to account for people spam-clicking the button, then doing all the popups at once.
|
||||
to_chat(src, "<span class='warning'>Too soon to do this again!</span>")
|
||||
return
|
||||
canlay -= numlings
|
||||
eggslaid += numlings
|
||||
if(eggtype == TS_DESC_RED)
|
||||
|
||||
@@ -298,7 +298,7 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/Life(seconds, times_fired)
|
||||
. = ..()
|
||||
if(!.) // if mob is dead
|
||||
if(stat == DEAD) // Can't use if(.) for this due to the fact it can sometimes return FALSE even when mob is alive.
|
||||
if(prob(2))
|
||||
// 2% chance every cycle to decompose
|
||||
visible_message("<span class='notice'>\The dead body of the [src] decomposes!</span>")
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
|
||||
//Parrots are kleptomaniacs. This variable ... stores the item a parrot is holding.
|
||||
var/obj/item/held_item = null
|
||||
flying = TRUE
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
|
||||
|
||||
@@ -710,7 +711,7 @@
|
||||
ears.talk_into(src, message_pieces, message_mode, verb)
|
||||
used_radios += ears
|
||||
|
||||
/mob/living/simple_animal/parrot/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency)
|
||||
/mob/living/simple_animal/parrot/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency, use_voice = TRUE)
|
||||
if(speaker != src && prob(50))
|
||||
parrot_hear(html_decode(multilingual_to_message(message_pieces)))
|
||||
..()
|
||||
|
||||
@@ -32,8 +32,9 @@
|
||||
animate_ghostly_presence(src, -1, 20, 1) // Restart the floating animation after the attack animation, as it will be cancelled.
|
||||
|
||||
|
||||
/mob/living/simple_animal/possessed_object/start_pulling(var/atom/movable/AM) // Silly motherfuckers think they can pull things.
|
||||
to_chat(src, "<span class='warning'>You are unable to pull [AM]!</span>")
|
||||
/mob/living/simple_animal/possessed_object/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE) // Silly motherfuckers think they can pull things.
|
||||
if(show_message)
|
||||
to_chat(src, "<span class='warning'>You are unable to pull [AM]!</span>")
|
||||
|
||||
|
||||
/mob/living/simple_animal/possessed_object/ghost() // Ghosting will return the object to normal, and will not disqualify the ghoster from various mid-round antag positions.
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
status_flags = 0
|
||||
faction = list("cult")
|
||||
status_flags = CANPUSH
|
||||
flying = TRUE
|
||||
loot = list(/obj/item/reagent_containers/food/snacks/ectoplasm)
|
||||
del_on_death = 1
|
||||
deathmessage = "lets out a contented sigh as their form unwinds."
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
return verb
|
||||
|
||||
/mob/living/simple_animal/slime/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency)
|
||||
/mob/living/simple_animal/slime/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency, use_voice = TRUE)
|
||||
if(speaker != src && !stat)
|
||||
if(speaker in Friends)
|
||||
speech_buffer = list()
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
/mob/living/simple_animal/slime/unEquip(obj/item/I, force)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/slime/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
|
||||
/mob/living/simple_animal/slime/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/slime/attack_ui(slot)
|
||||
|
||||
@@ -141,18 +141,6 @@
|
||||
if(updating && val_change)
|
||||
update_canmove()
|
||||
|
||||
/mob/living/proc/StartFlying()
|
||||
var/val_change = !flying
|
||||
flying = TRUE
|
||||
if(val_change)
|
||||
update_animations()
|
||||
|
||||
/mob/living/proc/StopFlying()
|
||||
var/val_change = !!flying
|
||||
flying = FALSE
|
||||
if(val_change)
|
||||
update_animations()
|
||||
|
||||
|
||||
// SCALAR STATUS EFFECTS
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
/mob/Login()
|
||||
GLOB.player_list |= src
|
||||
last_known_ckey = ckey
|
||||
update_Login_details()
|
||||
world.update_status()
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
for(var/datum/alternate_appearance/AA in viewing_alternate_appearances)
|
||||
AA.viewers -= src
|
||||
viewing_alternate_appearances = null
|
||||
logs.Cut()
|
||||
LAssailant = null
|
||||
return ..()
|
||||
|
||||
@@ -578,6 +577,8 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
changeNext_move(CLICK_CD_POINT)
|
||||
var/obj/P = new /obj/effect/temp_visual/point(tile)
|
||||
P.invisibility = invisibility
|
||||
P.pixel_x = A.pixel_x
|
||||
P.pixel_y = A.pixel_y
|
||||
return 1
|
||||
|
||||
/mob/proc/ret_grab(obj/effect/list_container/mobl/L as obj, flag)
|
||||
@@ -1238,10 +1239,13 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
create_log_in_list(debug_log, text, collapse, world.timeofday)
|
||||
|
||||
/mob/proc/create_log(log_type, what, target = null, turf/where = get_turf(src))
|
||||
LAZYINITLIST(logs[log_type])
|
||||
var/list/log_list = logs[log_type]
|
||||
if(!ckey)
|
||||
return
|
||||
var/real_ckey = ckey
|
||||
if(ckey[1] == "@") // Admin aghosting will do this
|
||||
real_ckey = copytext(ckey, 2)
|
||||
var/datum/log_record/record = new(log_type, src, what, target, where, world.time)
|
||||
log_list.Add(record)
|
||||
GLOB.logging.add_log(real_ckey, record)
|
||||
|
||||
/proc/create_log_in_list(list/target, text, collapse = TRUE, last_log)//forgive me code gods for this shitcode proc
|
||||
//this proc enables lovely stuff like an attack log that looks like this: "[18:20:29-18:20:45]21x John Smith attacked Andrew Jackson with a crowbar."
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
var/list/attack_log_old = list( )
|
||||
var/list/debug_log = null
|
||||
|
||||
var/list/logs = list() // Logs for each log type defined in __DEFINES/logs.dm
|
||||
var/last_known_ckey = null // Used in logging
|
||||
|
||||
var/last_log = 0
|
||||
var/obj/machinery/machine = null
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
var/question = "Do you want to play as [M.real_name ? M.real_name : M.name][M.job ? " ([M.job])" : ""]"
|
||||
if(alert("Do you want to show the antag status?","Show antag status","Yes","No") == "Yes")
|
||||
question += ", [M.mind?.special_role ? M.mind?.special_role : "No special role"]"
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("[question]?", poll_time = 100, min_hours = minhours)
|
||||
var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("[question]?", poll_time = 10 SECONDS, min_hours = minhours, source = M)
|
||||
var/mob/dead/observer/theghost = null
|
||||
|
||||
if(LAZYLEN(candidates))
|
||||
|
||||
@@ -369,8 +369,9 @@
|
||||
step(pulling, get_dir(pulling.loc, A))
|
||||
return
|
||||
|
||||
/mob/proc/update_gravity()
|
||||
/mob/proc/update_gravity(has_gravity)
|
||||
return
|
||||
|
||||
/client/proc/check_has_body_select()
|
||||
return mob && mob.hud_used && mob.hud_used.zone_select && istype(mob.hud_used.zone_select, /obj/screen/zone_sel)
|
||||
|
||||
|
||||
+17
-7
@@ -44,17 +44,27 @@
|
||||
usr.emote(message)
|
||||
|
||||
|
||||
/mob/proc/say_dead(var/message)
|
||||
if(!(client && client.holder))
|
||||
if(!config.dsay_allowed)
|
||||
to_chat(src, "<span class='danger'>Deadchat is globally muted.</span>")
|
||||
/mob/proc/say_dead(message)
|
||||
if(client)
|
||||
if(!client.holder)
|
||||
if(!config.dsay_allowed)
|
||||
to_chat(src, "<span class='danger'>Deadchat is globally muted.</span>")
|
||||
return
|
||||
|
||||
if(client.prefs.muted & MUTE_DEADCHAT)
|
||||
to_chat(src, "<span class='warning'>You cannot talk in deadchat (muted).</span>")
|
||||
return
|
||||
|
||||
if(client && !(client.prefs.toggles & CHAT_DEAD))
|
||||
to_chat(usr, "<span class='danger'>You have deadchat muted.</span>")
|
||||
return
|
||||
if(!(client.prefs.toggles & CHAT_DEAD))
|
||||
to_chat(src, "<span class='danger'>You have deadchat muted.</span>")
|
||||
return
|
||||
|
||||
if(client.handle_spam_prevention(message, MUTE_DEADCHAT))
|
||||
return
|
||||
|
||||
say_dead_direct("[pick("complains", "moans", "whines", "laments", "blubbers", "salts")], <span class='message'>\"[message]\"</span>", src)
|
||||
create_log(DEADCHAT_LOG, message)
|
||||
log_ghostsay(message, src)
|
||||
|
||||
/mob/proc/say_understands(var/mob/other, var/datum/language/speaking = null)
|
||||
if(stat == DEAD)
|
||||
|
||||
@@ -44,26 +44,37 @@
|
||||
|
||||
|
||||
|
||||
//human -> robot
|
||||
/mob/living/carbon/human/proc/Robotize()
|
||||
/**
|
||||
For transforming humans into robots (cyborgs).
|
||||
|
||||
Arguments:
|
||||
* cell_type: A type path of the cell the new borg should receive.
|
||||
* connect_to_default_AI: TRUE if you want /robot/New() to handle connecting the borg to the AI with the least borgs.
|
||||
* AI: A reference to the AI we want to connect to.
|
||||
*/
|
||||
/mob/living/carbon/human/proc/Robotize(cell_type = null, connect_to_default_AI = TRUE, mob/living/silicon/ai/AI = null)
|
||||
if(notransform)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
unEquip(W)
|
||||
regenerate_icons()
|
||||
|
||||
notransform = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
for(var/t in bodyparts)
|
||||
qdel(t)
|
||||
for(var/i in internal_organs)
|
||||
qdel(i)
|
||||
|
||||
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot( loc )
|
||||
// Creating a new borg here will connect them to a default AI and notify that AI, if `connect_to_default_AI` is TRUE.
|
||||
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(loc, connect_to_AI = connect_to_default_AI)
|
||||
|
||||
// cyborgs produced by Robotize get an automatic power cell
|
||||
O.cell = new /obj/item/stock_parts/cell/high(O)
|
||||
// If `AI` is passed in, we want to connect to that AI specifically.
|
||||
if(AI)
|
||||
O.lawupdate = TRUE
|
||||
O.connect_to_ai(AI)
|
||||
|
||||
if(!cell_type)
|
||||
O.cell = new /obj/item/stock_parts/cell/high(O)
|
||||
else
|
||||
O.cell = new cell_type(O)
|
||||
|
||||
O.gender = gender
|
||||
O.invisibility = 0
|
||||
@@ -77,9 +88,8 @@
|
||||
else
|
||||
O.key = key
|
||||
|
||||
O.loc = loc
|
||||
O.forceMove(loc)
|
||||
O.job = "Cyborg"
|
||||
O.notify_ai(1)
|
||||
|
||||
if(O.mind && O.mind.assigned_role == "Cyborg")
|
||||
if(O.mind.role_alt_title == "Robot")
|
||||
|
||||
@@ -55,12 +55,6 @@
|
||||
|
||||
// Procs that update other things about the mob
|
||||
|
||||
// Does various animations - Jitter, Flying, Spinning
|
||||
/mob/proc/update_animations()
|
||||
if(flying)
|
||||
animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING)
|
||||
animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING)
|
||||
|
||||
/mob/proc/update_stat()
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user