This commit is contained in:
Seris02
2020-02-22 19:54:10 +08:00
701 changed files with 12663 additions and 5550 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
var/preferred_form = null
if(IsAdminGhost(src))
has_unlimited_silicon_privilege = 1
silicon_privileges = ALL
if(client.prefs.unlock_content)
preferred_form = client.prefs.ghost_form
+10 -12
View File
@@ -55,7 +55,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
var/deadchat_name
var/datum/spawners_menu/spawners_menu
/mob/dead/observer/Initialize()
/mob/dead/observer/Initialize(mapload, mob/body)
set_invisibility(GLOB.observer_default_invisibility)
verbs += list(
@@ -76,11 +76,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
updateallghostimages()
var/turf/T
var/mob/body = loc
if(ismob(body))
T = get_turf(body) //Where is the body located?
if(body)
gender = body.gender
if(body.mind && body.mind.name)
name = body.mind.name
@@ -105,14 +101,15 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
update_icon()
if(!T)
if(!isturf(loc))
var/turf/T
var/list/turfs = get_area_turfs(/area/shuttle/arrival)
if(turfs.len)
T = pick(turfs)
else
T = SSmapping.get_station_center()
forceMove(T)
forceMove(T)
if(!name) //To prevent nameless ghosts
name = random_unique_name(gender)
@@ -196,13 +193,13 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
else
ghostimage_default.icon_state = new_form
if(ghost_accs >= GHOST_ACCS_DIR && icon_state in GLOB.ghost_forms_with_directions_list) //if this icon has dirs AND the client wants to show them, we make sure we update the dir on movement
if(ghost_accs >= GHOST_ACCS_DIR && (icon_state in GLOB.ghost_forms_with_directions_list)) //if this icon has dirs AND the client wants to show them, we make sure we update the dir on movement
updatedir = 1
else
updatedir = 0 //stop updating the dir in case we want to show accessories with dirs on a ghost sprite without dirs
setDir(2 )//reset the dir to its default so the sprites all properly align up
if(ghost_accs == GHOST_ACCS_FULL && icon_state in GLOB.ghost_forms_with_accessories_list) //check if this form supports accessories and if the client wants to show them
if(ghost_accs == GHOST_ACCS_FULL && (icon_state in GLOB.ghost_forms_with_accessories_list)) //check if this form supports accessories and if the client wants to show them
var/datum/sprite_accessory/S
if(facial_hair_style)
S = GLOB.facial_hair_styles_list[facial_hair_style]
@@ -268,7 +265,7 @@ Works together with spawning an observer, noted above.
if(!key || key[1] == "@" || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING))
return //mob has no key, is an aghost or some component hijacked.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
var/mob/dead/observer/ghost = new(get_turf(src), src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
if (client && client.prefs && client.prefs.auto_ooc)
@@ -310,8 +307,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/obj/machinery/cryopod/C = loc
C.despawn_occupant()
else
ghostize(0, penalize = TRUE, voluntary = TRUE) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
suicide_log(TRUE)
ghostize(FALSE, penalize = TRUE, voluntary = TRUE) //FALSE parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
/mob/camera/verb/ghost()
set category = "OOC"
+25 -2
View File
@@ -3,7 +3,7 @@
/mob/living/carbon/Initialize()
. = ..()
create_reagents(1000)
create_reagents(1000, NONE, NO_REAGENTS_VALUE)
update_body_parts() //to update the carbon's new bodyparts appearance
GLOB.carbon_list += src
blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio)
@@ -841,12 +841,31 @@
update_inv_handcuffed()
update_hud_handcuffed()
/mob/living/carbon/proc/can_defib()
var/tlimit = DEFIB_TIME_LIMIT * 10
var/obj/item/organ/heart = getorgan(/obj/item/organ/heart)
if(suiciding || hellbound || HAS_TRAIT(src, TRAIT_HUSK))
return
if((world.time - timeofdeath) > tlimit)
return
if((getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
return
if(!heart || (heart.organ_flags & ORGAN_FAILING))
return
var/obj/item/organ/brain/BR = getorgan(/obj/item/organ/brain)
if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || suiciding)
return
return TRUE
/mob/living/carbon/fully_heal(admin_revive = FALSE)
if(reagents)
reagents.clear_reagents()
var/obj/item/organ/brain/B = getorgan(/obj/item/organ/brain)
if(B)
B.brain_death = FALSE
for(var/O in internal_organs)
var/obj/item/organ/organ = O
organ.setOrganDamage(0)
for(var/thing in diseases)
var/datum/disease/D = thing
if(D.severity != DISEASE_SEVERITY_POSITIVE)
@@ -859,7 +878,8 @@
qdel(R)
update_handcuffed()
if(reagents)
reagents.addiction_list = list()
for(var/addi in reagents.addiction_list)
reagents.remove_addiction(addi)
cure_all_traumas(TRAUMA_RESILIENCE_MAGIC)
..()
// heal ears after healing traits, since ears check TRAIT_DEAF trait
@@ -994,3 +1014,6 @@
return TRUE
if(isclothing(wear_mask) && (wear_mask.clothing_flags & SCAN_REAGENTS))
return TRUE
/mob/living/carbon/can_hold_items()
return TRUE
@@ -1,6 +1,7 @@
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
var/hit_percent = (100-blocked)/100
if(!forced && hit_percent <= 0)
return 0
@@ -394,10 +394,10 @@
if(invisible_man)
. += "...?"
else
var/flavor = print_flavor_text()
var/flavor = print_flavor_text(flavor_text)
if(flavor)
. += flavor
var/temp_flavor = print_flavor_text_2()
var/temp_flavor = print_flavor_text(flavor_text_2)
if(temp_flavor)
. += temp_flavor
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
@@ -9,6 +9,8 @@
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
verbs += /mob/living/carbon/human/proc/underwear_toggle //fwee
verbs += /mob/proc/set_flavor
verbs += /mob/proc/set_flavor_2
//initialize limbs first
create_bodyparts()
@@ -801,7 +803,7 @@
hud_used.staminas?.update_icon_state()
hud_used.staminabuffer?.update_icon_state()
/mob/living/carbon/human/fully_heal(admin_revive = 0)
/mob/living/carbon/human/fully_heal(admin_revive = FALSE)
if(admin_revive)
regenerate_limbs()
regenerate_organs()
@@ -821,9 +823,6 @@
. += dna.species.check_weakness(weapon, attacker)
/mob/living/carbon/human/is_literate()
return 1
/mob/living/carbon/human/can_hold_items()
return TRUE
/mob/living/carbon/human/update_gravity(has_gravity,override = 0)
@@ -832,7 +831,7 @@
..()
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0)
if(blood && (NOBLOOD in dna.species.species_traits))
if(blood && dna?.species && (NOBLOOD in dna.species.species_traits))
if(message)
visible_message("<span class='warning'>[src] dry heaves!</span>", \
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
@@ -20,7 +20,7 @@
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, d_type)
if(!d_type)
if(!d_type || !def_zone)
return 0
var/protection = 0
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
@@ -1273,10 +1273,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.update_mutant_bodyparts()
/datum/species/proc/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.type == exotic_blood)
if(chem.type == exotic_blood && !istype(exotic_blood, /datum/reagent/blood))
H.blood_volume = min(H.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM)
H.reagents.del_reagent(chem.type)
return 1
return TRUE
return FALSE
/datum/species/proc/check_weakness(obj/item, mob/living/attacker)
@@ -1933,6 +1933,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
log_combat(user, target, "shoved", append_message)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
var/hit_percent = (100-(blocked+armor))/100
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
if(!forced && hit_percent <= 0)
@@ -135,7 +135,7 @@
RegisterSignal(owner, COMSIG_CLICK_SHIFT, .proc/examinate_check)
RegisterSignal(src, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner)
RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head)
RegisterSignal(owner, COMSIG_LIVING_FULLY_HEAL, .proc/retrieve_head)
RegisterSignal(owner, COMSIG_LIVING_REVIVE, .proc/retrieve_head)
/obj/item/dullahan_relay/proc/examinate_check(atom/source, mob/user)
if(user.client.eye == src)
@@ -148,8 +148,9 @@
/obj/item/dullahan_relay/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs)
excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs.
/obj/item/dullahan_relay/proc/retrieve_head(datum/source, admin_revive = FALSE)
if(admin_revive) //retrieving the owner's head for ahealing purposes.
//Retrieving the owner's head for better ahealing.
/obj/item/dullahan_relay/proc/retrieve_head(datum/source, full_heal, admin_revive)
if(admin_revive)
var/obj/item/bodypart/head/H = loc
var/turf/T = get_turf(owner)
if(H && istype(H) && T && !(H in owner.GetAllContents()))
@@ -13,22 +13,23 @@
exotic_bloodtype = "BUG"
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.type == /datum/reagent/toxin/pestkiller)
if(istype(chem, /datum/reagent/toxin/pestkiller))
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
return 1
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(istype(chem, /datum/reagent/consumable))
return TRUE
else if(istype(chem, /datum/reagent/consumable))
var/datum/reagent/consumable/nutri_check = chem
if(nutri_check.nutriment_factor > 0)
var/turf/pos = get_turf(H)
H.vomit(0, FALSE, FALSE, 2, TRUE)
var/obj/effect/decal/cleanable/vomit/V = locate() in pos
if(V)
H.reagents.trans_id_to(V, chem, chem.volume)
playsound(pos, 'sound/effects/splat.ogg', 50, 1)
H.visible_message("<span class='danger'>[H] vomits on the floor!</span>", \
"<span class='userdanger'>You throw up on the floor!</span>")
..()
return TRUE
return ..()
/datum/species/fly/check_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/melee/flyswatter))
@@ -308,7 +308,8 @@
if(chem.type == /datum/reagent/toxin/plantbgone)
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
return 1
return TRUE
return ..()
//Radioactive
/datum/species/golem/uranium
@@ -622,12 +623,11 @@
if(chem.type == /datum/reagent/water/holywater)
H.adjustFireLoss(4)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
if(chem.type == /datum/reagent/fuel/unholywater)
else if(chem.type == /datum/reagent/fuel/unholywater)
H.adjustBruteLoss(-4)
H.adjustFireLoss(-4)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
return ..()
/datum/species/golem/clockwork
name = "Clockwork Golem"
@@ -57,6 +57,7 @@
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
return TRUE
return ..()
/datum/species/mush/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
forced_colour = FALSE
@@ -50,7 +50,8 @@
if(chem.type == /datum/reagent/toxin/plantbgone)
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
return 1
return TRUE
return ..()
/datum/species/pod/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
switch(P.type)
@@ -70,14 +71,42 @@
if(/obj/item/projectile/energy/florayield)
H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL)
/datum/species/pod/pseudo_weak
name = "Anthromorphic Plant"
id = "podweak"
limbs_id = "pod"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur", "legs")
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs")
limbs_id = "pod"
light_nutrition_gain_factor = 7.5
light_bruteheal = 0.2
light_burnheal = 0.2
light_toxheal = 0.7
/datum/species/pod/pseudo_weak/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
stop_wagging_tail(H)
/datum/species/pod/pseudo_weak/spec_stun(mob/living/carbon/human/H,amount)
if(H)
stop_wagging_tail(H)
. = ..()
/datum/species/pod/pseudo_weak/can_wag_tail(mob/living/carbon/human/H)
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
/datum/species/pod/pseudo_weak/is_wagging_tail(mob/living/carbon/human/H)
return ("mam_waggingtail" in mutant_bodyparts)
/datum/species/pod/pseudo_weak/start_wagging_tail(mob/living/carbon/human/H)
if("mam_tail" in mutant_bodyparts)
mutant_bodyparts -= "mam_tail"
mutant_bodyparts |= "mam_waggingtail"
H.update_body()
/datum/species/pod/pseudo_weak/stop_wagging_tail(mob/living/carbon/human/H)
if("mam_waggingtail" in mutant_bodyparts)
mutant_bodyparts -= "mam_waggingtail"
mutant_bodyparts |= "mam_tail"
H.update_body()
@@ -213,6 +213,16 @@
PDA.f_lum = 0
PDA.update_icon()
visible_message("<span class='danger'>The light in [PDA] shorts out!</span>")
else if(istype(O, /obj/item/gun))
var/obj/item/gun/weapon = O
if(weapon.gun_light)
var/obj/item/flashlight/seclite/light = weapon.gun_light
light.forceMove(get_turf(weapon))
light.burn()
weapon.gun_light = null
weapon.update_gunlight()
QDEL_NULL(weapon.alight)
visible_message("<span class='danger'>[light] on [O] flickers out and disintegrates!</span>")
else
visible_message("<span class='danger'>[O] is disintegrated by [src]!</span>")
O.burn()
@@ -39,9 +39,8 @@
if(chem.type == /datum/reagent/medicine/synthflesh)
chem.reaction_mob(H, TOUCH, 2 ,0) //heal a little
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
return 1
else
return ..()
return TRUE
return ..()
/datum/species/synth/proc/assume_disguise(datum/species/S, mob/living/carbon/human/H)
+1 -1
View File
@@ -72,7 +72,7 @@
put_in_hands(I)
update_inv_hands()
if(SLOT_IN_BACKPACK)
if(!SEND_SIGNAL(back, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE))
if(!back || !SEND_SIGNAL(back, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE))
not_handled = TRUE
else
not_handled = TRUE
+4 -4
View File
@@ -357,12 +357,12 @@
if(istype(loc, /obj/structure/closet/crate/coffin)|| istype(loc, /obj/structure/closet/body_bag) || istype(loc, /obj/structure/bodycontainer))
return
// No decay if formaldehyde in corpse or when the corpse is charred
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || HAS_TRAIT(src, TRAIT_HUSK))
// No decay if formaldehyde/preservahyde in corpse or when the corpse is charred
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || HAS_TRAIT(src, TRAIT_HUSK) || reagents.has_reagent(/datum/reagent/preservahyde, 1))
return
// Also no decay if corpse chilled or not organic/undead
if(bodytemperature <= T0C-10 || (!(MOB_ORGANIC in mob_biotypes) && !(MOB_UNDEAD in mob_biotypes)))
if((bodytemperature <= T0C-10) || !(mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)))
return
// Wait a bit before decaying
@@ -397,7 +397,7 @@
if(O)
O.on_life()
else
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1)) // No organ decay if the body contains formaldehyde.
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || reagents.has_reagent(/datum/reagent/preservahyde, 1)) // No organ decay if the body contains formaldehyde. Or preservahyde.
return
for(var/V in internal_organs)
var/obj/item/organ/O = V
+1 -1
View File
@@ -25,7 +25,7 @@
/mob/living/proc/spawn_gibs(with_bodyparts, atom/loc_override)
var/location = loc_override ? loc_override.drop_location() : drop_location()
if(MOB_ROBOTIC in mob_biotypes)
if(mob_biotypes & MOB_ROBOTIC)
new /obj/effect/gibspawner/robot(location, src, get_static_viruses())
else
new /obj/effect/gibspawner/generic(location, src, get_static_viruses())
+9 -9
View File
@@ -482,7 +482,8 @@
med_hud_set_status()
//proc used to ressuscitate a mob
/mob/living/proc/revive(full_heal = 0, admin_revive = 0)
/mob/living/proc/revive(full_heal = FALSE, admin_revive = FALSE)
SEND_SIGNAL(src, COMSIG_LIVING_REVIVE, full_heal, admin_revive)
if(full_heal)
fully_heal(admin_revive)
if(stat == DEAD && can_be_revived()) //in some cases you can't revive (e.g. no brain)
@@ -528,11 +529,6 @@
fire_stacks = 0
confused = 0
update_canmove()
var/datum/component/mood/mood = GetComponent(/datum/component/mood)
if (mood)
QDEL_LIST_ASSOC_VAL(mood.mood_events)
mood.sanity = SANITY_GREAT
mood.update_mood()
//Heal all organs
if(iscarbon(src))
var/mob/living/carbon/C = src
@@ -540,8 +536,6 @@
for(var/organ in C.internal_organs)
var/obj/item/organ/O = organ
O.setOrganDamage(0)
SEND_SIGNAL(src, COMSIG_LIVING_FULLY_HEAL, admin_revive)
//proc called by revive(), to check if we can actually ressuscitate the mob (we don't want to revive him and have him instantly die again)
/mob/living/proc/can_be_revived()
@@ -552,6 +546,12 @@
/mob/living/proc/update_damage_overlays()
return
/mob/living/Crossed(atom/movable/AM)
. = ..()
for(var/i in get_equipped_items())
var/obj/item/item = i
SEND_SIGNAL(item, COMSIG_ITEM_WEARERCROSSED, AM)
/mob/living/Move(atom/newloc, direct)
if (buckled && buckled.loc != newloc) //not updating position
if (!buckled.anchored)
@@ -1080,7 +1080,7 @@
stop_pulling() //CIT CHANGE - Ditto...
else if(has_legs || ignore_legs)
lying = 0
if (pulledby)
if (pulledby && isliving(pulledby))
var/mob/living/L = pulledby
L.update_pull_movespeed()
if(buckled)
+2 -2
View File
@@ -258,7 +258,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(M.stat != DEAD) //not dead, not important
if(yellareas) //CIT CHANGE - see above. makes yelling penetrate walls
var/area/A = get_area(M) //CIT CHANGE - ditto
if(istype(A) && A.ambientsounds != SPACE && A in yellareas) //CIT CHANGE - ditto
if(istype(A) && A.ambientsounds != SPACE && (A in yellareas)) //CIT CHANGE - ditto
listening |= M //CIT CHANGE - ditto
continue
if(!M.client || !client) //client is so that ghosts don't have to listen to mice
@@ -368,7 +368,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(message_mode == MODE_HEADSET)
imp.radio.talk_into(src, message, , spans, language)
return ITALICS | REDUCE_RANGE
if(message_mode == MODE_DEPARTMENT || message_mode in GLOB.radiochannels)
if(message_mode == MODE_DEPARTMENT || (message_mode in GLOB.radiochannels))
imp.radio.talk_into(src, message, message_mode, spans, language)
return ITALICS | REDUCE_RANGE
+2 -2
View File
@@ -2,7 +2,6 @@
name = "pAI"
icon = 'icons/mob/pai.dmi'
icon_state = "repairbot"
mouse_opacity = MOUSE_OPACITY_OPAQUE
density = FALSE
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_TINY
@@ -11,6 +10,7 @@
health = 500
maxHealth = 500
layer = BELOW_MOB_LAYER
silicon_privileges = PRIVILEDGES_PAI
var/datum/element/mob_holder/current_mob_holder //because only a few of their chassis can be actually held.
var/network = "ss13"
@@ -74,7 +74,7 @@
var/emitteroverloadcd = 100
var/radio_short = FALSE
var/radio_short_cooldown = 5 MINUTES
var/radio_short_cooldown = 3 MINUTES
var/radio_short_timerid
canmove = FALSE
@@ -56,7 +56,8 @@
if(P.stun)
fold_in(force = TRUE)
visible_message("<span class='warning'>The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!</span>")
return ..()
. = ..()
return BULLET_ACT_FORCE_PIERCE
/mob/living/silicon/pai/stripPanelUnequip(obj/item/what, mob/who, where) //prevents stripping
to_chat(src, "<span class='warning'>Your holochassis stutters and warps intensely as you attempt to interact with the object, forcing you to cease lest the field fail.</span>")
@@ -8,9 +8,9 @@
var/list/states = icon_states(icon)
icon_state = ""
if(resting) //The next line is some bullshit but I can make it worse if you want and make it a single line instead of four.. :)
if(dynamic_chassis_sit && ("sit") in states)
if(dynamic_chassis_sit && ("sit" in states))
icon_state = "sit"
else if(dynamic_chassis_bellyup && ("bellyup") in states)
else if(dynamic_chassis_bellyup && ("bellyup" in states))
icon_state = "bellyup"
else if("rest" in states)
icon_state = "rest"
@@ -97,8 +97,8 @@
var/obj/item/stack/S = I
if(is_type_in_list(S, list(/obj/item/stack/sheet/metal, /obj/item/stack/rods, /obj/item/stack/tile/plasteel)))
if(S.materials[MAT_METAL])
S.cost = S.materials[MAT_METAL] * 0.25
if(S.custom_materials?.len && S.custom_materials[getmaterialref(/datum/material/iron)])
S.cost = S.custom_materials[getmaterialref(/datum/material/iron)] * 0.25
S.source = get_or_create_estorage(/datum/robot_energy_storage/metal)
else if(istype(S, /obj/item/stack/sheet/glass))
@@ -127,7 +127,7 @@
S.source = get_or_create_estorage(/datum/robot_energy_storage/wrapping_paper)
if(S && S.source)
S.materials = list()
S.custom_materials = null
S.is_cyborg = 1
if(I.loc != src)
@@ -340,7 +340,7 @@
/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/medmodels = list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot", "Medihound", "Medihound Dark", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
if(R.client && (R.client.ckey in list("nezuli")))
medmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medmodels
if(!borg_icon)
@@ -437,7 +437,7 @@
/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
if(R.client && (R.client.ckey in list("nezuli")))
engymodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
if(!borg_icon)
@@ -515,7 +515,7 @@
/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/secmodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider", "K9", "K9 Dark", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
if(R.client && (R.client.ckey in list("nezuli")))
secmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in secmodels
if(!borg_icon)
@@ -596,8 +596,8 @@
/obj/item/robot_module/peacekeeper/do_transform_animation()
..()
to_chat(loc, "<span class='userdanger'>Under ASIMOV/CREWSIMOV, you are an enforcer of the PEACE and preventer of HUMAN/CREW HARM. \
You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.</span>")
to_chat(loc, "<span class='userdanger'>Under ASIMOV/CREWSIMOV, you are an enforcer of the PEACE. \
You are not a security module and you are expected to follow orders to the best of your abilities without causing harm. Space law means nothing to you.</span>")
/obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
+1 -1
View File
@@ -1,6 +1,6 @@
/mob/living/silicon
gender = NEUTER
has_unlimited_silicon_privilege = 1
silicon_privileges = PRIVILEDGES_SILICON
verb_say = "states"
verb_ask = "queries"
verb_exclaim = "declares"
@@ -15,7 +15,7 @@
maxbodytemp = INFINITY
minbodytemp = 0
blood_volume = 0
has_unlimited_silicon_privilege = 1
silicon_privileges = PRIVILEDGES_BOT
sentience_type = SENTIENCE_ARTIFICIAL
status_flags = NONE //no default canpush
verb_say = "states"
@@ -194,10 +194,12 @@
if(locked) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again.
locked = FALSE
emagged = 1
to_chat(user, "<span class='notice'>You bypass [src]'s controls.</span>")
if(user)
to_chat(user, "<span class='notice'>You bypass [src]'s controls.</span>")
return TRUE
if(!open)
to_chat(user, "<span class='warning'>You need to open maintenance panel first!</span>")
if(user)
to_chat(user, "<span class='warning'>You need to open maintenance panel first!</span>")
return
emagged = 2
remote_disabled = 1 //Manually emagging the bot locks out the AI built in panel.
@@ -205,7 +207,8 @@
bot_reset()
turn_on() //The bot automatically turns on when emagged, unless recently hit with EMP.
to_chat(src, "<span class='userdanger'>(#$*#$^^( OVERRIDE DETECTED</span>")
log_combat(user, src, "emagged")
if(user)
log_combat(user, src, "emagged")
return TRUE
/mob/living/simple_animal/bot/examine(mob/user)
@@ -123,7 +123,8 @@
emagged = TRUE
if(!open)
locked = !locked
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] [src]'s controls!</span>")
if(user)
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] [src]'s controls!</span>")
flick("mulebot-emagged", src)
playsound(src, "sparks", 100, FALSE)
@@ -180,7 +181,7 @@
var/list/data = list()
data["on"] = on
data["locked"] = locked
data["siliconUser"] = user.has_unlimited_silicon_privilege
data["siliconUser"] = hasSiliconAccessInArea(usr)
data["mode"] = mode ? mode_name[mode] : "Ready"
data["modeStatus"] = ""
switch(mode)
@@ -205,11 +206,12 @@
return data
/mob/living/simple_animal/bot/mulebot/ui_act(action, params)
if(..() || (locked && !usr.has_unlimited_silicon_privilege))
var/silicon_access = hasSiliconAccessInArea(usr)
if(..() || (locked && silicon_access))
return
switch(action)
if("lock")
if(usr.has_unlimited_silicon_privilege)
if(silicon_access)
locked = !locked
. = TRUE
if("power")
@@ -766,4 +768,3 @@
/obj/machinery/bot_core/mulebot
req_access = list(ACCESS_CARGO)
@@ -11,7 +11,7 @@
blood_volume = 350
speak_chance = 1
turns_per_move = 5
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1)
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/rawcrab = 1)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
@@ -41,7 +41,7 @@
bubble_icon = "machine"
initial_language_holder = /datum/language_holder/drone
mob_size = MOB_SIZE_SMALL
has_unlimited_silicon_privilege = 1
silicon_privileges = PRIVILEDGES_DRONE
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD)
unique_name = TRUE
@@ -454,7 +454,7 @@
name = "udder"
/obj/item/udder/Initialize()
create_reagents(50)
create_reagents(50, NONE, NO_REAGENTS_VALUE)
reagents.add_reagent(/datum/reagent/consumable/milk, 20)
. = ..()
@@ -0,0 +1,39 @@
/mob/living/simple_animal/hostile/dark_wizard
name = "Dark Wizard"
desc = "Killing amateurs since the dawn of times."
icon = 'icons/mob/simple_human.dmi'
icon_state = "dark_wizard"
icon_living = "dark_wizard"
move_to_delay = 10
projectiletype = /obj/item/projectile/temp/earth_bolt
projectilesound = 'sound/magic/ethereal_enter.ogg'
ranged = TRUE
ranged_message = "earth bolts"
ranged_cooldown_time = 20
maxHealth = 50
health = 50
harm_intent_damage = 5
obj_damage = 20
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "staves"
a_intent = INTENT_HARM
speak_emote = list("chants")
attack_sound = 'sound/weapons/bladeslice.ogg'
aggro_vision_range = 9
turns_per_move = 5
gold_core_spawnable = HOSTILE_SPAWN
faction = list(ROLE_WIZARD)
do_footstep = TRUE
weather_immunities = list("lava","ash")
minbodytemp = 0
maxbodytemp = INFINITY
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)
loot = list(/obj/effect/decal/remains/human)
/obj/item/projectile/temp/earth_bolt
name = "earth_bolt"
icon_state = "declone"
damage = 4
damage_type = BURN
flag = "energy"
@@ -39,8 +39,8 @@ Difficulty: Medium
ranged = 1
ranged_cooldown_time = 16
pixel_x = -16
crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator, /obj/item/crusher_trophy/miner_eye)
loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator)
crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka, /obj/item/crusher_trophy/miner_eye)
loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka)
wander = FALSE
del_on_death = TRUE
blood_volume = BLOOD_VOLUME_NORMAL
@@ -73,7 +73,7 @@ Difficulty: Medium
target.stun_absorption -= "miner"
/obj/item/projectile/kinetic/miner
damage = 20
damage = 40
speed = 0.9
icon_state = "ka_tracer"
range = MINER_DASH_RANGE
@@ -0,0 +1,91 @@
//shameless copies of carps.
/mob/living/simple_animal/hostile/shark
name = "Space Shark"
desc = "The best terror of the seas, next to the kraken."
icon_state = "shark"
icon_living = "shark"
icon = 'icons/mob/sharks.dmi'
icon_dead = "shark_dead"
icon_gib = "carp_gib"
environment_smash = 0
speak_chance = 0
turns_per_move = 3
butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 3)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "hits"
speed = 0
maxHealth = 75
health = 75
harm_intent_damage = 18
melee_damage_lower = 18
melee_damage_upper = 18
attacktext = "maims"
attack_sound = 'sound/weapons/bite.ogg'
gold_core_spawnable = 1
//Space shark aren't affected by cold.
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
maxbodytemp = 1500
faction = list("shark")
/mob/living/simple_animal/hostile/shark/Process_Spacemove(var/movement_dir = 0)
return 1 //No drifting in space for space sharks....either!
/mob/living/simple_animal/hostile/shark/FindTarget()
. = ..()
if(.)
emote("me", 1, "growls at [.]!")
/mob/living/simple_animal/hostile/shark/AttackingTarget()
. =..()
var/mob/living/carbon/L = .
if(istype(L))
if(prob(25))
L.Knockdown(20)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
/mob/living/simple_animal/hostile/shark/laser
name = "Laser-Shark"
desc = "NOW we've jumped the shark."
icon_state = "lasershark"
icon_living = "lasershark"
icon_dead = "lasershark_dead"
icon_gib = "carp_gib"
ranged = 1
retreat_distance = 3
minimum_distance = 0 //Between shots they can and will close in to nash
projectiletype = /obj/item/projectile/beam/laser/heavylaser
projectilesound = 'sound/weapons/lasercannonfire.ogg'
maxHealth = 50
health = 50
/mob/living/simple_animal/hostile/shark/kawaii
name = "Kawaii Shark"
desc = "Senpai~ Notice me.."
icon_state = "kawaiishark"
icon_living = "kawaiishark"
icon_dead = "kawaiishark_dead"
speak = list("Oh Senpai","Notice me senpai!","Oh my...","Kawaii~")
speak_emote = list("lovingly says","says")
speak_chance = 2
turns_per_move = 3
butcher_results = list(/mob/living/simple_animal/butterfly = 3)
maxHealth = 50
health = 50
maxbodytemp = INFINITY
harm_intent_damage = 0
melee_damage_lower = 0
melee_damage_upper = 0
attacktext = "violently hugs"
vision_range = 0
/mob/living/simple_animal/hostile/shark/kawaii/death()
say("Senpai, you noticed~!")
LoseAggro()
..()
walk(src, 0)
@@ -126,7 +126,7 @@
// This loop will, at most, loop twice.
for(var/atom/check in check_list)
for(var/mob/living/M in viewers(world.view + 1, check) - src)
if(M.client && CanAttack(M) && !M.has_unlimited_silicon_privilege)
if(M.client && CanAttack(M) && !M.silicon_privileges)
if(!M.eye_blind)
return M
for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you
@@ -191,7 +191,7 @@
/obj/effect/proc_holder/spell/aoe_turf/blindness/cast(list/targets,mob/user = usr)
for(var/mob/living/L in GLOB.alive_mob_list)
var/turf/T = get_turf(L.loc)
if(T && T in targets)
if(T && (T in targets))
L.blind_eyes(4)
return
@@ -467,11 +467,11 @@
return
return
if(parrot_interest && parrot_interest in view(src))
if(parrot_interest && (parrot_interest in view(src)))
parrot_state = PARROT_SWOOP | PARROT_STEAL
return
if(parrot_perch && parrot_perch in view(src))
if(parrot_perch && (parrot_perch in view(src)))
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
@@ -97,7 +97,7 @@
else
var/datum/action/innate/slime/evolve/E = new
E.Grant(src)
create_reagents(100)
create_reagents(100, NONE, NO_REAGENTS_VALUE)
set_colour(new_colour)
. = ..()
nutrition = 700
+21 -18
View File
@@ -16,21 +16,22 @@
// non destructively tastes a reagent container
/mob/living/proc/taste(datum/reagents/from)
if(last_taste_time + 50 < world.time)
var/taste_sensitivity = get_taste_sensitivity()
var/text_output = from.generate_taste_message(taste_sensitivity)
// We dont want to spam the same message over and over again at the
// person. Give it a bit of a buffer.
if(hallucination > 50 && prob(25))
text_output = pick("spiders","dreams","nightmares","the future","the past","victory",\
"defeat","pain","bliss","revenge","poison","time","space","death","life","truth","lies","justice","memory",\
"regrets","your soul","suffering","music","noise","blood","hunger","the american way")
if(text_output != last_taste_text || last_taste_time + 100 < world.time)
to_chat(src, "<span class='notice'>You can taste [text_output].</span>")
// "something indescribable" -> too many tastes, not enough flavor.
last_taste_time = world.time
last_taste_text = text_output
if(last_taste_time + 50 > world.time)
return FALSE
var/taste_sensitivity = get_taste_sensitivity()
var/text_output = from.generate_taste_message(taste_sensitivity)
// We dont want to spam the same message over and over again at the
// person. Give it a bit of a buffer.
if(hallucination > 50 && prob(25))
text_output = pick("spiders","dreams","nightmares","the future","the past","victory",\
"defeat","pain","bliss","revenge","poison","time","space","death","life","truth","lies","justice","memory",\
"regrets","your soul","suffering","music","noise","blood","hunger","the american way")
if(text_output != last_taste_text || last_taste_time + 100 < world.time)
to_chat(src, "<span class='notice'>You can taste [text_output].</span>")
// "something indescribable" -> too many tastes, not enough flavor.
last_taste_time = world.time
last_taste_text = text_output
return TRUE
//FermiChem - How to check pH of a beaker without a meter/pH paper.
//Basically checks the pH of the holder and burns your poor tongue if it's too acidic!
@@ -41,22 +42,24 @@
if (!T)
return
.=..()
if(!.)
return
if ((from.pH > 12.5) || (from.pH < 1.5))
to_chat(src, "<span class='warning'>You taste chemical burns!</span>")
T.applyOrganDamage(5)
to_chat(src, "<span class='warning'>You taste chemical burns!</span>")
if(istype(T, /obj/item/organ/tongue/cybernetic))
to_chat(src, "<span class='notice'>Your tongue moves on it's own in response to the liquid.</span>")
say("The pH is appropriately [round(from.pH, 1)].")
return
if (!HAS_TRAIT(src, TRAIT_AGEUSIA)) //I'll let you get away with not having 1 damage.
switch(from.pH)
if(11.5 to INFINITY)
if(11.5 to 12.5)
to_chat(src, "<span class='warning'>You taste a strong alkaline flavour!</span>")
if(8.5 to 11.5)
to_chat(src, "<span class='notice'>You taste a sort of soapy tone in the mixture.</span>")
if(2.5 to 5.5)
to_chat(src, "<span class='notice'>You taste a sort of acid tone in the mixture.</span>")
if(-INFINITY to 2.5)
if(1.5 to 2.5)
to_chat(src, "<span class='warning'>You taste a strong acidic flavour!</span>")
#undef DEFAULT_TASTE_SENSITIVITY
-3
View File
@@ -512,9 +512,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
usr << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", name, replacetext(flavor_text_2, "\n", "<BR>")), text("window=[];size=500x200", name))
onclose(usr, "[name]")
if(href_list["flavor_change"])
update_flavor_text()
if(href_list["refresh"])
if(machine && in_range(src, usr))
show_inv(machine)
+5 -2
View File
@@ -95,7 +95,7 @@
var/digitalinvis = 0 //Are they ivisible to the AI?
var/image/digitaldisguise = null //what does the AI see instead of them?
var/has_unlimited_silicon_privilege = 0 // Can they interact with station electronics
var/silicon_privileges = NONE // Can they interact with station electronics
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
var/atom/movable/remote_control //Calls relaymove() to whatever it is
@@ -124,4 +124,7 @@
var/siliconaccessareas = list()
var/siliconaccesstoggle = FALSE
var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted.
var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted.
var/flavor_text = ""
var/flavor_text_2 = "" //version of the above that only lasts for the current round.
+3 -3
View File
@@ -406,8 +406,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
return
return TRUE
/atom/proc/hasSiliconAccessInArea(mob/user)
return user && (issilicon(user) || (user.siliconaccesstoggle && (get_area(src) in user.siliconaccessareas)))
/atom/proc/hasSiliconAccessInArea(mob/user, flags = PRIVILEDGES_SILICON)
return user.silicon_privileges & (flags) || (user.siliconaccesstoggle && (get_area(src) in user.siliconaccessareas))
/mob/proc/toggleSiliconAccessArea(area/area)
if (area in siliconaccessareas)
@@ -555,4 +555,4 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
//Can the mob see reagents inside of containers?
/mob/proc/can_see_reagents()
return stat == DEAD || has_unlimited_silicon_privilege //Dead guys and silicons can always see reagents
return stat == DEAD || silicon_privileges //Dead guys and silicons can always see reagents
-49
View File
@@ -1,52 +1,6 @@
//////////////////////////////////////////////////////
////////////////////SUBTLE COMMAND////////////////////
//////////////////////////////////////////////////////
/mob
var/flavor_text = "" //tired of fucking double checking this
var/flavor_text_2 = ""
/mob/proc/update_flavor_text()
set src in usr
if(usr != src)
to_chat(usr, "No.")
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN, TRUE)
if(msg)
flavor_text = html_encode(msg)
/mob/proc/update_flavor_text_2()
set src in usr
if(usr != src)
to_chat(usr, "No.")
var/msg = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", html_decode(flavor_text_2), MAX_MESSAGE_LEN, TRUE)
if(msg)
flavor_text_2 = html_encode(msg)
/mob/proc/warn_flavor_changed()
if(flavor_text && flavor_text != "") // don't spam people that don't use it!
to_chat(src, "<h2 class='alert'>OOC Warning:</h2>")
to_chat(src, "<span class='alert'>Your flavor text is likely out of date! <a href='?src=[REF(src)];flavor_change=1'>Change</a></span>")
/mob/proc/print_flavor_text()
if(flavor_text && flavor_text != "")
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
var/msg = html_decode(replacetext(flavor_text, "\n", " "))
if(length_char(msg) <= 40)
return "<span class='notice'>[html_encode(msg)]</span>"
else
return "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];flavor_more=1'>More...</span></a>"
/mob/proc/print_flavor_text_2()
if(flavor_text && flavor_text != "")
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
var/msg = html_decode(replacetext(flavor_text_2, "\n", " "))
if(length_char(msg) <= 40)
return "<span class='notice'>[html_encode(msg)]</span>"
else
return "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];flavor2_more=1'>More...</span></a>"
/mob/proc/get_top_level_mob()
if(istype(src.loc,/mob)&&src.loc!=src)
@@ -60,9 +14,6 @@ proc/get_top_level_mob(var/mob/S)
return M.get_top_level_mob()
return S
///////////////// EMOTE CODE
// Maybe making this as an emote is less messy?
// It was - ktccd