mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 07:33:34 +01:00
Merge https://github.com/ParadiseSS13/Paradise into Magic-With-Style
This commit is contained in:
@@ -263,7 +263,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
..()
|
||||
statpanel("Status")
|
||||
if(client.statpanel == "Status")
|
||||
show_stat_station_time()
|
||||
show_stat_emergency_shuttle_eta()
|
||||
stat(null, "Respawnability: [(src in GLOB.respawnable_list) ? "Yes" : "No"]")
|
||||
|
||||
@@ -402,10 +401,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(usr, "Not when you're not dead!")
|
||||
return
|
||||
|
||||
var/area/A = input("Area to jump to", "BOOYEA") as null|anything in ghostteleportlocs
|
||||
var/area/thearea = ghostteleportlocs[A]
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Area to jump to: ", ghostteleportlocs)
|
||||
A.on_close(CALLBACK(src, .proc/teleport))
|
||||
|
||||
if(!thearea)
|
||||
/mob/dead/observer/proc/teleport(area/thearea)
|
||||
if(!thearea || !isobserver(usr))
|
||||
return
|
||||
|
||||
var/list/L = list()
|
||||
@@ -416,7 +416,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(usr, "<span class='warning'>No area available.</span>")
|
||||
return
|
||||
|
||||
usr.forceMove(pick(L))
|
||||
forceMove(pick(L))
|
||||
following = null
|
||||
|
||||
/mob/dead/observer/verb/follow()
|
||||
@@ -425,13 +425,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set desc = "Follow and orbit a mob."
|
||||
|
||||
var/list/mobs = getpois(skip_mindless=1)
|
||||
var/input = input("Please, select a mob!", "Haunt", null, null) as null|anything in mobs
|
||||
var/mob/target = mobs[input]
|
||||
ManualFollow(target)
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Please, select a mob: ", mobs)
|
||||
A.on_close(CALLBACK(src, .proc/ManualFollow))
|
||||
|
||||
// This is the ghost's follow verb with an argument
|
||||
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
|
||||
if(!target)
|
||||
if(!target || !isobserver(usr))
|
||||
return
|
||||
|
||||
if(!get_turf(target))
|
||||
@@ -499,25 +498,21 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Jump to Mob"
|
||||
set desc = "Teleport to a mob"
|
||||
|
||||
if(isobserver(usr)) //Make sure they're an observer!
|
||||
var/list/dest = list() //List of possible destinations (mobs)
|
||||
var/target = null //Chosen target.
|
||||
if(isobserver(usr)) //Make sure they're an observer!
|
||||
var/list/dest = getpois(mobs_only=1) //Fill list, prompt user with list
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Enter a mob name: ", dest)
|
||||
A.on_close(CALLBACK(src, .proc/jump_to_mob))
|
||||
|
||||
dest += getpois(mobs_only=1) //Fill list, prompt user with list
|
||||
target = input("Please, select a mob!", "Jump to Mob", null, null) as null|anything in dest
|
||||
|
||||
if(!target) //Make sure we actually have a target
|
||||
return
|
||||
else
|
||||
var/mob/M = dest[target] //Destination mob
|
||||
var/mob/A = src //Source mob
|
||||
var/turf/T = get_turf(M) //Turf of the destination mob
|
||||
|
||||
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
|
||||
A.forceMove(T)
|
||||
else
|
||||
to_chat(A, "This mob is not located in the game world.")
|
||||
/mob/dead/observer/proc/jump_to_mob(mob/M)
|
||||
if(!M || !isobserver(usr))
|
||||
return
|
||||
var/mob/A = src //Source mob
|
||||
var/turf/T = get_turf(M) //Turf of the destination mob
|
||||
|
||||
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
|
||||
A.forceMove(T)
|
||||
return
|
||||
to_chat(A, "This mob is not located in the game world.")
|
||||
|
||||
/* Now a spell. See spells.dm
|
||||
/mob/dead/observer/verb/boo()
|
||||
|
||||
@@ -58,19 +58,20 @@
|
||||
if(message)
|
||||
log_emote(message, src)
|
||||
|
||||
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
|
||||
// Maybe some people are okay with that.
|
||||
|
||||
// Hearing gasp and such every five seconds is not good emotes were not global for a reason.
|
||||
// Maybe some people are okay with that.
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
if(istype(M, /mob/new_player))
|
||||
continue
|
||||
if(findtext(message," snores.")) //Because we have so many sleeping people.
|
||||
break
|
||||
if(M.stat == DEAD && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(findtext(message, " snores.")) //Because we have so many sleeping people.
|
||||
break
|
||||
|
||||
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
// Type 1 (Visual) emotes are sent to anyone in view of the item
|
||||
if(m_type & EMOTE_VISUAL)
|
||||
|
||||
@@ -63,10 +63,10 @@
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = environment ? environment.return_pressure() : 0
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(pressure < ONE_ATMOSPHERE * 0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
|
||||
italics = 1
|
||||
italics = TRUE
|
||||
sound_vol *= 0.5
|
||||
|
||||
if(sleeping || stat == UNCONSCIOUS)
|
||||
@@ -87,8 +87,6 @@
|
||||
|
||||
var/track = null
|
||||
if(isobserver(src))
|
||||
if(italics && client.prefs.toggles & CHAT_GHOSTRADIO)
|
||||
return
|
||||
if(speaker_name != speaker.real_name && speaker.real_name)
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
track = "([ghost_follow_link(speaker, ghost=src)]) "
|
||||
|
||||
@@ -6,6 +6,14 @@
|
||||
if(hand) return l_hand
|
||||
else return r_hand
|
||||
|
||||
/mob/verb/quick_equip()
|
||||
set name = "quick-equip"
|
||||
set hidden = 1
|
||||
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(I)
|
||||
I.equip_to_best_slot(src)
|
||||
|
||||
/mob/proc/is_in_active_hand(obj/item/I)
|
||||
var/obj/item/item_to_test = get_active_hand()
|
||||
|
||||
@@ -254,3 +262,4 @@
|
||||
if(slot_r_hand)
|
||||
return r_hand
|
||||
return null
|
||||
|
||||
|
||||
@@ -455,6 +455,7 @@
|
||||
colour = "alien"
|
||||
key = "y"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/wryn/check_special_condition(mob/other)
|
||||
var/mob/living/carbon/M = other
|
||||
@@ -485,7 +486,7 @@
|
||||
colour = "alien"
|
||||
key = "a"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/terrorspider
|
||||
name = "Spider Hivemind"
|
||||
@@ -496,7 +497,7 @@
|
||||
colour = "terrorspider"
|
||||
key = "ts"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/ling
|
||||
name = "Changeling"
|
||||
@@ -505,10 +506,11 @@
|
||||
colour = "changeling"
|
||||
key = "g"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/ling/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
if(speaker.mind && speaker.mind.changeling)
|
||||
..(speaker,message,speaker.mind.changeling.changelingID)
|
||||
..(speaker, message, speaker.mind.changeling.changelingID)
|
||||
else if(speaker.mind && speaker.mind.linglink)
|
||||
..()
|
||||
else
|
||||
@@ -521,6 +523,7 @@
|
||||
colour = "shadowling"
|
||||
key = "8"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/shadowling/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
if(speaker.mind && speaker.mind.special_role == SPECIAL_ROLE_SHADOWLING)
|
||||
@@ -539,6 +542,7 @@
|
||||
colour = "abductor"
|
||||
key = "zw" //doesn't matter, this is their default and only language
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/abductor/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
..(speaker,message,speaker.real_name)
|
||||
@@ -567,6 +571,7 @@
|
||||
colour = "alien"
|
||||
key = "bo"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/corticalborer/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
var/mob/living/simple_animal/borer/B
|
||||
@@ -590,7 +595,7 @@
|
||||
exclaim_verb = "declares"
|
||||
key = "b"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
var/drone_only
|
||||
|
||||
/datum/language/binary/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
@@ -636,8 +641,8 @@
|
||||
colour = "say_quote"
|
||||
key = "d"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
drone_only = 1
|
||||
follow = 1
|
||||
drone_only = TRUE
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/drone
|
||||
name = "Drone"
|
||||
@@ -647,7 +652,7 @@
|
||||
exclaim_verb = "declares"
|
||||
key = "]"
|
||||
flags = RESTRICTED
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
syllables = list ("beep", "boop")
|
||||
|
||||
/datum/language/swarmer
|
||||
@@ -659,7 +664,7 @@
|
||||
colour = "say_quote"
|
||||
key = "z"//Zwarmer...Or Zerg!
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
|
||||
// Language handling.
|
||||
/mob/proc/add_language(language)
|
||||
|
||||
@@ -73,7 +73,11 @@
|
||||
stat = CONSCIOUS
|
||||
return
|
||||
health = maxHealth - getOxyLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
|
||||
|
||||
update_stat("updatehealth([reason])")
|
||||
med_hud_set_health()
|
||||
med_hud_set_status()
|
||||
handle_hud_icons_health()
|
||||
|
||||
/mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
. = -1 //hunters are sanic
|
||||
. += ..() //but they still need to slow down on stun
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/handle_regular_hud_updates()
|
||||
/mob/living/carbon/alien/humanoid/hunter/handle_hud_icons_health()
|
||||
..() //-Yvarov
|
||||
|
||||
if(healths)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/handle_regular_hud_updates()
|
||||
/mob/living/carbon/alien/humanoid/sentinel/handle_hud_icons_health()
|
||||
..() //-Yvarov
|
||||
|
||||
if(healths)
|
||||
|
||||
@@ -48,29 +48,26 @@
|
||||
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/empress
|
||||
/mob/living/carbon/alien/humanoid/empress/handle_hud_icons_health()
|
||||
..() //-Yvarov
|
||||
|
||||
handle_regular_hud_updates()
|
||||
|
||||
..() //-Yvarov
|
||||
|
||||
if(src.healths)
|
||||
if(src.stat != 2)
|
||||
switch(health)
|
||||
if(250 to INFINITY)
|
||||
src.healths.icon_state = "health0"
|
||||
if(175 to 250)
|
||||
src.healths.icon_state = "health1"
|
||||
if(100 to 175)
|
||||
src.healths.icon_state = "health2"
|
||||
if(50 to 100)
|
||||
src.healths.icon_state = "health3"
|
||||
if(0 to 50)
|
||||
src.healths.icon_state = "health4"
|
||||
else
|
||||
src.healths.icon_state = "health5"
|
||||
else
|
||||
src.healths.icon_state = "health6"
|
||||
if(healths)
|
||||
if(stat != 2)
|
||||
switch(health)
|
||||
if(250 to INFINITY)
|
||||
healths.icon_state = "health0"
|
||||
if(175 to 250)
|
||||
healths.icon_state = "health1"
|
||||
if(100 to 175)
|
||||
healths.icon_state = "health2"
|
||||
if(50 to 100)
|
||||
healths.icon_state = "health3"
|
||||
if(0 to 50)
|
||||
healths.icon_state = "health4"
|
||||
else
|
||||
healths.icon_state = "health5"
|
||||
else
|
||||
healths.icon_state = "health6"
|
||||
|
||||
/mob/living/carbon/alien/humanoid/empress/verb/lay_egg()
|
||||
set name = "Lay Egg (250)"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
. = ..()
|
||||
. += 3
|
||||
|
||||
/mob/living/carbon/alien/humanoid/queen/handle_regular_hud_updates()
|
||||
/mob/living/carbon/alien/humanoid/queen/handle_hud_icons_health()
|
||||
..() //-Yvarov
|
||||
|
||||
if(healths)
|
||||
|
||||
@@ -72,7 +72,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
/obj/item/clothing/mask/facehugger/equipped(mob/M)
|
||||
Attach(M)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
|
||||
/obj/item/clothing/mask/facehugger/Crossed(atom/target, oldloc)
|
||||
HasProximity(target)
|
||||
return
|
||||
|
||||
|
||||
@@ -95,7 +95,6 @@ I'm using this for Stat to give it a more nifty interface to work with
|
||||
..()
|
||||
if(has_synthetic_assistance())
|
||||
statpanel("Status")
|
||||
show_stat_station_time()
|
||||
show_stat_emergency_shuttle_eta()
|
||||
|
||||
if(client.statpanel == "Status")
|
||||
|
||||
@@ -216,56 +216,7 @@
|
||||
add_attack_logs(M, src, "Shaked", ATKLOG_ALL)
|
||||
if(health >= HEALTH_THRESHOLD_CRIT)
|
||||
if(src == M && ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
visible_message( \
|
||||
text("<span class='notice'>[src] examines [].</span>",gender==MALE?"himself":"herself"), \
|
||||
"<span class='notice'>You check yourself for injuries.</span>" \
|
||||
)
|
||||
|
||||
var/list/missing = list("head", "chest", "groin", "l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")
|
||||
for(var/X in H.bodyparts)
|
||||
var/obj/item/organ/external/LB = X
|
||||
missing -= LB.limb_name
|
||||
var/status = ""
|
||||
var/brutedamage = LB.brute_dam
|
||||
var/burndamage = LB.burn_dam
|
||||
|
||||
if(brutedamage > 0)
|
||||
status = "bruised"
|
||||
if(brutedamage > 20)
|
||||
status = "battered"
|
||||
if(brutedamage > 40)
|
||||
status = "mangled"
|
||||
if(brutedamage > 0 && burndamage > 0)
|
||||
status += " and "
|
||||
if(burndamage > 40)
|
||||
status += "peeling away"
|
||||
|
||||
else if(burndamage > 10)
|
||||
status += "blistered"
|
||||
else if(burndamage > 0)
|
||||
status += "numb"
|
||||
if(LB.status & ORGAN_MUTATED)
|
||||
status = "weirdly shapen."
|
||||
if(status == "")
|
||||
status = "OK"
|
||||
to_chat(src, "\t <span class='[status == "OK" ? "notice" : "warning"]'>Your [LB.name] is [status].</span>")
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
to_chat(src, "\t <a href='byond://?src=[UID()];embedded_object=[I.UID()];embedded_limb=[LB.UID()]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
|
||||
|
||||
for(var/t in missing)
|
||||
to_chat(src, "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>")
|
||||
|
||||
if(H.bleed_rate)
|
||||
to_chat(src, "<span class='danger'>You are bleeding!</span>")
|
||||
if(staminaloss)
|
||||
if(staminaloss > 30)
|
||||
to_chat(src, "<span class='info'>You're completely exhausted.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='info'>You feel fatigued.</span>")
|
||||
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
|
||||
H.play_xylophone()
|
||||
check_self_for_injuries()
|
||||
else
|
||||
if(player_logged)
|
||||
M.visible_message("<span class='notice'>[M] shakes [src], but [p_they()] [p_do()] not respond. Probably suffering from SSD.", \
|
||||
@@ -308,6 +259,58 @@
|
||||
else if(H.w_uniform)
|
||||
H.w_uniform.add_fingerprint(M)
|
||||
|
||||
/mob/living/carbon/proc/check_self_for_injuries()
|
||||
var/mob/living/carbon/human/H = src
|
||||
visible_message( \
|
||||
text("<span class='notice'>[src] examines [].</span>",gender==MALE?"himself":"herself"), \
|
||||
"<span class='notice'>You check yourself for injuries.</span>" \
|
||||
)
|
||||
|
||||
var/list/missing = list("head", "chest", "groin", "l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")
|
||||
for(var/X in H.bodyparts)
|
||||
var/obj/item/organ/external/LB = X
|
||||
missing -= LB.limb_name
|
||||
var/status = ""
|
||||
var/brutedamage = LB.brute_dam
|
||||
var/burndamage = LB.burn_dam
|
||||
|
||||
if(brutedamage > 0)
|
||||
status = "bruised"
|
||||
if(brutedamage > 20)
|
||||
status = "battered"
|
||||
if(brutedamage > 40)
|
||||
status = "mangled"
|
||||
if(brutedamage > 0 && burndamage > 0)
|
||||
status += " and "
|
||||
if(burndamage > 40)
|
||||
status += "peeling away"
|
||||
|
||||
else if(burndamage > 10)
|
||||
status += "blistered"
|
||||
else if(burndamage > 0)
|
||||
status += "numb"
|
||||
if(LB.status & ORGAN_MUTATED)
|
||||
status = "weirdly shapen."
|
||||
if(status == "")
|
||||
status = "OK"
|
||||
to_chat(src, "\t <span class='[status == "OK" ? "notice" : "warning"]'>Your [LB.name] is [status].</span>")
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
to_chat(src, "\t <a href='byond://?src=[UID()];embedded_object=[I.UID()];embedded_limb=[LB.UID()]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
|
||||
|
||||
for(var/t in missing)
|
||||
to_chat(src, "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>")
|
||||
|
||||
if(H.bleed_rate)
|
||||
to_chat(src, "<span class='danger'>You are bleeding!</span>")
|
||||
if(staminaloss)
|
||||
if(staminaloss > 30)
|
||||
to_chat(src, "<span class='info'>You're completely exhausted.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='info'>You feel fatigued.</span>")
|
||||
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
|
||||
H.play_xylophone()
|
||||
|
||||
/mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
|
||||
. = ..()
|
||||
var/damage = intensity - check_eye_prot()
|
||||
@@ -972,6 +975,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
|
||||
to_chat(src, "<span class='notice'>You [slipVerb]ped on [description]!</span>")
|
||||
playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
|
||||
// Something something don't run with scissors
|
||||
moving_diagonally = 0 //If this was part of diagonal move slipping will stop it.
|
||||
Stun(stun)
|
||||
Weaken(weaken)
|
||||
return 1
|
||||
|
||||
@@ -671,9 +671,9 @@
|
||||
if(!restrained())
|
||||
var/t1 = round(text2num(param))
|
||||
if(isnum(t1))
|
||||
if(t1 <= 5 && (!r_hand || !l_hand))
|
||||
if(t1 <= 5 && t1 >= 1 && (!r_hand || !l_hand))
|
||||
message = "<B>[src]</B> raises [t1] finger\s."
|
||||
else if(t1 <= 10 && (!r_hand && !l_hand))
|
||||
else if(t1 <= 10 && t1 >= 1 && (!r_hand && !l_hand))
|
||||
message = "<B>[src]</B> raises [t1] finger\s."
|
||||
m_type = 1
|
||||
|
||||
@@ -946,9 +946,13 @@
|
||||
// Maybe some people are okay with that.
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
if(!M.client || istype(M, /mob/new_player))
|
||||
continue //skip monkeys, leavers and new players
|
||||
if(M.stat == DEAD && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
if(!M.client)
|
||||
continue
|
||||
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
switch(m_type)
|
||||
|
||||
@@ -338,18 +338,9 @@
|
||||
msg += "[p_they(TRUE)] [p_are()] mostly dessicated now, with only bones remaining of what used to be a person.\n"
|
||||
|
||||
if(hasHUD(user,"security"))
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/criminal = "None"
|
||||
|
||||
if(wear_id)
|
||||
var/obj/item/card/id/I = wear_id.GetID()
|
||||
if(I)
|
||||
perpname = I.registered_name
|
||||
else
|
||||
perpname = name
|
||||
else
|
||||
perpname = name
|
||||
|
||||
if(perpname)
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
@@ -361,18 +352,9 @@
|
||||
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=[UID()];secrecord=`'>\[View\]</a> <a href='?src=[UID()];secrecordadd=`'>\[Add comment\]</a>\n"
|
||||
|
||||
if(hasHUD(user,"medical"))
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/medical = "None"
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.general)
|
||||
|
||||
@@ -162,8 +162,6 @@
|
||||
stat(null, "Intent: [a_intent]")
|
||||
stat(null, "Move Mode: [m_intent]")
|
||||
|
||||
show_stat_station_time()
|
||||
|
||||
show_stat_emergency_shuttle_eta()
|
||||
|
||||
if(client.statpanel == "Status")
|
||||
@@ -455,7 +453,7 @@
|
||||
popup.open()
|
||||
|
||||
|
||||
/mob/living/carbon/human/Crossed(atom/movable/AM)
|
||||
/mob/living/carbon/human/Crossed(atom/movable/AM, oldloc)
|
||||
var/mob/living/simple_animal/bot/mulebot/MB = AM
|
||||
if(istype(MB))
|
||||
MB.RunOver(src)
|
||||
@@ -713,17 +711,9 @@
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/found_record = 0
|
||||
var/perpname = "wot"
|
||||
if(wear_id)
|
||||
var/obj/item/card/id/I = wear_id.GetID()
|
||||
if(I)
|
||||
perpname = I.registered_name
|
||||
else
|
||||
perpname = name
|
||||
else
|
||||
perpname = name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
|
||||
if(perpname)
|
||||
if(perpname != "Unknown")
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.security)
|
||||
@@ -760,17 +750,9 @@
|
||||
if(hasHUD(usr,"security"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/read = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.security)
|
||||
@@ -792,24 +774,16 @@
|
||||
if(hasHUD(usr,"security"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/read = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.security)
|
||||
if(R.fields["id"] == E.fields["id"])
|
||||
if(hasHUD(usr,"security"))
|
||||
read = 1
|
||||
if(length(R.fields["comments"]))
|
||||
if(LAZYLEN(R.fields["comments"]))
|
||||
for(var/c in R.fields["comments"])
|
||||
to_chat(usr, c)
|
||||
else
|
||||
@@ -823,15 +797,8 @@
|
||||
if(hasHUD(usr,"security"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.security)
|
||||
@@ -854,17 +821,8 @@
|
||||
if(hasHUD(usr,"medical"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/modified = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
@@ -889,17 +847,9 @@
|
||||
if(hasHUD(usr,"medical"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/read = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.medical)
|
||||
@@ -922,24 +872,16 @@
|
||||
if(hasHUD(usr,"medical"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/read = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.medical)
|
||||
if(R.fields["id"] == E.fields["id"])
|
||||
if(hasHUD(usr,"medical"))
|
||||
read = 1
|
||||
if(length(R.fields["comments"]))
|
||||
if(LAZYLEN(R.fields["comments"]))
|
||||
for(var/c in R.fields["comments"])
|
||||
to_chat(usr, c)
|
||||
else
|
||||
@@ -953,15 +895,7 @@
|
||||
if(hasHUD(usr,"medical"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.medical)
|
||||
@@ -976,6 +910,9 @@
|
||||
if(isrobot(usr))
|
||||
var/mob/living/silicon/robot/U = usr
|
||||
R.fields["comments"] += "Made by [U.name] ([U.modtype] [U.braintype]) on [current_date_string] [station_time_timestamp()]<BR>[t1]"
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
R.fields["comments"] += "Made by [U.name] (artificial intelligence) on [current_date_string] [station_time_timestamp()]<BR>[t1]"
|
||||
|
||||
if(href_list["lookitem"])
|
||||
var/obj/item/I = locate(href_list["lookitem"])
|
||||
@@ -1480,19 +1417,22 @@
|
||||
|
||||
if(usr != src)
|
||||
return 0 //something is terribly wrong
|
||||
|
||||
if(incapacitated())
|
||||
to_chat(src, "<span class='warning'>You can't write on the floor in your current state!</span>")
|
||||
return
|
||||
if(!bloody_hands)
|
||||
verbs -= /mob/living/carbon/human/proc/bloody_doodle
|
||||
|
||||
if(src.gloves)
|
||||
to_chat(src, "<span class='warning'>Your [src.gloves] are getting in the way.</span>")
|
||||
if(gloves)
|
||||
to_chat(src, "<span class='warning'>[gloves] are preventing you from writing anything down!</span>")
|
||||
return
|
||||
|
||||
var/turf/simulated/T = src.loc
|
||||
var/turf/simulated/T = loc
|
||||
if(!istype(T)) //to prevent doodling out of mechs and lockers
|
||||
to_chat(src, "<span class='warning'>You cannot reach the floor.</span>")
|
||||
return
|
||||
|
||||
var/turf/origin = T
|
||||
var/direction = input(src,"Which way?","Tile selection") as anything in list("Here","North","South","East","West")
|
||||
if(direction != "Here")
|
||||
T = get_step(T,text2dir(direction))
|
||||
@@ -1510,7 +1450,9 @@
|
||||
var/max_length = bloody_hands * 30 //tweeter style
|
||||
|
||||
var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")
|
||||
|
||||
if(origin != loc)
|
||||
to_chat(src, "<span class='notice'>Stay still while writing!</span>")
|
||||
return
|
||||
if(message)
|
||||
var/used_blood_amount = round(length(message) / 30, 1)
|
||||
bloody_hands = max(0, bloody_hands - used_blood_amount) //use up some blood
|
||||
@@ -1518,7 +1460,8 @@
|
||||
if(length(message) > max_length)
|
||||
message += "-"
|
||||
to_chat(src, "<span class='warning'>You ran out of blood to write with!</span>")
|
||||
|
||||
else
|
||||
to_chat(src, "<span class='notice'>You daub '[message]' on [T] in shiny red lettering.</span>")
|
||||
var/obj/effect/decal/cleanable/blood/writing/W = new(T)
|
||||
W.message = message
|
||||
W.add_fingerprint(src)
|
||||
@@ -1602,7 +1545,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
|
||||
|
||||
//Check for arrest warrant
|
||||
if(judgebot.check_records)
|
||||
var/perpname = get_face_name(get_id_name())
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/datum/data/record/R = find_record("name", perpname, data_core.security)
|
||||
if(R && R.fields["criminal"])
|
||||
switch(R.fields["criminal"])
|
||||
@@ -1935,7 +1878,6 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
|
||||
. += "---"
|
||||
.["Set Species"] = "?_src_=vars;setspecies=[UID()]"
|
||||
.["Make AI"] = "?_src_=vars;makeai=[UID()]"
|
||||
.["Make Mask of Nar'sie"] = "?_src_=vars;makemask=[UID()]"
|
||||
.["Make cyborg"] = "?_src_=vars;makerobot=[UID()]"
|
||||
.["Make monkey"] = "?_src_=vars;makemonkey=[UID()]"
|
||||
.["Make alien"] = "?_src_=vars;makealien=[UID()]"
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
/mob/living/carbon/human/verb/quick_equip()
|
||||
set name = "quick-equip"
|
||||
set hidden = 1
|
||||
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(I)
|
||||
I.equip_to_best_slot(src)
|
||||
|
||||
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1)
|
||||
for(var/slot in slots)
|
||||
if(equip_to_slot_if_possible(W, slots[slot], del_on_fail = 0))
|
||||
|
||||
@@ -341,9 +341,6 @@
|
||||
if(SKELETON in target.mutations)
|
||||
to_chat(user, "<span class='warning'>There is no blood in a skeleton!</span>")
|
||||
return
|
||||
if(issmall(target) && !target.ckey) //Monkeyized humans are okay, humanized monkeys are okay, NPC monkeys are not.
|
||||
to_chat(user, "<span class='warning'>Blood from a monkey is useless!</span>")
|
||||
return
|
||||
//we're good to suck the blood, blaah
|
||||
user.mind.vampire.handle_bloodsucking(target)
|
||||
add_attack_logs(user, target, "vampirebit")
|
||||
@@ -603,20 +600,37 @@
|
||||
H.healthdoll.cached_healthdoll_overlays = new_overlays
|
||||
|
||||
/datum/species/proc/handle_hud_icons_nutrition(mob/living/carbon/human/H)
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fat)
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/full)
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/well_fed)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fed)
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/hungry)
|
||||
else
|
||||
H.throw_alert("nutrition", /obj/screen/alert/starving)
|
||||
return 1
|
||||
if(H.mind && H.mind.vampire && (H.mind in SSticker.mode.vampires)) //Vampires
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fat/vampire)
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/full/vampire)
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/well_fed/vampire)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fed/vampire)
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/hungry/vampire)
|
||||
else
|
||||
H.throw_alert("nutrition", /obj/screen/alert/starving/vampire)
|
||||
return 1
|
||||
|
||||
else ///Any other non-vampires
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fat)
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/full)
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/well_fed)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fed)
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/hungry)
|
||||
else
|
||||
H.throw_alert("nutrition", /obj/screen/alert/starving)
|
||||
return 1
|
||||
|
||||
/*
|
||||
Returns the path corresponding to the corresponding organ
|
||||
@@ -675,7 +689,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u
|
||||
H.see_invisible = G.invis_override
|
||||
else
|
||||
H.see_invisible = min(G.invis_view, H.see_invisible)
|
||||
|
||||
|
||||
if(!isnull(G.lighting_alpha))
|
||||
H.lighting_alpha = min(G.lighting_alpha, H.lighting_alpha)
|
||||
|
||||
|
||||
@@ -59,8 +59,7 @@
|
||||
handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
|
||||
|
||||
if(client)
|
||||
//regular_hud_updates() //THIS DOESN'T FUCKING UPDATE SHIT
|
||||
handle_regular_hud_updates() //IT JUST REMOVES FUCKING HUD IMAGES
|
||||
handle_regular_hud_updates()
|
||||
|
||||
..()
|
||||
|
||||
|
||||
@@ -528,7 +528,7 @@
|
||||
return
|
||||
|
||||
var/pull_dir = get_dir(src, pulling)
|
||||
if(get_dist(src, pulling) > 1 || ((pull_dir - 1) & pull_dir)) // puller and pullee more than one tile away or in diagonal position
|
||||
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position
|
||||
if(isliving(pulling))
|
||||
var/mob/living/M = pulling
|
||||
if(M.lying && !M.buckled && (prob(M.getBruteLoss() * 200 / M.maxHealth)))
|
||||
|
||||
@@ -216,7 +216,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
message_range = 1
|
||||
|
||||
if(pressure < ONE_ATMOSPHERE * 0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
|
||||
italics = 1
|
||||
italics = TRUE
|
||||
sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact
|
||||
|
||||
var/list/hear = hear(message_range, T)
|
||||
@@ -236,12 +236,20 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
continue
|
||||
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
if(M.stat == DEAD && M.client && M.get_preference(CHAT_GHOSTEARS) && client) // client is so that ghosts don't have to listen to mice
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(isobserver(M))
|
||||
if(M.get_preference(CHAT_GHOSTEARS) && client) // The client check is so that ghosts don't have to listen to mice.
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(message_range < world.view && (get_dist(T, M) <= world.view))
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(get_turf(M) in hearturfs)
|
||||
listening |= M
|
||||
|
||||
@@ -291,10 +299,13 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
log_emote(message, src)
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
if(!M.client || istype(M, /mob/new_player))
|
||||
continue //skip monkeys, leavers and new players //who the hell knows why new players are in the dead mob list
|
||||
if(!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
|
||||
if(M.stat == DEAD && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
switch(type)
|
||||
@@ -380,7 +391,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
|
||||
var/list/hearturfs = list()
|
||||
|
||||
//Pass whispers on to anything inside the immediate listeners.
|
||||
// Pass whispers on to anything inside the immediate listeners.
|
||||
// This comes before the ghosts do so that ghosts don't act as whisper relays
|
||||
for(var/atom/L in listening)
|
||||
if(ismob(L))
|
||||
@@ -391,22 +402,26 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(isobj(L))
|
||||
hearturfs += get_turf(L)
|
||||
|
||||
//ghosts
|
||||
for(var/mob/M in GLOB.dead_mob_list) //does this include players who joined as observers as well?
|
||||
// Loop through all players to see if they need to hear it.
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(M.stat == DEAD && M.client && M.get_preference(CHAT_GHOSTEARS))
|
||||
listening |= M
|
||||
|
||||
// This, in tandem with "hearturfs", lets nested mobs hear whispers that are in range
|
||||
// Grifted from saycode above.
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client || isnewplayer(M))
|
||||
continue //skip monkeys and leavers
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M))
|
||||
if(M.get_preference(CHAT_GHOSTEARS)) // The client check is so that ghosts don't have to listen to mice.
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(message_range < world.view && (get_dist(whisper_loc, M) <= world.view))
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(get_turf(M) in hearturfs)
|
||||
listening |= M
|
||||
|
||||
|
||||
//pass on the message to objects that can hear us.
|
||||
for(var/obj/O in view(message_range, whisper_loc))
|
||||
spawn(0)
|
||||
|
||||
@@ -498,7 +498,7 @@ var/list/ai_verbs_default = list(
|
||||
if(check_unable(AI_CHECK_WIRELESS))
|
||||
return
|
||||
|
||||
var/input = input(usr, "Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","") as text|null
|
||||
var/input = clean_input("Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","")
|
||||
if(!input || stat)
|
||||
return
|
||||
|
||||
@@ -634,7 +634,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if(href_list["trackbot"])
|
||||
var/mob/living/simple_animal/bot/target = locate(href_list["trackbot"]) in GLOB.simple_animals
|
||||
var/mob/living/simple_animal/bot/target = locate(href_list["trackbot"]) in GLOB.bots_list
|
||||
if(target)
|
||||
ai_actual_track(target)
|
||||
else
|
||||
@@ -642,7 +642,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if(href_list["callbot"]) //Command a bot to move to a selected location.
|
||||
Bot = locate(href_list["callbot"]) in GLOB.simple_animals
|
||||
Bot = locate(href_list["callbot"]) in GLOB.bots_list
|
||||
if(!Bot || Bot.remote_disabled || control_disabled)
|
||||
return //True if there is no bot found, the bot is manually emagged, or the AI is carded with wireless off.
|
||||
waypoint_mode = 1
|
||||
@@ -650,7 +650,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if(href_list["interface"]) //Remotely connect to a bot!
|
||||
Bot = locate(href_list["interface"]) in GLOB.simple_animals
|
||||
Bot = locate(href_list["interface"]) in GLOB.bots_list
|
||||
if(!Bot || Bot.remote_disabled || control_disabled)
|
||||
return
|
||||
Bot.attack_ai(src)
|
||||
@@ -746,7 +746,7 @@ var/list/ai_verbs_default = list(
|
||||
d += "<A HREF=?src=[UID()];botrefresh=\ref[Bot]>Query network status</A><br>"
|
||||
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='20%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
|
||||
|
||||
for(var/mob/living/simple_animal/bot/Bot in GLOB.simple_animals)
|
||||
for(var/mob/living/simple_animal/bot/Bot in GLOB.bots_list)
|
||||
if(is_ai_allowed(Bot.z) && !Bot.remote_disabled) //Only non-emagged bots on the allowed Z-level are detected!
|
||||
bot_area = get_area(Bot)
|
||||
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!) </span>[Bot.name]" : Bot.name] ([Bot.model])</td>"
|
||||
@@ -1074,7 +1074,7 @@ var/list/ai_verbs_default = list(
|
||||
set desc = "Change the message that's transmitted when a new crew member arrives on station."
|
||||
set category = "AI Commands"
|
||||
|
||||
var/newmsg = input("What would you like the arrival message to be? List of options: $name, $rank, $species, $gender, $age", "Change Arrival Message", arrivalmsg) as text
|
||||
var/newmsg = clean_input("What would you like the arrival message to be? List of options: $name, $rank, $species, $gender, $age", "Change Arrival Message", arrivalmsg)
|
||||
if(newmsg != arrivalmsg)
|
||||
arrivalmsg = newmsg
|
||||
to_chat(usr, "The arrival message has been successfully changed.")
|
||||
|
||||
@@ -99,7 +99,7 @@ var/const/VOX_PATH = "sound/vox_fem/"
|
||||
to_chat(src, "<span class='warning'>Please wait [round((announcing_vox - world.time) / 10)] seconds.</span>")
|
||||
return
|
||||
|
||||
var/message = input(src, "WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement) as text|null
|
||||
var/message = clean_input("WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement, src)
|
||||
|
||||
last_announcement = message
|
||||
|
||||
|
||||
@@ -2,6 +2,3 @@
|
||||
..()
|
||||
regenerate_icons()
|
||||
show_laws(0)
|
||||
|
||||
var/datum/hotkey_mode/cyborg/C = new(src)
|
||||
C.set_winset_values()
|
||||
|
||||
@@ -103,6 +103,9 @@ var/list/robot_verbs_default = list(
|
||||
var/datum/action/item_action/toggle_research_scanner/scanner = null
|
||||
var/list/module_actions = list()
|
||||
|
||||
/mob/living/silicon/robot/get_cell()
|
||||
return cell
|
||||
|
||||
/mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0, var/alien = 0)
|
||||
spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
@@ -1453,4 +1456,4 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
|
||||
sync_lighting_plane_alpha()
|
||||
|
||||
|
||||
|
||||
@@ -156,7 +156,6 @@
|
||||
/mob/living/silicon/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
show_stat_station_time()
|
||||
show_stat_emergency_shuttle_eta()
|
||||
show_system_integrity()
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
..()
|
||||
light_color = LIGHT_COLOR_PURE_RED //if you see a red one. RUN!!
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/Crossed(atom/movable/AM)
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/Crossed(atom/movable/AM, oldloc)
|
||||
..()
|
||||
if(ismob(AM) && AM == target)
|
||||
var/mob/living/carbon/C = AM
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/Crossed(atom/movable/AM)
|
||||
/mob/living/simple_animal/bot/honkbot/Crossed(atom/movable/AM, oldloc)
|
||||
if(ismob(AM) && on) //only if its online
|
||||
if(prob(30)) //you're far more likely to trip on a honkbot
|
||||
var/mob/living/carbon/C = AM
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
var/currentBloodColor = "#A10808"
|
||||
var/currentDNA = null
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/get_cell()
|
||||
return cell
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/New()
|
||||
..()
|
||||
wires = new /datum/wires/mulebot(src)
|
||||
|
||||
@@ -439,7 +439,7 @@ Auto Patrol: []"},
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM)
|
||||
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM, oldloc)
|
||||
if(ismob(AM) && target)
|
||||
var/mob/living/carbon/C = AM
|
||||
if(!istype(C) || !C || in_range(src, target))
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
status_flags = 0
|
||||
const_type = "juggernaut"
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/night_vision, /obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
|
||||
force_threshold = 11
|
||||
playstyle_string = "<b>You are a Juggernaut. Though slow, your shell can withstand extreme punishment, \
|
||||
create shield walls, rip apart enemies and walls alike, and even deflect energy weapons.</b>"
|
||||
@@ -171,7 +171,7 @@
|
||||
see_in_dark = 8
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
const_type = "wraith"
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/night_vision, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
|
||||
retreat_distance = 2 //AI wraiths will move in and out of combat
|
||||
playstyle_string = "<b>You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</b>"
|
||||
|
||||
@@ -202,7 +202,8 @@
|
||||
minimum_distance = 10 //AI artificers will flee like fuck
|
||||
attack_sound = 'sound/weapons/punch2.ogg'
|
||||
const_type = "builder"
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/night_vision,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/pylon,
|
||||
@@ -311,7 +312,8 @@
|
||||
see_in_dark = 8
|
||||
attack_sound = 'sound/weapons/tap.ogg'
|
||||
const_type = "harvester"
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/night_vision,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
|
||||
/obj/effect/proc_holder/spell/targeted/smoke/disable)
|
||||
retreat_distance = 2 //AI harvesters will move in and out of combat, like wraiths, but shittier
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
/mob/living/simple_animal/cockroach/can_die()
|
||||
return ..() && !SSticker.cinematic //If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes.
|
||||
|
||||
/mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM)
|
||||
/mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM, oldloc)
|
||||
if(isliving(AM))
|
||||
var/mob/living/A = AM
|
||||
if(A.mob_size > MOB_SIZE_SMALL)
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
to_chat(src, "<span class='warning'>You are too small to pull anything.</span>")
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj)
|
||||
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj, oldloc)
|
||||
if(ishuman(AM))
|
||||
if(!stat)
|
||||
var/mob/M = AM
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
turns_per_move = 10
|
||||
icon = 'icons/mob/penguins.dmi'
|
||||
|
||||
/mob/living/simple_animal/pet/penguin/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/waddling)
|
||||
|
||||
/mob/living/simple_animal/pet/penguin/emperor
|
||||
name = "Emperor penguin"
|
||||
real_name = "penguin"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "alienh_running"
|
||||
icon_living = "alienh_running"
|
||||
icon_dead = "alien_l"
|
||||
icon_dead = "alienh_dead"
|
||||
icon_gib = "syndicate_gib"
|
||||
response_help = "pokes the"
|
||||
response_disarm = "shoves the"
|
||||
@@ -40,7 +40,7 @@
|
||||
name = "alien drone"
|
||||
icon_state = "aliend_running"
|
||||
icon_living = "aliend_running"
|
||||
icon_dead = "aliend_l"
|
||||
icon_dead = "aliend_dead"
|
||||
health = 60
|
||||
maxHealth = 60
|
||||
melee_damage_lower = 15
|
||||
@@ -61,7 +61,7 @@
|
||||
name = "alien sentinel"
|
||||
icon_state = "aliens_running"
|
||||
icon_living = "aliens_running"
|
||||
icon_dead = "aliens_l"
|
||||
icon_dead = "aliens_dead"
|
||||
health = 120
|
||||
maxHealth = 120
|
||||
melee_damage_lower = 15
|
||||
@@ -77,7 +77,7 @@
|
||||
name = "alien queen"
|
||||
icon_state = "alienq_running"
|
||||
icon_living = "alienq_running"
|
||||
icon_dead = "alienq_l"
|
||||
icon_dead = "alienq_d"
|
||||
health = 250
|
||||
maxHealth = 250
|
||||
melee_damage_lower = 15
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
return //no don't attack the goddamm box
|
||||
else
|
||||
..()
|
||||
if(isliving(target))
|
||||
if(isliving(target) && (!client || a_intent == INTENT_HARM))
|
||||
var/mob/living/L = target
|
||||
if(L.reagents)
|
||||
if(beegent)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/mob/living/simple_animal/hostile/creature
|
||||
name = "creature"
|
||||
desc = "A sanity-destroying otherthing."
|
||||
icon = 'icons/mob/critter.dmi'
|
||||
speak_emote = list("gibbers")
|
||||
icon_state = "otherthing"
|
||||
icon_living = "otherthing"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
maxHealth = 50
|
||||
health = 50
|
||||
pixel_x = -16
|
||||
see_in_dark = 8
|
||||
|
||||
harm_intent_damage = 8
|
||||
melee_damage_lower = 15
|
||||
|
||||
@@ -1,265 +1,265 @@
|
||||
#define MINER_DASH_RANGE 4
|
||||
|
||||
/*
|
||||
|
||||
BLOOD-DRUNK MINER
|
||||
|
||||
Effectively a highly aggressive miner, the blood-drunk miner has very few attacks but compensates by being highly aggressive.
|
||||
|
||||
The blood-drunk miner's attacks are as follows
|
||||
- If not in KA range, it will rapidly dash at its target
|
||||
- If in KA range, it will fire its kinetic accelerator
|
||||
- If in melee range, will rapidly attack, akin to an actual player
|
||||
- After any of these attacks, may transform its cleaving saw:
|
||||
Untransformed, it attacks very rapidly for smaller amounts of damage
|
||||
Transformed, it attacks at normal speed for higher damage and cleaves enemies hit
|
||||
|
||||
When the blood-drunk miner dies, it leaves behind the cleaving saw it was using and its kinetic accelerator.
|
||||
|
||||
Difficulty: Medium
|
||||
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner
|
||||
name = "blood-drunk miner"
|
||||
desc = "A miner destined to wander forever, engaged in an endless hunt."
|
||||
health = 900
|
||||
maxHealth = 900
|
||||
icon_state = "miner"
|
||||
icon_living = "miner"
|
||||
icon = 'icons/mob/alienqueen.dmi'
|
||||
light_color = "#E4C7C5"
|
||||
speak_emote = list("roars")
|
||||
speed = 1
|
||||
move_to_delay = 3
|
||||
projectiletype = /obj/item/projectile/kinetic/miner
|
||||
projectilesound = 'sound/weapons/kenetic_accel.ogg'
|
||||
ranged = 1
|
||||
ranged_cooldown_time = 16
|
||||
pixel_x = -16
|
||||
loot = list(/obj/item/melee/energy/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator)
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
var/obj/item/melee/energy/cleaving_saw/miner/miner_saw
|
||||
var/time_until_next_transform = 0
|
||||
var/dashing = FALSE
|
||||
var/dash_cooldown = 15
|
||||
var/guidance = FALSE
|
||||
deathmessage = "falls to the ground, decaying into glowing particles."
|
||||
death_sound = "bodyfall"
|
||||
|
||||
/obj/item/gps/internal/miner
|
||||
icon_state = null
|
||||
gpstag = "Resonant Signal"
|
||||
desc = "The sweet blood, oh, it sings to me."
|
||||
invisibility = 100
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance
|
||||
guidance = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter/AttackingTarget()
|
||||
. = ..()
|
||||
if(. && prob(12))
|
||||
INVOKE_ASYNC(src, .proc/dash)
|
||||
|
||||
/obj/item/melee/energy/cleaving_saw/miner //nerfed saw because it is very murdery
|
||||
force = 6
|
||||
force_on = 10
|
||||
|
||||
/obj/item/melee/energy/cleaving_saw/miner/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
target.add_stun_absorption("miner", 10, INFINITY)
|
||||
..()
|
||||
target.stun_absorption -= "miner"
|
||||
|
||||
/obj/item/projectile/kinetic/miner
|
||||
damage = 20
|
||||
speed = 0.9
|
||||
icon_state = "ka_tracer"
|
||||
range = MINER_DASH_RANGE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Initialize()
|
||||
. = ..()
|
||||
miner_saw = new(src)
|
||||
internal_gps = new/obj/item/gps/internal/miner(src)
|
||||
|
||||
// Add a zone selection UI; otherwise the mob can't melee attack properly.
|
||||
zone_sel = new /obj/screen/zone_sel()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
var/adjustment_amount = amount * 0.1
|
||||
if(world.time + adjustment_amount > next_move)
|
||||
changeNext_move(adjustment_amount) //attacking it interrupts it attacking, but only briefly
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/death()
|
||||
if(health > 0)
|
||||
return
|
||||
new /obj/effect/temp_visual/dir_setting/miner_death(loc, dir)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Move(atom/newloc)
|
||||
if(dashing || (newloc && newloc.z == z && (islava(newloc) || ischasm(newloc)))) //we're not stupid!
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity, target)
|
||||
if(dash())
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/AttackingTarget()
|
||||
if(QDELETED(target))
|
||||
return
|
||||
if(next_move > world.time || !Adjacent(target)) //some cheating
|
||||
INVOKE_ASYNC(src, .proc/quick_attack_loop)
|
||||
return
|
||||
face_atom(target)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat == DEAD)
|
||||
visible_message("<span class='danger'>[src] butchers [L]!</span>",
|
||||
"<span class='userdanger'>You butcher [L], restoring your health!</span>")
|
||||
if(!is_station_level(z) || client) //NPC monsters won't heal while on station
|
||||
if(guidance)
|
||||
adjustHealth(-L.maxHealth)
|
||||
else
|
||||
adjustHealth(-(L.maxHealth * 0.5))
|
||||
L.gib()
|
||||
return TRUE
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
miner_saw.melee_attack_chain(src, target)
|
||||
if(guidance)
|
||||
adjustHealth(-2)
|
||||
transform_weapon()
|
||||
INVOKE_ASYNC(src, .proc/quick_attack_loop)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
|
||||
if(!used_item && !isturf(A))
|
||||
used_item = miner_saw
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/GiveTarget(new_target)
|
||||
var/targets_the_same = (new_target == target)
|
||||
. = ..()
|
||||
if(. && target && !targets_the_same)
|
||||
wander = TRUE
|
||||
transform_weapon()
|
||||
INVOKE_ASYNC(src, .proc/quick_attack_loop)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/OpenFire()
|
||||
Goto(target, move_to_delay, minimum_distance)
|
||||
if(get_dist(src, target) > MINER_DASH_RANGE && dash_cooldown <= world.time)
|
||||
INVOKE_ASYNC(src, .proc/dash, target)
|
||||
else
|
||||
shoot_ka()
|
||||
transform_weapon()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/shoot_ka()
|
||||
if(ranged_cooldown <= world.time && get_dist(src, target) <= MINER_DASH_RANGE && !Adjacent(target))
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
visible_message("<span class='danger'>[src] fires the proto-kinetic accelerator!</span>")
|
||||
face_atom(target)
|
||||
new /obj/effect/temp_visual/dir_setting/firing_effect(loc, dir)
|
||||
Shoot(target)
|
||||
changeNext_move(CLICK_CD_RANGE)
|
||||
|
||||
//I'm still of the belief that this entire proc needs to be wiped from existence.
|
||||
// do not take my touching of it to be endorsement of it. ~mso
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop()
|
||||
while(!QDELETED(target) && next_move <= world.time) //this is done this way because next_move can change to be sooner while we sleep.
|
||||
stoplag(1)
|
||||
sleep((next_move - world.time) * 1.5) //but don't ask me what the fuck this is about
|
||||
if(QDELETED(target))
|
||||
return
|
||||
if(dashing || next_move > world.time || !Adjacent(target))
|
||||
if(dashing && next_move <= world.time)
|
||||
next_move = world.time + 1
|
||||
INVOKE_ASYNC(src, .proc/quick_attack_loop) //lets try that again.
|
||||
return
|
||||
AttackingTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/dash(atom/dash_target)
|
||||
if(world.time < dash_cooldown)
|
||||
return
|
||||
var/list/accessable_turfs = list()
|
||||
var/self_dist_to_target = 0
|
||||
var/turf/own_turf = get_turf(src)
|
||||
if(!QDELETED(dash_target))
|
||||
self_dist_to_target += get_dist(dash_target, own_turf)
|
||||
for(var/turf/simulated/O in RANGE_TURFS(MINER_DASH_RANGE, own_turf))
|
||||
var/turf_dist_to_target = 0
|
||||
if(!QDELETED(dash_target))
|
||||
turf_dist_to_target += get_dist(dash_target, O)
|
||||
if(get_dist(src, O) >= MINER_DASH_RANGE && turf_dist_to_target <= self_dist_to_target && !islava(O) && !ischasm(O))
|
||||
var/valid = TRUE
|
||||
for(var/turf/T in getline(own_turf, O))
|
||||
if(is_blocked_turf(T, TRUE))
|
||||
valid = FALSE
|
||||
continue
|
||||
if(valid)
|
||||
accessable_turfs[O] = turf_dist_to_target
|
||||
var/turf/target_turf
|
||||
if(!QDELETED(dash_target))
|
||||
var/closest_dist = MINER_DASH_RANGE
|
||||
for(var/t in accessable_turfs)
|
||||
if(accessable_turfs[t] < closest_dist)
|
||||
closest_dist = accessable_turfs[t]
|
||||
for(var/t in accessable_turfs)
|
||||
if(accessable_turfs[t] != closest_dist)
|
||||
accessable_turfs -= t
|
||||
if(!LAZYLEN(accessable_turfs))
|
||||
return
|
||||
dash_cooldown = world.time + initial(dash_cooldown)
|
||||
target_turf = pick(accessable_turfs)
|
||||
var/turf/step_back_turf = get_step(target_turf, get_cardinal_dir(target_turf, own_turf))
|
||||
var/turf/step_forward_turf = get_step(own_turf, get_cardinal_dir(own_turf, target_turf))
|
||||
new /obj/effect/temp_visual/small_smoke/halfsecond(step_back_turf)
|
||||
new /obj/effect/temp_visual/small_smoke/halfsecond(step_forward_turf)
|
||||
var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc, src)
|
||||
animate(D, alpha = 0, time = 5)
|
||||
forceMove(step_back_turf)
|
||||
playsound(own_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1)
|
||||
dashing = TRUE
|
||||
alpha = 0
|
||||
animate(src, alpha = 255, time = 5)
|
||||
sleep(2)
|
||||
D.forceMove(step_forward_turf)
|
||||
forceMove(target_turf)
|
||||
playsound(target_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1)
|
||||
sleep(1)
|
||||
dashing = FALSE
|
||||
shoot_ka()
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/transform_weapon()
|
||||
if(time_until_next_transform <= world.time)
|
||||
miner_saw.transform_cooldown = 0
|
||||
miner_saw.transform_weapon(src, TRUE)
|
||||
icon_state = "miner[miner_saw.active ? "_transformed":""]"
|
||||
icon_living = "miner[miner_saw.active ? "_transformed":""]"
|
||||
time_until_next_transform = world.time + rand(50, 100)
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/miner_death
|
||||
icon_state = "miner_death"
|
||||
duration = 15
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/miner_death/Initialize(mapload, set_dir)
|
||||
. = ..()
|
||||
INVOKE_ASYNC(src, .proc/fade_out)
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/miner_death/proc/fade_out()
|
||||
var/matrix/M = new
|
||||
M.Turn(pick(90, 270))
|
||||
var/final_dir = dir
|
||||
if(dir & (EAST|WEST)) //Facing east or west
|
||||
final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
|
||||
|
||||
animate(src, transform = M, pixel_y = -6, dir = final_dir, time = 2, easing = EASE_IN|EASE_OUT)
|
||||
sleep(5)
|
||||
animate(src, color = list("#A7A19E", "#A7A19E", "#A7A19E", list(0, 0, 0)), time = 10, easing = EASE_IN, flags = ANIMATION_PARALLEL)
|
||||
sleep(4)
|
||||
animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags = ANIMATION_PARALLEL)
|
||||
|
||||
#define MINER_DASH_RANGE 4
|
||||
|
||||
/*
|
||||
|
||||
BLOOD-DRUNK MINER
|
||||
|
||||
Effectively a highly aggressive miner, the blood-drunk miner has very few attacks but compensates by being highly aggressive.
|
||||
|
||||
The blood-drunk miner's attacks are as follows
|
||||
- If not in KA range, it will rapidly dash at its target
|
||||
- If in KA range, it will fire its kinetic accelerator
|
||||
- If in melee range, will rapidly attack, akin to an actual player
|
||||
- After any of these attacks, may transform its cleaving saw:
|
||||
Untransformed, it attacks very rapidly for smaller amounts of damage
|
||||
Transformed, it attacks at normal speed for higher damage and cleaves enemies hit
|
||||
|
||||
When the blood-drunk miner dies, it leaves behind the cleaving saw it was using and its kinetic accelerator.
|
||||
|
||||
Difficulty: Medium
|
||||
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner
|
||||
name = "blood-drunk miner"
|
||||
desc = "A miner destined to wander forever, engaged in an endless hunt."
|
||||
health = 900
|
||||
maxHealth = 900
|
||||
icon_state = "miner"
|
||||
icon_living = "miner"
|
||||
icon = 'icons/mob/alienqueen.dmi'
|
||||
light_color = "#E4C7C5"
|
||||
speak_emote = list("roars")
|
||||
speed = 1
|
||||
move_to_delay = 3
|
||||
projectiletype = /obj/item/projectile/kinetic/miner
|
||||
projectilesound = 'sound/weapons/kenetic_accel.ogg'
|
||||
ranged = 1
|
||||
ranged_cooldown_time = 16
|
||||
pixel_x = -16
|
||||
loot = list(/obj/item/melee/energy/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator)
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
var/obj/item/melee/energy/cleaving_saw/miner/miner_saw
|
||||
var/time_until_next_transform = 0
|
||||
var/dashing = FALSE
|
||||
var/dash_cooldown = 15
|
||||
var/guidance = FALSE
|
||||
deathmessage = "falls to the ground, decaying into glowing particles."
|
||||
death_sound = "bodyfall"
|
||||
|
||||
/obj/item/gps/internal/miner
|
||||
icon_state = null
|
||||
gpstag = "Resonant Signal"
|
||||
desc = "The sweet blood, oh, it sings to me."
|
||||
invisibility = 100
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance
|
||||
guidance = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter/AttackingTarget()
|
||||
. = ..()
|
||||
if(. && prob(12))
|
||||
INVOKE_ASYNC(src, .proc/dash)
|
||||
|
||||
/obj/item/melee/energy/cleaving_saw/miner //nerfed saw because it is very murdery
|
||||
force = 6
|
||||
force_on = 10
|
||||
|
||||
/obj/item/melee/energy/cleaving_saw/miner/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
target.add_stun_absorption("miner", 10, INFINITY)
|
||||
..()
|
||||
target.stun_absorption -= "miner"
|
||||
|
||||
/obj/item/projectile/kinetic/miner
|
||||
damage = 20
|
||||
speed = 0.9
|
||||
icon_state = "ka_tracer"
|
||||
range = MINER_DASH_RANGE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Initialize()
|
||||
. = ..()
|
||||
miner_saw = new(src)
|
||||
internal_gps = new/obj/item/gps/internal/miner(src)
|
||||
|
||||
// Add a zone selection UI; otherwise the mob can't melee attack properly.
|
||||
zone_sel = new /obj/screen/zone_sel()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
var/adjustment_amount = amount * 0.1
|
||||
if(world.time + adjustment_amount > next_move)
|
||||
changeNext_move(adjustment_amount) //attacking it interrupts it attacking, but only briefly
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/death()
|
||||
if(health > 0)
|
||||
return
|
||||
new /obj/effect/temp_visual/dir_setting/miner_death(loc, dir)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Move(atom/newloc)
|
||||
if(dashing || (newloc && newloc.z == z && (islava(newloc) || ischasm(newloc)))) //we're not stupid!
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity, target)
|
||||
if(dash())
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/AttackingTarget()
|
||||
if(QDELETED(target))
|
||||
return
|
||||
if(next_move > world.time || !Adjacent(target)) //some cheating
|
||||
INVOKE_ASYNC(src, .proc/quick_attack_loop)
|
||||
return
|
||||
face_atom(target)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat == DEAD)
|
||||
visible_message("<span class='danger'>[src] butchers [L]!</span>",
|
||||
"<span class='userdanger'>You butcher [L], restoring your health!</span>")
|
||||
if(!is_station_level(z) || client) //NPC monsters won't heal while on station
|
||||
if(guidance)
|
||||
adjustHealth(-L.maxHealth)
|
||||
else
|
||||
adjustHealth(-(L.maxHealth * 0.5))
|
||||
L.gib()
|
||||
return TRUE
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
miner_saw.melee_attack_chain(src, target)
|
||||
if(guidance)
|
||||
adjustHealth(-2)
|
||||
transform_weapon()
|
||||
INVOKE_ASYNC(src, .proc/quick_attack_loop)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
|
||||
if(!used_item && !isturf(A))
|
||||
used_item = miner_saw
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/GiveTarget(new_target)
|
||||
var/targets_the_same = (new_target == target)
|
||||
. = ..()
|
||||
if(. && target && !targets_the_same)
|
||||
wander = TRUE
|
||||
transform_weapon()
|
||||
INVOKE_ASYNC(src, .proc/quick_attack_loop)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/OpenFire()
|
||||
Goto(target, move_to_delay, minimum_distance)
|
||||
if(get_dist(src, target) > MINER_DASH_RANGE && dash_cooldown <= world.time)
|
||||
INVOKE_ASYNC(src, .proc/dash, target)
|
||||
else
|
||||
shoot_ka()
|
||||
transform_weapon()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/shoot_ka()
|
||||
if(ranged_cooldown <= world.time && get_dist(src, target) <= MINER_DASH_RANGE && !Adjacent(target))
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
visible_message("<span class='danger'>[src] fires the proto-kinetic accelerator!</span>")
|
||||
face_atom(target)
|
||||
new /obj/effect/temp_visual/dir_setting/firing_effect(loc, dir)
|
||||
Shoot(target)
|
||||
changeNext_move(CLICK_CD_RANGE)
|
||||
|
||||
//I'm still of the belief that this entire proc needs to be wiped from existence.
|
||||
// do not take my touching of it to be endorsement of it. ~mso
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop()
|
||||
while(!QDELETED(target) && next_move <= world.time) //this is done this way because next_move can change to be sooner while we sleep.
|
||||
stoplag(1)
|
||||
sleep((next_move - world.time) * 1.5) //but don't ask me what the fuck this is about
|
||||
if(QDELETED(target))
|
||||
return
|
||||
if(dashing || next_move > world.time || !Adjacent(target))
|
||||
if(dashing && next_move <= world.time)
|
||||
next_move = world.time + 1
|
||||
INVOKE_ASYNC(src, .proc/quick_attack_loop) //lets try that again.
|
||||
return
|
||||
AttackingTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/dash(atom/dash_target)
|
||||
if(world.time < dash_cooldown)
|
||||
return
|
||||
var/list/accessable_turfs = list()
|
||||
var/self_dist_to_target = 0
|
||||
var/turf/own_turf = get_turf(src)
|
||||
if(!QDELETED(dash_target))
|
||||
self_dist_to_target += get_dist(dash_target, own_turf)
|
||||
for(var/turf/simulated/O in RANGE_TURFS(MINER_DASH_RANGE, own_turf))
|
||||
var/turf_dist_to_target = 0
|
||||
if(!QDELETED(dash_target))
|
||||
turf_dist_to_target += get_dist(dash_target, O)
|
||||
if(get_dist(src, O) >= MINER_DASH_RANGE && turf_dist_to_target <= self_dist_to_target && !islava(O) && !ischasm(O))
|
||||
var/valid = TRUE
|
||||
for(var/turf/T in getline(own_turf, O))
|
||||
if(is_blocked_turf(T, TRUE))
|
||||
valid = FALSE
|
||||
continue
|
||||
if(valid)
|
||||
accessable_turfs[O] = turf_dist_to_target
|
||||
var/turf/target_turf
|
||||
if(!QDELETED(dash_target))
|
||||
var/closest_dist = MINER_DASH_RANGE
|
||||
for(var/t in accessable_turfs)
|
||||
if(accessable_turfs[t] < closest_dist)
|
||||
closest_dist = accessable_turfs[t]
|
||||
for(var/t in accessable_turfs)
|
||||
if(accessable_turfs[t] != closest_dist)
|
||||
accessable_turfs -= t
|
||||
if(!LAZYLEN(accessable_turfs))
|
||||
return
|
||||
dash_cooldown = world.time + initial(dash_cooldown)
|
||||
target_turf = pick(accessable_turfs)
|
||||
var/turf/step_back_turf = get_step(target_turf, get_cardinal_dir(target_turf, own_turf))
|
||||
var/turf/step_forward_turf = get_step(own_turf, get_cardinal_dir(own_turf, target_turf))
|
||||
new /obj/effect/temp_visual/small_smoke/halfsecond(step_back_turf)
|
||||
new /obj/effect/temp_visual/small_smoke/halfsecond(step_forward_turf)
|
||||
var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc, src)
|
||||
animate(D, alpha = 0, time = 5)
|
||||
forceMove(step_back_turf)
|
||||
playsound(own_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1)
|
||||
dashing = TRUE
|
||||
alpha = 0
|
||||
animate(src, alpha = 255, time = 5)
|
||||
sleep(2)
|
||||
D.forceMove(step_forward_turf)
|
||||
forceMove(target_turf)
|
||||
playsound(target_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1)
|
||||
sleep(1)
|
||||
dashing = FALSE
|
||||
shoot_ka()
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/transform_weapon()
|
||||
if(time_until_next_transform <= world.time)
|
||||
miner_saw.transform_cooldown = 0
|
||||
miner_saw.transform_weapon(src, TRUE)
|
||||
icon_state = "miner[miner_saw.active ? "_transformed":""]"
|
||||
icon_living = "miner[miner_saw.active ? "_transformed":""]"
|
||||
time_until_next_transform = world.time + rand(50, 100)
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/miner_death
|
||||
icon_state = "miner_death"
|
||||
duration = 15
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/miner_death/Initialize(mapload, set_dir)
|
||||
. = ..()
|
||||
INVOKE_ASYNC(src, .proc/fade_out)
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/miner_death/proc/fade_out()
|
||||
var/matrix/M = new
|
||||
M.Turn(pick(90, 270))
|
||||
var/final_dir = dir
|
||||
if(dir & (EAST|WEST)) //Facing east or west
|
||||
final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
|
||||
|
||||
animate(src, transform = M, pixel_y = -6, dir = final_dir, time = 2, easing = EASE_IN|EASE_OUT)
|
||||
sleep(5)
|
||||
animate(src, color = list("#A7A19E", "#A7A19E", "#A7A19E", list(0, 0, 0)), time = 10, easing = EASE_IN, flags = ANIMATION_PARALLEL)
|
||||
sleep(4)
|
||||
animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags = ANIMATION_PARALLEL)
|
||||
|
||||
#undef MINER_DASH_RANGE
|
||||
@@ -526,7 +526,7 @@ Difficulty: Hard
|
||||
sleep(1.3) //slightly forgiving; the burst animation is 1.5 deciseconds
|
||||
bursting = FALSE //we no longer damage crossers
|
||||
|
||||
/obj/effect/temp_visual/hierophant/blast/Crossed(atom/movable/AM)
|
||||
/obj/effect/temp_visual/hierophant/blast/Crossed(atom/movable/AM, oldloc)
|
||||
..()
|
||||
if(bursting)
|
||||
do_damage(get_turf(src))
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
maxHealth = 250
|
||||
max_mobs = 3
|
||||
spawn_time = 300 //30 seconds default
|
||||
mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril)
|
||||
spawn_text = "emerges from"
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
@@ -73,7 +73,7 @@
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/lavaland/goliath
|
||||
mob_type = /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril)
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/lavaland/legion
|
||||
mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril)
|
||||
@@ -0,0 +1,111 @@
|
||||
/mob/living/simple_animal/hostile/netherworld
|
||||
name = "creature"
|
||||
desc = "A sanity-destroying otherthing from the netherworld."
|
||||
icon_state = "otherthing"
|
||||
icon_living = "otherthing"
|
||||
icon_dead = "otherthing-dead"
|
||||
health = 80
|
||||
maxHealth = 80
|
||||
obj_damage = 100
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 50
|
||||
attacktext = "slashes"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
faction = list("creature")
|
||||
speak_emote = list("screams")
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
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("nether")
|
||||
|
||||
/mob/living/simple_animal/hostile/netherworld/migo
|
||||
name = "mi-go"
|
||||
desc = "A pinkish, fungoid crustacean-like creature with numerous pairs of clawed appendages and a head covered with waving antennae."
|
||||
speak_emote = list("screams", "clicks", "chitters", "barks", "moans", "growls", "meows", "reverberates", "roars", "squeaks", "rattles", "exclaims", "yells", "remarks", "mumbles", "jabbers", "stutters", "seethes")
|
||||
icon_state = "mi-go"
|
||||
icon_living = "mi-go"
|
||||
icon_dead = "mi-go-dead"
|
||||
attacktext = "lacerates"
|
||||
speed = -0.5
|
||||
var/static/list/migo_sounds
|
||||
deathmessage = "wails as its form turns into a pulpy mush."
|
||||
death_sound = 'sound/voice/hiss6.ogg'
|
||||
|
||||
/mob/living/simple_animal/hostile/netherworld/migo/Initialize()
|
||||
. = ..()
|
||||
migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/voice/bcreep.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/mpatchedup.ogg', 'sound/voice/mfeelbetter.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heartbeat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/goonstation/effects/screech.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/goonstation/misc/airraid_loop.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/chainsaw.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshots/gunshot_silenced.ogg', 'sound/weapons/gunshots/gunshot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlock_close.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlock_open.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg') //hahahaha fuck you code divers
|
||||
|
||||
/mob/living/simple_animal/hostile/netherworld/migo/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||
..()
|
||||
if(stat)
|
||||
return
|
||||
var/chosen_sound = pick(migo_sounds)
|
||||
playsound(src, chosen_sound, 50, TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/netherworld/migo/Life()
|
||||
..()
|
||||
if(stat)
|
||||
return
|
||||
if(prob(10))
|
||||
var/chosen_sound = pick(migo_sounds)
|
||||
playsound(src, chosen_sound, 50, TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/netherworld/blankbody
|
||||
name = "blank body"
|
||||
desc = "This looks human enough, but its flesh has an ashy texture, and it's face is featureless save an eerie smile."
|
||||
icon_state = "blank-body"
|
||||
icon_living = "blank-body"
|
||||
icon_dead = "blank-dead"
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_INVALID
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 10
|
||||
attacktext = "punches"
|
||||
deathmessage = "falls apart into a fine dust."
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/nether
|
||||
name = "netherworld link"
|
||||
desc = null //see examine()
|
||||
icon_state = "nether"
|
||||
health = 50
|
||||
spawn_time = 600 //1 minute
|
||||
max_mobs = 15
|
||||
icon = 'icons/mob/nest.dmi'
|
||||
spawn_text = "crawls through"
|
||||
mob_types = list(/mob/living/simple_animal/hostile/netherworld/migo, /mob/living/simple_animal/hostile/netherworld, /mob/living/simple_animal/hostile/netherworld/blankbody)
|
||||
faction = list("nether")
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/nether/Initialize()
|
||||
.=..()
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/nether/examine(mob/user)
|
||||
..()
|
||||
if(isskeleton(user))
|
||||
to_chat(user, "A direct link to another dimension full of creatures very happy to see you. <span class='nicegreen'>You can see your house from here!</span>")
|
||||
else
|
||||
to_chat(user, "A direct link to another dimension full of creatures not very happy to see you. <span class='warning'>Entering the link would be a very bad idea.</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/nether/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(isskeleton(user))
|
||||
to_chat(user, "<span class='notice'>You don't feel like going home yet...</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] is violently pulled into the link!</span>", \
|
||||
"<span class='userdanger'>Touching the portal, you are quickly pulled through into a world of unimaginable horror!</span>")
|
||||
contents.Add(user)
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/nether/process()
|
||||
for(var/mob/living/M in contents)
|
||||
if(M)
|
||||
playsound(src, 'sound/magic/demon_consume.ogg', 50, 1)
|
||||
M.adjustBruteLoss(60)
|
||||
new /obj/effect/gibspawner/generic(get_turf(M), M)
|
||||
if(M.stat == DEAD)
|
||||
var/mob/living/simple_animal/hostile/netherworld/blankbody/blank
|
||||
blank = new(loc)
|
||||
blank.name = "[M]"
|
||||
blank.desc = "It's [M], but [M.p_their()] flesh has an ashy texture, and [M.p_their()] face is featureless save an eerie smile."
|
||||
visible_message("<span class='warning'>[M] reemerges from the link!</span>")
|
||||
qdel(M)
|
||||
@@ -54,7 +54,7 @@
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 2
|
||||
speak_emote = list("blurps")
|
||||
butcher_results = null
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/salmonmeat = 1)
|
||||
|
||||
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
|
||||
|
||||
@@ -189,35 +189,6 @@
|
||||
L.EyeBlind(4)
|
||||
return
|
||||
|
||||
//Toggle Night Vision
|
||||
/obj/effect/proc_holder/spell/targeted/night_vision
|
||||
name = "Toggle Nightvision"
|
||||
desc = "Toggle your nightvision mode."
|
||||
|
||||
charge_max = 10
|
||||
clothes_req = 0
|
||||
|
||||
message = "<span class='notice'>You toggle your night vision!</span>"
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/night_vision/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/target in targets)
|
||||
switch(target.lighting_alpha)
|
||||
if (LIGHTING_PLANE_ALPHA_VISIBLE)
|
||||
target.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
|
||||
name = "Toggle Nightvision \[More]"
|
||||
if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
|
||||
target.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
name = "Toggle Nightvision \[Full]"
|
||||
if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE)
|
||||
target.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
|
||||
name = "Toggle Nightvision \[OFF]"
|
||||
else
|
||||
target.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
|
||||
name = "Toggle Nightvision \[ON]"
|
||||
target.update_sight()
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/sentience_act()
|
||||
faction -= "neutral"
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ var/global/list/ts_spiderling_list = list()
|
||||
var/obj/machinery/door/airlock/A = target
|
||||
if(A.density)
|
||||
try_open_airlock(A)
|
||||
else if(isliving(target))
|
||||
else if(isliving(target) && (!client || a_intent == INTENT_HARM))
|
||||
var/mob/living/G = target
|
||||
if(issilicon(G))
|
||||
G.attack_animal(src)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
desc = "A thick vine, painful to the touch."
|
||||
|
||||
|
||||
/obj/effect/ebeam/vine/Crossed(atom/movable/AM)
|
||||
/obj/effect/ebeam/vine/Crossed(atom/movable/AM, oldloc)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!("vines" in L.faction))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
var/max_mobs = 5
|
||||
var/spawn_delay = 0
|
||||
var/spawn_time = 300 //30 seconds default
|
||||
var/mob_type = /mob/living/simple_animal/hostile/carp
|
||||
var/mob_types = list(/mob/living/simple_animal/hostile/carp)
|
||||
var/spawn_text = "emerges from"
|
||||
status_flags = 0
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
@@ -39,7 +39,8 @@
|
||||
if(spawn_delay > world.time)
|
||||
return 0
|
||||
spawn_delay = world.time + spawn_time
|
||||
var/mob/living/simple_animal/L = new mob_type(src.loc)
|
||||
var/chosen_type = pick(mob_types)
|
||||
var/mob/living/simple_animal/L = new chosen_type(loc)
|
||||
L.admin_spawned = admin_spawned //If we were admin spawned, lets have our children count as that as well.
|
||||
spawned_mobs += L
|
||||
L.nest = src
|
||||
@@ -51,7 +52,7 @@
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "syndbeacon"
|
||||
spawn_text = "warps in from"
|
||||
mob_type = /mob/living/simple_animal/hostile/syndicate/ranged
|
||||
mob_types = list(/mob/living/simple_animal/hostile/syndicate/ranged)
|
||||
faction = list("syndicate")
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/mining
|
||||
@@ -64,21 +65,21 @@
|
||||
max_mobs = 3
|
||||
icon = 'icons/mob/nest.dmi'
|
||||
spawn_text = "crawls out of"
|
||||
mob_type = /mob/living/simple_animal/hostile/asteroid/goldgrub
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub)
|
||||
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)
|
||||
faction = list("mining")
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/mining/goliath
|
||||
name = "goliath den"
|
||||
desc = "A den housing a nest of goliaths, oh god why?"
|
||||
mob_type = /mob/living/simple_animal/hostile/asteroid/goliath
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath)
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/mining/hivelord
|
||||
name = "hivelord den"
|
||||
desc = "A den housing a nest of hivelords."
|
||||
mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord)
|
||||
|
||||
/mob/living/simple_animal/hostile/spawner/mining/basilisk
|
||||
name = "basilisk den"
|
||||
desc = "A den housing a nest of basilisks, bring a coat."
|
||||
mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk)
|
||||
|
||||
+27
-4
@@ -2,6 +2,7 @@
|
||||
GLOB.mob_list -= src
|
||||
GLOB.dead_mob_list -= src
|
||||
GLOB.living_mob_list -= src
|
||||
focus = null
|
||||
QDEL_NULL(hud_used)
|
||||
if(mind && mind.current == src)
|
||||
spellremove(src)
|
||||
@@ -30,6 +31,7 @@
|
||||
GLOB.dead_mob_list += src
|
||||
else
|
||||
GLOB.living_mob_list += src
|
||||
set_focus(src)
|
||||
prepare_huds()
|
||||
..()
|
||||
|
||||
@@ -50,7 +52,6 @@
|
||||
/mob/proc/GetAltName()
|
||||
return ""
|
||||
|
||||
|
||||
/mob/proc/Cell()
|
||||
set category = "Admin"
|
||||
set hidden = 1
|
||||
@@ -173,6 +174,7 @@
|
||||
return 0
|
||||
|
||||
/mob/proc/Life(seconds, times_fired)
|
||||
set waitfor = FALSE
|
||||
if(forced_look)
|
||||
if(!isnum(forced_look))
|
||||
var/atom/A = locateUID(forced_look)
|
||||
@@ -691,9 +693,13 @@ var/list/slot_equipment_priority = list( \
|
||||
|
||||
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
|
||||
msg = sanitize_simple(html_encode(msg), list("\n" = "<BR>"))
|
||||
|
||||
if(mind)
|
||||
|
||||
var/combined = length(memory + msg)
|
||||
if(mind && (combined < MAX_PAPER_MESSAGE_LEN))
|
||||
mind.store_memory(msg)
|
||||
else if(combined >= MAX_PAPER_MESSAGE_LEN)
|
||||
to_chat(src, "Your brain can't hold that much information!")
|
||||
return
|
||||
else
|
||||
to_chat(src, "The game appears to have misplaced your mind datum, so we can't show you your notes.")
|
||||
|
||||
@@ -988,6 +994,9 @@ var/list/slot_equipment_priority = list( \
|
||||
|
||||
statpanel("Status") // Switch to the Status panel again, for the sake of the lazy Stat procs
|
||||
|
||||
if(client && client.statpanel == "Status" && SSticker)
|
||||
show_stat_station_time()
|
||||
|
||||
// this function displays the station time in the status panel
|
||||
/mob/proc/show_stat_station_time()
|
||||
stat(null, "Round Time: [worldtime2text()]")
|
||||
@@ -1361,5 +1370,19 @@ var/list/slot_equipment_priority = list( \
|
||||
/mob/proc/sync_lighting_plane_alpha()
|
||||
if(hud_used)
|
||||
var/obj/screen/plane_master/lighting/L = hud_used.plane_masters["[LIGHTING_PLANE]"]
|
||||
if (L)
|
||||
if(L)
|
||||
L.alpha = lighting_alpha
|
||||
|
||||
sync_nightvision_screen() //Sync up the overlay used for nightvision to the amount of see_in_dark a mob has. This needs to be called everywhere sync_lighting_plane_alpha() is.
|
||||
|
||||
/mob/proc/sync_nightvision_screen()
|
||||
var/obj/screen/fullscreen/see_through_darkness/S = screens["see_through_darkness"]
|
||||
if(S)
|
||||
var/suffix = ""
|
||||
switch(see_in_dark)
|
||||
if(3 to 8)
|
||||
suffix = "_[see_in_dark]"
|
||||
if(8 to INFINITY)
|
||||
suffix = "_8"
|
||||
|
||||
S.icon_state = "[initial(S.icon_state)][suffix]"
|
||||
|
||||
@@ -399,9 +399,6 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
|
||||
set name = "Rest"
|
||||
set category = "IC"
|
||||
|
||||
if(world.time < client.move_delay)
|
||||
return
|
||||
|
||||
if(!resting)
|
||||
client.move_delay = world.time + 20
|
||||
to_chat(src, "<span class='notice'>You are now resting.</span>")
|
||||
@@ -485,6 +482,8 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
|
||||
if(A)
|
||||
if(O.client.prefs && O.client.prefs.UI_style)
|
||||
A.icon = ui_style2icon(O.client.prefs.UI_style)
|
||||
if(title)
|
||||
A.name = title
|
||||
A.desc = message
|
||||
A.action = action
|
||||
A.target = source
|
||||
@@ -568,9 +567,9 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
|
||||
|
||||
for(var/i=1,i<=3,i++) //we get 3 attempts to pick a suitable name.
|
||||
if(force)
|
||||
newname = input(src, "Pick a new name.", "Name Change", oldname) as text
|
||||
newname = clean_input("Pick a new name.", "Name Change", oldname, src)
|
||||
else
|
||||
newname = input(src, "You are a [role]. Would you like to change your name to something else? (You have 3 minutes to select a new name.)", "Name Change", oldname) as text
|
||||
newname = clean_input("You are a [role]. Would you like to change your name to something else? (You have 3 minutes to select a new name.)", "Name Change", oldname, src)
|
||||
if(((world.time - time_passed) > 1800) && !force)
|
||||
alert(src, "Unfortunately, more than 3 minutes have passed for selecting your name. If you are a robot, use the Namepick verb; otherwise, adminhelp.", "Name Change")
|
||||
return //took too long
|
||||
@@ -641,5 +640,26 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
|
||||
// Cast to 1/0
|
||||
return !!(client.prefs.toggles & toggleflag)
|
||||
|
||||
// Used to make sure that a player has a valid job preference setup, used to knock players out of eligibility for anything if their prefs don't make sense.
|
||||
// A "valid job preference setup" in this situation means at least having one job set to low, or not having "return to lobby" enabled
|
||||
// Prevents "antag rolling" by setting antag prefs on, all jobs to never, and "return to lobby if preferences not availible"
|
||||
// Doing so would previously allow you to roll for antag, then send you back to lobby if you didn't get an antag role
|
||||
// This also does some admin notification and logging as well
|
||||
/mob/proc/has_valid_preferences()
|
||||
if(!client)
|
||||
return FALSE //Not sure how this would get run without the mob having a client, but let's just be safe.
|
||||
if(client.prefs.alternate_option != RETURN_TO_LOBBY)
|
||||
return TRUE
|
||||
// If they have antags enabled, they're potentially doing this on purpose instead of by accident. Notify admins if so.
|
||||
var/has_antags = FALSE
|
||||
if(client.prefs.be_special.len > 0)
|
||||
has_antags = TRUE
|
||||
if(!client.prefs.check_any_job())
|
||||
to_chat(src, "<span class='danger'>You have no jobs enabled, along with return to lobby if job is unavailable. This makes you ineligible for any round start role, please update your job preferences.</span>")
|
||||
if(has_antags)
|
||||
log_admin("[src.ckey] just got booted back to lobby with no jobs, but antags enabled.")
|
||||
message_admins("[src.ckey] just got booted back to lobby with no jobs enabled, but antag rolling enabled. Likely antag rolling abuse.")
|
||||
return FALSE //This is the only case someone should actually be completely blocked from antag rolling as well
|
||||
return TRUE
|
||||
|
||||
#define isterrorspider(A) (istype((A), /mob/living/simple_animal/hostile/poison/terror_spider))
|
||||
|
||||
+145
-105
@@ -15,102 +15,6 @@
|
||||
return 1
|
||||
return (!mover.density || !density || lying)
|
||||
|
||||
//The byond version of these verbs wait for the next tick before acting.
|
||||
// instant verbs however can run mid tick or even during the time between ticks.
|
||||
#define DO_MOVE(this_dir) var/final_dir = turn(this_dir, -dir2angle(dir)); Move(get_step(mob, final_dir), final_dir);
|
||||
|
||||
/client/verb/moveup()
|
||||
set name = ".moveup"
|
||||
set instant = 1
|
||||
DO_MOVE(NORTH)
|
||||
|
||||
/client/verb/movedown()
|
||||
set name = ".movedown"
|
||||
set instant = 1
|
||||
DO_MOVE(SOUTH)
|
||||
|
||||
/client/verb/moveright()
|
||||
set name = ".moveright"
|
||||
set instant = 1
|
||||
DO_MOVE(EAST)
|
||||
|
||||
/client/verb/moveleft()
|
||||
set name = ".moveleft"
|
||||
set instant = 1
|
||||
DO_MOVE(WEST)
|
||||
|
||||
#undef DO_MOVE
|
||||
|
||||
/client/Northeast()
|
||||
swap_hand()
|
||||
return
|
||||
|
||||
|
||||
/client/Southeast()
|
||||
attack_self()
|
||||
return
|
||||
|
||||
|
||||
/client/Southwest()
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
C.toggle_throw_mode()
|
||||
else if(isrobot(usr))
|
||||
var/mob/living/silicon/robot/R = usr
|
||||
var/module = R.get_selected_module()
|
||||
if(!module)
|
||||
to_chat(usr, "<span class='warning'>You have no module selected.</span>")
|
||||
return
|
||||
R.cycle_modules()
|
||||
R.uneq_numbered(module)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>This mob type cannot throw items.</span>")
|
||||
return
|
||||
|
||||
|
||||
/client/Northwest()
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
if(!C.get_active_hand())
|
||||
to_chat(usr, "<span class='warning'>You have nothing to drop in your hand.</span>")
|
||||
return
|
||||
drop_item()
|
||||
else if(isrobot(usr))
|
||||
var/mob/living/silicon/robot/R = usr
|
||||
if(!R.get_selected_module())
|
||||
to_chat(usr, "<span class='warning'>You have no module selected.</span>")
|
||||
return
|
||||
R.deselect_module(R.get_selected_module())
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>This mob type cannot drop items.</span>")
|
||||
return
|
||||
|
||||
//This gets called when you press the delete button.
|
||||
/client/verb/delete_key_pressed()
|
||||
set hidden = 1
|
||||
|
||||
if(!usr.pulling)
|
||||
to_chat(usr, "<span class='notice'>You are not pulling anything.</span>")
|
||||
return
|
||||
usr.stop_pulling()
|
||||
|
||||
/client/verb/swap_hand()
|
||||
set hidden = 1
|
||||
if(istype(mob, /mob/living/carbon))
|
||||
mob:swap_hand()
|
||||
if(istype(mob,/mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = mob
|
||||
R.cycle_modules()
|
||||
return
|
||||
|
||||
|
||||
|
||||
/client/verb/attack_self()
|
||||
set hidden = 1
|
||||
if(mob)
|
||||
mob.mode()
|
||||
return
|
||||
|
||||
|
||||
/client/verb/toggle_throw_mode()
|
||||
set hidden = 1
|
||||
@@ -128,7 +32,7 @@
|
||||
return
|
||||
|
||||
|
||||
/client/Center()
|
||||
/* /client/Center()
|
||||
/* No 3D movement in 2D spessman game. dir 16 is Z Up
|
||||
if(isobj(mob.loc))
|
||||
var/obj/O = mob.loc
|
||||
@@ -136,7 +40,7 @@
|
||||
return O.relaymove(mob, 16)
|
||||
*/
|
||||
return
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/client/proc/Move_object(direct)
|
||||
@@ -155,11 +59,17 @@
|
||||
/client/Move(n, direct)
|
||||
if(world.time < move_delay)
|
||||
return
|
||||
else
|
||||
next_move_dir_add = 0
|
||||
next_move_dir_sub = 0
|
||||
var/old_move_delay = move_delay
|
||||
move_delay = world.time + world.tick_lag //this is here because Move() can now be called multiple times per tick
|
||||
if(!mob || !mob.loc)
|
||||
return 0
|
||||
|
||||
if(!n || !direct) // why did we never check this before?
|
||||
return FALSE
|
||||
|
||||
if(mob.notransform)
|
||||
return 0 //This is sota the goto stop mobs from moving var
|
||||
|
||||
@@ -226,9 +136,9 @@
|
||||
moving = 1
|
||||
var/delay = mob.movement_delay()
|
||||
if(old_move_delay + (delay * MOVEMENT_DELAY_BUFFER_DELTA) + MOVEMENT_DELAY_BUFFER > world.time)
|
||||
move_delay = old_move_delay + delay
|
||||
move_delay = old_move_delay
|
||||
else
|
||||
move_delay = delay + world.time
|
||||
move_delay = world.time
|
||||
mob.last_movement = world.time
|
||||
|
||||
if(locate(/obj/item/grab, mob))
|
||||
@@ -264,19 +174,29 @@
|
||||
return
|
||||
|
||||
else if(mob.confused)
|
||||
step(mob, pick(cardinal))
|
||||
else
|
||||
. = ..()
|
||||
var/newdir = 0
|
||||
if(mob.confused > 40)
|
||||
newdir = pick(alldirs)
|
||||
else if(prob(mob.confused * 1.5))
|
||||
newdir = angle2dir(dir2angle(direct) + pick(90, -90))
|
||||
else if(prob(mob.confused * 3))
|
||||
newdir = angle2dir(dir2angle(direct) + pick(45, -45))
|
||||
if(newdir)
|
||||
direct = newdir
|
||||
n = get_step(mob, direct)
|
||||
|
||||
. = ..()
|
||||
mob.setDir(direct)
|
||||
|
||||
for(var/obj/item/grab/G in mob)
|
||||
if(G.state == GRAB_NECK)
|
||||
mob.setDir(reverse_dir[direct])
|
||||
mob.setDir(angle2dir((dir2angle(direct) + 202.5) % 365))
|
||||
G.adjust_position()
|
||||
for(var/obj/item/grab/G in mob.grabbed_by)
|
||||
G.adjust_position()
|
||||
|
||||
if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully
|
||||
delay = mob.movement_delay() * 2
|
||||
move_delay += delay
|
||||
moving = 0
|
||||
if(mob && .)
|
||||
if(mob.throwing)
|
||||
@@ -461,3 +381,123 @@
|
||||
|
||||
/mob/proc/update_gravity()
|
||||
return
|
||||
/client/proc/check_has_body_select()
|
||||
return mob && mob.hud_used && mob.zone_sel && istype(mob.zone_sel, /obj/screen/zone_sel)
|
||||
|
||||
/client/verb/body_toggle_head()
|
||||
set name = "body-toggle-head"
|
||||
set hidden = 1
|
||||
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/next_in_line
|
||||
switch(mob.zone_sel.selecting)
|
||||
if(BODY_ZONE_HEAD)
|
||||
next_in_line = BODY_ZONE_PRECISE_EYES
|
||||
if(BODY_ZONE_PRECISE_EYES)
|
||||
next_in_line = BODY_ZONE_PRECISE_MOUTH
|
||||
else
|
||||
next_in_line = BODY_ZONE_HEAD
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.zone_sel
|
||||
selector.set_selected_zone(next_in_line, mob)
|
||||
|
||||
/client/verb/body_r_arm()
|
||||
set name = "body-r-arm"
|
||||
set hidden = 1
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/next_in_line
|
||||
if(mob.zone_sel.selecting == BODY_ZONE_R_ARM)
|
||||
next_in_line = BODY_ZONE_PRECISE_R_HAND
|
||||
else
|
||||
next_in_line = BODY_ZONE_R_ARM
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.zone_sel
|
||||
selector.set_selected_zone(next_in_line, mob)
|
||||
|
||||
/client/verb/body_chest()
|
||||
set name = "body-chest"
|
||||
set hidden = 1
|
||||
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.zone_sel
|
||||
selector.set_selected_zone(BODY_ZONE_CHEST, mob)
|
||||
|
||||
/client/verb/body_l_arm()
|
||||
set name = "body-l-arm"
|
||||
set hidden = 1
|
||||
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/next_in_line
|
||||
if(mob.zone_sel.selecting == BODY_ZONE_L_ARM)
|
||||
next_in_line = BODY_ZONE_PRECISE_L_HAND
|
||||
else
|
||||
next_in_line = BODY_ZONE_L_ARM
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.zone_sel
|
||||
selector.set_selected_zone(next_in_line, mob)
|
||||
|
||||
/client/verb/body_r_leg()
|
||||
set name = "body-r-leg"
|
||||
set hidden = 1
|
||||
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/next_in_line
|
||||
if(mob.zone_sel.selecting == BODY_ZONE_R_LEG)
|
||||
next_in_line = BODY_ZONE_PRECISE_R_FOOT
|
||||
else
|
||||
next_in_line = BODY_ZONE_R_LEG
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.zone_sel
|
||||
selector.set_selected_zone(next_in_line, mob)
|
||||
|
||||
/client/verb/body_groin()
|
||||
set name = "body-groin"
|
||||
set hidden = 1
|
||||
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.zone_sel
|
||||
selector.set_selected_zone(BODY_ZONE_PRECISE_GROIN, mob)
|
||||
|
||||
/client/verb/body_l_leg()
|
||||
set name = "body-l-leg"
|
||||
set hidden = 1
|
||||
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/next_in_line
|
||||
if(mob.zone_sel.selecting == BODY_ZONE_L_LEG)
|
||||
next_in_line = BODY_ZONE_PRECISE_L_FOOT
|
||||
else
|
||||
next_in_line = BODY_ZONE_L_LEG
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.zone_sel
|
||||
selector.set_selected_zone(next_in_line, mob)
|
||||
|
||||
/client/verb/toggle_walk_run()
|
||||
set name = "toggle-walk-run"
|
||||
set hidden = TRUE
|
||||
set instant = TRUE
|
||||
if(mob)
|
||||
mob.toggle_move_intent(usr)
|
||||
|
||||
/mob/proc/toggle_move_intent(mob/user)
|
||||
if(m_intent == MOVE_INTENT_RUN)
|
||||
m_intent = MOVE_INTENT_WALK
|
||||
else
|
||||
m_intent = MOVE_INTENT_RUN
|
||||
if(hud_used && hud_used.static_inventory)
|
||||
for(var/obj/screen/mov_intent/selector in hud_used.static_inventory)
|
||||
selector.update_icon(src)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
return
|
||||
|
||||
if(!new_type)
|
||||
new_type = input("Mob type path:", "Mob type") as text|null
|
||||
new_type = clean_input("Mob type path:", "Mob type")
|
||||
|
||||
if(istext(new_type))
|
||||
new_type = text2path(new_type)
|
||||
|
||||
@@ -136,8 +136,6 @@
|
||||
..()
|
||||
|
||||
statpanel("Status")
|
||||
if(client.statpanel == "Status" && SSticker)
|
||||
show_stat_station_time()
|
||||
|
||||
|
||||
/mob/new_player/Topic(href, href_list[])
|
||||
|
||||
@@ -169,7 +169,10 @@
|
||||
/datum/sprite_accessory/underwear
|
||||
icon = 'icons/mob/underwear.dmi'
|
||||
species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/underwear.dmi')
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/underwear.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/underwear.dmi'
|
||||
)
|
||||
gender = NEUTER
|
||||
|
||||
/datum/sprite_accessory/underwear/nude
|
||||
@@ -296,7 +299,9 @@
|
||||
/datum/sprite_accessory/undershirt
|
||||
icon = 'icons/mob/underwear.dmi'
|
||||
species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/underwear.dmi')
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/underwear.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/underwear.dmi')
|
||||
gender = NEUTER
|
||||
|
||||
/datum/sprite_accessory/undershirt/nude
|
||||
|
||||
Reference in New Issue
Block a user