This commit is contained in:
kappa-sama
2020-01-11 12:31:03 -05:00
parent e9f0740878
commit f752b41c99
958 changed files with 22207 additions and 30253 deletions
@@ -27,7 +27,12 @@
/datum/preferences/proc/update_preview_icon(equip_job = TRUE)
// Determine what job is marked as 'High' priority, and dress them up as such.
var/datum/job/previewJob = get_highest_job()
var/datum/job/previewJob
var/highest_pref = 0
for(var/job in job_preferences)
if(job_preferences["[job]"] > highest_pref)
previewJob = SSjob.GetJob(job)
highest_pref = job_preferences["[job]"]
if(previewJob)
// Silicons only need a very basic preview since there is no customization for them.
@@ -52,11 +57,3 @@
parent.show_character_previews(new /mutable_appearance(mannequin))
unset_busy_human_dummy(DUMMY_HUMAN_SLOT_PREFERENCES)
/datum/preferences/proc/get_highest_job()
var/highest_pref = 0
var/datum/job/highest_job
for(var/job in job_preferences)
if(job_preferences["[job]"] > highest_pref)
highest_job = SSjob.GetJob(job)
highest_pref = job_preferences["[job]"]
return highest_job
@@ -74,5 +74,4 @@
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
var/has_color = FALSE
var/has_digitigrade = FALSE
var/has_color = FALSE
@@ -27,33 +27,28 @@
extra2 = TRUE
center = TRUE
dimension_x = 64
var/taur_mode = NONE //Must be a single specific tauric suit variation bitflag. Don't do FLAG_1|FLAG_2
var/alt_taur_mode = NONE //Same as above.
var/taur_mode = NOT_TAURIC
color_src = MATRIXED
/datum/sprite_accessory/taur/none
dimension_x = 32
center = FALSE
name = "None"
icon_state = "None"
/datum/sprite_accessory/taur/cow
name = "Cow"
icon_state = "cow"
taur_mode = STYLE_HOOF_TAURIC
alt_taur_mode = STYLE_PAW_TAURIC
taur_mode = HOOF_TAURIC
/datum/sprite_accessory/taur/deer
name = "Deer"
icon_state = "deer"
taur_mode = STYLE_HOOF_TAURIC
alt_taur_mode = STYLE_PAW_TAURIC
taur_mode = HOOF_TAURIC
color_src = MUTCOLORS
/datum/sprite_accessory/taur/drake
name = "Drake"
icon_state = "drake"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
/datum/sprite_accessory/taur/drider
name = "Drider"
@@ -63,68 +58,67 @@
/datum/sprite_accessory/taur/eevee
name = "Eevee"
icon_state = "eevee"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
color_src = MUTCOLORS
/datum/sprite_accessory/taur/fox
name = "Fox"
icon_state = "fox"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
/datum/sprite_accessory/taur/husky
name = "Husky"
icon_state = "husky"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
/datum/sprite_accessory/taur/horse
name = "Horse"
icon_state = "horse"
taur_mode = STYLE_HOOF_TAURIC
alt_taur_mode = STYLE_PAW_TAURIC
taur_mode = HOOF_TAURIC
/datum/sprite_accessory/taur/lab
name = "Lab"
icon_state = "lab"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
/datum/sprite_accessory/taur/naga
name = "Naga"
icon_state = "naga"
taur_mode = STYLE_SNEK_TAURIC
taur_mode = SNEK_TAURIC
/datum/sprite_accessory/taur/otie
name = "Otie"
icon_state = "otie"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
/datum/sprite_accessory/taur/pede
name = "Scolipede"
icon_state = "pede"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
color_src = MUTCOLORS
/datum/sprite_accessory/taur/panther
name = "Panther"
icon_state = "panther"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
/datum/sprite_accessory/taur/shepherd
name = "Shepherd"
icon_state = "shepherd"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
/datum/sprite_accessory/taur/tentacle
name = "Tentacle"
icon_state = "tentacle"
taur_mode = STYLE_SNEK_TAURIC
taur_mode = SNEK_TAURIC
color_src = MUTCOLORS
/datum/sprite_accessory/taur/tiger
name = "Tiger"
icon_state = "tiger"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
/datum/sprite_accessory/taur/wolf
name = "Wolf"
icon_state = "wolf"
taur_mode = STYLE_PAW_TAURIC
taur_mode = PAW_TAURIC
@@ -2,9 +2,6 @@
// Socks Definitions //
///////////////////////
/datum/sprite_accessory/underwear/socks
has_digitigrade = TRUE
/datum/sprite_accessory/underwear/socks/nude
name = "Nude"
icon_state = null
@@ -310,40 +310,4 @@
name = "Tube Top"
icon_state = "tubetop"
has_color = TRUE
gender = FEMALE
/datum/sprite_accessory/underwear/top/cowboyshirt
name = "Cowboy Shirt Black"
icon_state = "cowboyshirt"
/datum/sprite_accessory/underwear/top/cowboyshirt/s
name = "Cowboy Shirt Shortsleeved Black"
icon_state = "cowboyshirt_s"
/datum/sprite_accessory/underwear/top/cowboyshirt/white
name = "Cowboy Shirt White"
icon_state = "cowboyshirt_white"
/datum/sprite_accessory/underwear/top/cowboyshirt/white/s
name = "Cowboy Shirt Shortsleeved White"
icon_state = "cowboyshirt_whites"
/datum/sprite_accessory/underwear/top/cowboyshirt/navy
name = "Cowboy Shirt Navy"
icon_state = "cowboyshirt_navy"
/datum/sprite_accessory/underwear/top/cowboyshirt/navy/s
name = "Cowboy Shirt Shortsleeved Navy"
icon_state = "cowboyshirt_navys"
/datum/sprite_accessory/underwear/top/cowboyshirt/red
name = "Cowboy Shirt Red"
icon_state = "cowboyshirt_red"
/datum/sprite_accessory/underwear/top/cowboyshirt/red/s
name = "Cowboy Shirt Shortsleeved Red"
icon_state = "cowboyshirt_reds"
gender = FEMALE
@@ -28,49 +28,41 @@
name = "Boxers"
icon_state = "boxers"
has_color = TRUE
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_bee
name = "Boxers - Bee"
icon_state = "bee_shorts"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_hearts
name = "Boxers - Heart"
icon_state = "boxers_heart"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_stripe
name = "Boxers - Striped"
icon_state = "boxers_striped"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_commie
name = "Boxers - Striped Communist"
icon_state = "boxers_commie"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_usastripe
name = "Boxers - Striped Freedom"
icon_state = "boxers_assblastusa"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_uk
name = "Boxers - Striped UK"
icon_state = "boxers_uk"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/boxer_briefs
name = "Boxer Briefs"
icon_state = "boxer_briefs"
has_digitigrade = TRUE
has_color = TRUE
/datum/sprite_accessory/underwear/bottom/panties
@@ -148,7 +140,6 @@
/datum/sprite_accessory/underwear/bottom/longjon
name = "Long John Bottoms"
icon_state = "ljonb"
has_digitigrade = TRUE
has_color = TRUE
/datum/sprite_accessory/underwear/bottom/swimsuit_red
+47 -33
View File
@@ -3,6 +3,8 @@ GLOBAL_LIST_EMPTY(ghost_images_simple) //this is a list of all ghost images as t
GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
#define CANT_REENTER_ROUND -1
/mob/dead/observer
name = "ghost"
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
@@ -19,6 +21,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
hud_type = /datum/hud/ghost
movement_type = GROUND | FLYING
var/can_reenter_corpse
var/reenter_round_timeout = 0 // used to prevent people from coming back through ghost roles/midround antags as they suicide/cryo for a duration set by CONFIG_GET(number/suicide_reenter_round_timer) and CONFIG_GET(number/roundstart_suicide_time_limit)
var/datum/hud/living/carbon/hud = null // hud
var/bootime = 0
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
@@ -134,7 +137,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
AA.onNewMob(src)
. = ..()
AddElement(/datum/element/ghost_role_eligibility)
grant_all_languages()
/mob/dead/observer/get_photo_description(obj/item/camera/camera)
@@ -269,12 +272,16 @@ Works together with spawning an observer, noted above.
var/mob/dead/observer/ghost = new(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)
if (!(client.prefs.chat_toggles & CHAT_OOC))
client.prefs.chat_toggles ^= CHAT_OOC
if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
penalty += roundstart_quit_limit - world.time
if(penalty)
ghost.reenter_round_timeout = world.realtime + penalty
if(ghost.reenter_round_timeout - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
ghost.reenter_round_timeout = CANT_REENTER_ROUND
transfer_ckey(ghost, FALSE)
ghost.AddElement(/datum/element/ghost_role_eligibility,penalize) // technically already run earlier, but this adds the penalty
// needs to be done AFTER the ckey transfer, too
return ghost
/*
@@ -331,7 +338,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
ghostize(0, penalize = TRUE)
/mob/dead/observer/proc/can_reenter_round(silent = FALSE)
if(reenter_round_timeout != CANT_REENTER_ROUND && reenter_round_timeout <= world.realtime)
return TRUE
if(!silent)
to_chat(src, "<span class='warning'>You are unable to reenter the round[reenter_round_timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(reenter_round_timeout - world.realtime)]" : ""].</span>")
return FALSE
/mob/dead/observer/Move(NewLoc, direct)
if(updatedir)
@@ -477,32 +489,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
pixel_y = 0
animate(src, pixel_y = 2, time = 10, loop = -1)
/mob/dead/observer/verb/observe()
set name = "Observe"
set category = "Ghost"
var/list/creatures = getpois()
reset_perspective(null)
var/eye_name = null
eye_name = input("Please, select a player!", "Observe", null, null) as null|anything in creatures
if (!eye_name)
return
var/mob/mob_eye = creatures[eye_name]
//Istype so we filter out points of interest that are not mobs
if(client && mob_eye && istype(mob_eye))
client.eye = mob_eye
if(mob_eye.hud_used)
client.screen = list()
LAZYINITLIST(mob_eye.observers)
mob_eye.observers |= src
mob_eye.hud_used.show_hud(mob_eye.hud_used.hud_version, src)
observetarget = mob_eye
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
set category = "Ghost"
set name = "Jump to Mob"
@@ -833,6 +819,32 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
client.screen = list()
hud_used.show_hud(hud_used.hud_version)
/mob/dead/observer/verb/observe()
set name = "Observe"
set category = "OOC"
var/list/creatures = getpois()
reset_perspective(null)
var/eye_name = null
eye_name = input("Please, select a player!", "Observe", null, null) as null|anything in creatures
if (!eye_name)
return
var/mob/mob_eye = creatures[eye_name]
//Istype so we filter out points of interest that are not mobs
if(client && mob_eye && istype(mob_eye))
client.eye = mob_eye
if(mob_eye.hud_used)
client.screen = list()
LAZYINITLIST(mob_eye.observers)
mob_eye.observers |= src
mob_eye.hud_used.show_hud(mob_eye.hud_used.hud_version, src)
observetarget = mob_eye
/mob/dead/observer/verb/register_pai_candidate()
set category = "Ghost"
set name = "pAI Setup"
@@ -886,3 +898,5 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
spawners_menu = new(src)
spawners_menu.ui_interact(src)
#undef CANT_REENTER_ROUND
+7 -7
View File
@@ -155,7 +155,7 @@
if(iscarbon(AM))
var/mob/living/carbon/C = AM
if(blood_id == C.get_blood_id())//both mobs have the same blood substance
if(blood_id == /datum/reagent/blood || blood_id == /datum/reagent/blood/jellyblood) //normal blood
if(blood_id == "blood" || blood_id == "jellyblood") //normal blood
if(blood_data["viruses"])
for(var/thing in blood_data["viruses"])
var/datum/disease/D = thing
@@ -175,7 +175,7 @@
return
/mob/living/carbon/get_blood_data(blood_id)
if(blood_id == /datum/reagent/blood || /datum/reagent/blood/jellyblood) //actual blood reagent
if(blood_id == "blood" || blood_id == "jellyblood") //actual blood reagent
var/blood_data = list()
//set the blood data
blood_data["donor"] = src
@@ -191,7 +191,7 @@
blood_data["resistances"] = disease_resistances.Copy()
var/list/temp_chem = list()
for(var/datum/reagent/R in reagents.reagent_list)
temp_chem[R.type] = R.volume
temp_chem[R.id] = R.volume
blood_data["trace_chem"] = list2params(temp_chem)
if(mind)
blood_data["mind"] = mind
@@ -226,21 +226,21 @@
/mob/living/simple_animal/get_blood_id()
if(blood_volume)
return /datum/reagent/blood
return "blood"
/mob/living/carbon/monkey/get_blood_id()
if(!(HAS_TRAIT(src, TRAIT_NOCLONE)))
return /datum/reagent/blood
return "blood"
/mob/living/carbon/get_blood_id()
if(isjellyperson(src))
return /datum/reagent/blood/jellyblood
return "jellyblood"
if(dna?.species?.exotic_blood)
return dna.species.exotic_blood
else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE)))
return
else
return /datum/reagent/blood
return "blood"
// This is has more potential uses, and is probably faster than the old proc.
/proc/get_safe_blood(bloodtype)
+2 -2
View File
@@ -73,7 +73,7 @@
if(victim.stat == CONSCIOUS)
src.visible_message("<span class='warning'>[victim] kicks free of the blood pool just before entering it!</span>", null, "<span class='notice'>You hear splashing and struggling.</span>")
else if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/consumable/ethanol/demonsblood))
else if(victim.reagents && victim.reagents.has_reagent("demonsblood"))
visible_message("<span class='warning'>Something prevents [victim] from entering the pool!</span>", "<span class='warning'>A strange force is blocking [victim] from entering!</span>", "<span class='notice'>You hear a splash and a thud.</span>")
else
victim.forceMove(src)
@@ -104,7 +104,7 @@
if(!victim)
return FALSE
if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/consumable/ethanol/devilskiss))
if(victim.reagents && victim.reagents.has_reagent("devilskiss"))
to_chat(src, "<span class='warning'><b>AAH! THEIR FLESH! IT BURNS!</b></span>")
adjustBruteLoss(25) //I can't use adjustHealth() here because bloodcrawl affects /mob/living and adjustHealth() only affects simple mobs
var/found_bloodpool = FALSE
+8 -8
View File
@@ -102,16 +102,16 @@
if(istype(O, /obj/item/organ_storage)) //BUG_PROBABLE_CAUSE
return //Borg organ bags shouldn't be killing brains
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent(/datum/reagent/medicine/neurine)) //Neurine fixes dead brains
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent("neurine")) //Neurine fixes dead brains
. = TRUE //don't do attack animation.
var/cached_Bdamage = brainmob?.health
var/datum/reagent/medicine/neurine/N = reagents.has_reagent(/datum/reagent/medicine/neurine)
var/datum/reagent/medicine/mannitol/M1 = reagents.has_reagent(/datum/reagent/medicine/mannitol)
var/datum/reagent/medicine/neurine/N = reagents.has_reagent("neurine")
var/datum/reagent/medicine/mannitol/M1 = reagents.has_reagent("mannitol")
if(O.reagents.has_reagent(/datum/reagent/medicine/mannitol))//Just a quick way to bolster the effects if someone mixes up a batch.
if(O.reagents.has_reagent("mannitol"))//Just a quick way to bolster the effects if someone mixes up a batch.
N.volume *= (M1.volume*0.5)
if(!O.reagents.has_reagent(/datum/reagent/medicine/neurine, 10))
if(!O.reagents.has_reagent("neurine", 10))
to_chat(user, "<span class='warning'>There's not enough neurine in [O] to restore [src]!</span>")
return
@@ -134,14 +134,14 @@
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
return
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent(/datum/reagent/medicine/mannitol)) //attempt to heal the brain
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent("mannitol")) //attempt to heal the brain
. = TRUE //don't do attack animation.
var/datum/reagent/medicine/mannitol/M = reagents.has_reagent(/datum/reagent/medicine/mannitol)
var/datum/reagent/medicine/mannitol/M = reagents.has_reagent("mannitol")
if(brain_death || brainmob?.health <= HEALTH_THRESHOLD_DEAD) //if the brain is fucked anyway, do nothing
to_chat(user, "<span class='warning'>[src] is far too damaged, you'll have to use neurine on it!</span>")
return
if(!O.reagents.has_reagent(/datum/reagent/medicine/mannitol, 10))
if(!O.reagents.has_reagent("mannitol", 10))
to_chat(user, "<span class='warning'>There's not enough mannitol in [O] to restore [src]!</span>")
return
@@ -6,21 +6,21 @@
return 2 //no ears
/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush)
return ..(AM, skipcatch = TRUE, hitpush = FALSE)
..(AM, skipcatch = TRUE, hitpush = FALSE)
/mob/living/carbon/alien/can_embed(obj/item/I)
return FALSE
/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other.
As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble.
In all, this is a lot like the monkey code. /N
*/
/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M)
. = ..()
if(!.) // the attack was blocked or was help/grab intent
if(isturf(loc) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return
switch(M.a_intent)
if (INTENT_HELP)
if ("help")
if(!recoveringstam)
resting = 0
AdjustStun(-60)
@@ -28,7 +28,11 @@ In all, this is a lot like the monkey code. /N
AdjustUnconscious(-60)
AdjustSleeping(-100)
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake [p_them()] up!</span>")
if(INTENT_DISARM, INTENT_HARM)
if ("grab")
grabbedby(M)
else
if(health > 0)
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
@@ -46,31 +50,28 @@ In all, this is a lot like the monkey code. /N
/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M)
. = ..()
if(.) //To allow surgery to return properly.
return
if(..()) //to allow surgery to return properly.
return 0
switch(M.a_intent)
if(INTENT_HELP)
if("help")
help_shake_act(M)
if(INTENT_GRAB)
if("grab")
grabbedby(M)
if (INTENT_HARM)
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt [src]!</span>")
return TRUE
if ("harm")
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
if(INTENT_DISARM)
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt [src]!</span>")
return TRUE
return 1
if("disarm")
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
return 1
return 0
/mob/living/carbon/alien/attack_paw(mob/living/carbon/monkey/M)
. = ..()
if(.) //successful monkey bite.
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(rand(1, 3), BRUTE, affecting)
if(..())
if (stat != DEAD)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(rand(1, 3), BRUTE, affecting)
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M)
@@ -92,15 +93,13 @@ In all, this is a lot like the monkey code. /N
adjustStaminaLoss(damage)
/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M)
. = ..()
if(!.) //unsuccessful slime attack
return
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(10, 40)
adjustBruteLoss(damage)
log_combat(M, src, "attacked")
updatehealth()
if(..()) //successful slime attack
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(10, 40)
adjustBruteLoss(damage)
log_combat(M, src, "attacked")
updatehealth()
/mob/living/carbon/alien/ex_act(severity, target, origin)
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
@@ -63,7 +63,12 @@
if(A)
if(isliving(A))
var/mob/living/L = A
if(!L.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
var/blocked = FALSE
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(H.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
blocked = TRUE
if(!blocked)
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
L.Knockdown(100)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
@@ -5,11 +5,9 @@
else
..()
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
. = ..(user, TRUE)
if(.)
return
..(user, 1)
adjustBruteLoss(15)
var/hitverb = "punched"
if(mob_size < MOB_SIZE_LARGE)
@@ -23,46 +21,46 @@
return 1
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
. = ..()
if(.) //To allow surgery to return properly.
return
switch(M.a_intent)
if (INTENT_HARM)
var/damage = rand(1, 9)
if (prob(90))
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
"<span class='userdanger'>[M] has punched [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of knocking an alien down.
Unconscious(40)
visible_message("<span class='danger'>[M] has knocked [src] down!</span>", \
"<span class='userdanger'>[M] has knocked [src] down!</span>")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(damage, BRUTE, affecting)
log_combat(M, src, "attacked")
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>", \
"<span class='userdanger'>[M] has attempted to punch [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if (INTENT_DISARM)
if (!lying)
if (prob(5))
Unconscious(40)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
log_combat(M, src, "pushed")
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
"<span class='userdanger'>[M] has pushed down [src]!</span>")
if(..())
switch(M.a_intent)
if ("harm")
var/damage = rand(1, 9)
if (prob(90))
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
"<span class='userdanger'>[M] has punched [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of knocking an alien down.
Unconscious(40)
visible_message("<span class='danger'>[M] has knocked [src] down!</span>", \
"<span class='userdanger'>[M] has knocked [src] down!</span>")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(damage, BRUTE, affecting)
log_combat(M, src, "attacked")
else
if (prob(50))
dropItemToGround(get_active_held_item())
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='userdanger'>[M] has attempted to punch [src]!</span>", \
"<span class='userdanger'>[M] has attempted to punch [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if ("disarm")
if (!lying)
if (prob(5))
Unconscious(40)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(M, src, "pushed")
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
"<span class='userdanger'>[M] has pushed down [src]!</span>")
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to disarm [src]!</span>",\
"<span class='userdanger'>[M] has attempted to disarm [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if (prob(50))
dropItemToGround(get_active_held_item())
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='userdanger'>[M] has attempted to disarm [src]!</span>",\
"<span class='userdanger'>[M] has attempted to disarm [src]!</span>", null, COMBAT_MESSAGE_RANGE)
/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(!no_effect && !visual_effect_icon)
@@ -14,9 +14,10 @@
var/max_grown = 100
var/time_of_birth
rotate_on_lying = FALSE
rotate_on_lying = 0
bodyparts = list(/obj/item/bodypart/chest/larva, /obj/item/bodypart/head/larva)
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/larva/Initialize()
@@ -1,33 +1,26 @@
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
. = ..()
if(. || M.a_intent == INTENT_HELP || M.a_intent == INTENT_GRAB)
return
var/damage = rand(1, 9)
if (prob(90))
playsound(loc, "punch", 25, 1, -1)
log_combat(M, src, "attacked")
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
"<span class='userdanger'>[M] has kicked [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if ((stat != DEAD) && (damage > 4.9))
Unconscious(rand(100,200))
if(..())
var/damage = rand(1, 9)
if (prob(90))
playsound(loc, "punch", 25, 1, -1)
log_combat(M, src, "attacked")
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
"<span class='userdanger'>[M] has kicked [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if ((stat != DEAD) && (damage > 4.9))
Unconscious(rand(100,200))
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(damage, BRUTE, affecting)
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
"<span class='userdanger'>[M] has attempted to kick [src]!</span>", null, COMBAT_MESSAGE_RANGE)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(damage, BRUTE, affecting)
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
"<span class='userdanger'>[M] has attempted to kick [src]!</span>", null, COMBAT_MESSAGE_RANGE)
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
. = ..(user, TRUE)
if(.)
return
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has pummeled [src]!</span>", \
"<span class='userdanger'>[user] has pummeled [src]!</span>", null, COMBAT_MESSAGE_RANGE)
..(user, 1)
adjustBruteLoss(5 + rand(1,9))
new /datum/forced_movement(src, get_step_away(user,src, 30), 1)
return 1
@@ -27,7 +27,7 @@
/obj/item/organ/alien/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent(/datum/reagent/toxin/acid, 10)
S.reagents.add_reagent("sacid", 10)
return S
@@ -46,7 +46,7 @@
/obj/item/organ/alien/plasmavessel/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent(/datum/reagent/toxin/plasma, storedPlasma/10)
S.reagents.add_reagent("plasma", storedPlasma/10)
return S
/obj/item/organ/alien/plasmavessel/large
@@ -18,7 +18,7 @@
/obj/item/organ/body_egg/alien_embryo/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent(/datum/reagent/toxin/acid, 10)
S.reagents.add_reagent("sacid", 10)
return S
/obj/item/organ/body_egg/alien_embryo/on_life()
@@ -103,17 +103,15 @@
new_xeno.notransform = 0
new_xeno.invisibility = 0
var/mob/living/carbon/old_owner = owner
if(kill_on_sucess) //ITS TOO LATE
new_xeno.visible_message("<span class='danger'>[new_xeno] bursts out of [owner]!</span>", "<span class='userdanger'>You exit [owner], your previous host.</span>", "<span class='italics'>You hear organic matter ripping and tearing!</span>")
owner.apply_damage(rand(100,300),BRUTE,zone,FALSE) //Random high damage to torso so health sensors don't metagame.
var/obj/item/bodypart/B = owner.get_bodypart(zone)
B.drop_organs(owner) //Lets still make the death gruesome and impossible to just simply defib someone.
owner.spill_organs(TRUE,FALSE,TRUE) //Lets still make the death gruesome and impossible to just simply defib someone.
owner.death(FALSE) //Just in case some freak occurance occurs where you somehow survive all your organs being removed from you and the 100-300 brute damage.
else //When it is removed via surgery at a late stage, rather than forced.
new_xeno.visible_message("<span class='danger'>[new_xeno] wriggles out of [owner]!</span>", "<span class='userdanger'>You exit [owner], your previous host.</span>")
owner.adjustBruteLoss(40)
old_owner.cut_overlay(overlay)
owner.cut_overlay(overlay)
qdel(src)
@@ -21,7 +21,7 @@
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
layer = MOB_LAYER
max_integrity = 100
mutantrace_variation = STYLE_MUZZLE
mutantrace_variation = MUTANTRACE_VARIATION
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
+4 -5
View File
@@ -157,7 +157,6 @@
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(src, "<span class='warning'>You're too exhausted.</span>")
return
var/random_turn = a_intent == INTENT_HARM
//END OF CIT CHANGES
var/obj/item/I = src.get_active_held_item()
@@ -182,7 +181,7 @@
if(HAS_TRAIT(src, TRAIT_PACIFISM))
to_chat(src, "<span class='notice'>You gently let go of [throwable_mob].</span>")
return
adjustStaminaLossBuffered(25)//CIT CHANGE - throwing an entire person shall be very tiring
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
var/turf/end_T = get_turf(target)
@@ -205,7 +204,7 @@
do_attack_animation(target, no_effect = 1)
playsound(loc, 'sound/weapons/punchmiss.ogg', 50, 1, -1)
newtonian_move(get_dir(target, src))
thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, random_turn)
thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src)
@@ -518,7 +517,7 @@
add_splatter_floor(T)
if(stun)
adjustBruteLoss(3)
else if(src.reagents.has_reagent(/datum/reagent/consumable/ethanol/blazaam))
else if(src.reagents.has_reagent("blazaam"))
if(T)
T.add_vomit_floor(src, VOMIT_PURPLE)
else
@@ -988,4 +987,4 @@
if(H.clothing_flags & SCAN_REAGENTS)
return TRUE
if(isclothing(wear_mask) && (wear_mask.clothing_flags & SCAN_REAGENTS))
return TRUE
return TRUE
@@ -48,42 +48,41 @@
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
affecting.dismember(P.damtype)
/mob/living/carbon/catch_item(obj/item/I, skip_throw_mode_check = FALSE)
. = ..()
if(!HAS_TRAIT(src, TRAIT_AUTO_CATCH_ITEM) && !skip_throw_mode_check && !in_throw_mode)
/mob/living/carbon/proc/can_catch_item(skip_throw_mode_check)
. = FALSE
if(mind)
if(mind.martial_art && mind.martial_art.dodge_chance == 100)
return TRUE
if(!skip_throw_mode_check && !in_throw_mode)
return
if(get_active_held_item() || restrained())
if(get_active_held_item())
return
I.attack_hand(src)
if(get_active_held_item() == I) //if our attack_hand() picks up the item...
visible_message("<span class='warning'>[src] catches [I]!</span>") //catch that sucker!
throw_mode_off()
return TRUE
if(restrained())
return
return TRUE
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE)
if(!skipcatch) //ugly, but easy
if(can_catch_item())
if(istype(AM, /obj/item))
var/obj/item/I = AM
if (mind)
if (mind.martial_art && mind.martial_art.dodge_chance == 100) //autocatch for rising bass
if (get_active_held_item())
visible_message("<span class='warning'>[I] falls to the ground as [src] chops it out of the air!</span>")
return 1
if(!in_throw_mode)
throw_mode_on()
if(isturf(I.loc))
I.attack_hand(src)
if(get_active_held_item() == I) //if our attack_hand() picks up the item...
visible_message("<span class='warning'>[src] catches [I]!</span>") //catch that sucker!
throw_mode_off()
return 1
..()
/mob/living/carbon/embed_item(obj/item/I)
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
var/obj/item/bodypart/L = pick(bodyparts)
L.embedded_objects |= I
I.add_mob_blood(src)//it embedded itself in you, of course it's bloody!
I.forceMove(src)
L.receive_damage(I.w_class*I.embedding.embedded_impact_pain_multiplier)
visible_message("<span class='danger'>[I] embeds itself in [src]'s [L.name]!</span>","<span class='userdanger'>[I] embeds itself in your [L.name]!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user)
//CIT CHANGES START HERE - combatmode and resting checks
var/totitemdamage = I.force
if(iscarbon(user))
var/mob/living/carbon/tempcarb = user
if(!tempcarb.combatmode)
totitemdamage *= 0.5
if(user.resting)
totitemdamage *= 0.5
if(!combatmode)
totitemdamage *= 1.5
//CIT CHANGES END HERE
if(user != src && check_shields(I, totitemdamage, "the [I.name]", MELEE_ATTACK, I.armour_penetration))
return FALSE
var/obj/item/bodypart/affecting
if(user == src)
affecting = get_bodypart(check_zone(user.zone_selected)) //we're self-mutilating! yay!
@@ -94,6 +93,17 @@
SEND_SIGNAL(I, COMSIG_ITEM_ATTACK_ZONE, src, user, affecting)
send_item_attack_message(I, user, affecting.name)
if(I.force)
//CIT CHANGES START HERE - combatmode and resting checks
var/totitemdamage = I.force
if(iscarbon(user))
var/mob/living/carbon/tempcarb = user
if(!tempcarb.combatmode)
totitemdamage *= 0.5
if(user.resting)
totitemdamage *= 0.5
if(!combatmode)
totitemdamage *= 1.5
//CIT CHANGES END HERE
apply_damage(totitemdamage, I.damtype, affecting) //CIT CHANGE - replaces I.force with totitemdamage
if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC)
var/basebloodychance = affecting.brute_dam + totitemdamage
@@ -127,9 +137,7 @@
//ATTACK HAND IGNORING PARENT RETURN VALUE
/mob/living/carbon/attack_hand(mob/living/carbon/human/user)
. = ..()
if(.) //was the attack blocked?
return
for(var/thing in diseases)
var/datum/disease/D = thing
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
@@ -144,7 +152,8 @@
if(user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, user.a_intent))
return TRUE
return 1
return 0
/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M)
@@ -164,8 +173,7 @@
help_shake_act(M)
return 0
. = ..()
if(.) //successful monkey bite.
if(..()) //successful monkey bite.
for(var/thing in M.diseases)
var/datum/disease/D = thing
ForceContractDisease(D)
@@ -173,27 +181,26 @@
/mob/living/carbon/attack_slime(mob/living/simple_animal/slime/M)
. = ..()
if(!.)
return
if(M.powerlevel > 0)
var/stunprob = M.powerlevel * 7 + 10 // 17 at level 1, 80 at level 10
if(prob(stunprob))
M.powerlevel -= 3
if(M.powerlevel < 0)
M.powerlevel = 0
if(..()) //successful slime attack
if(M.powerlevel > 0)
var/stunprob = M.powerlevel * 7 + 10 // 17 at level 1, 80 at level 10
if(prob(stunprob))
M.powerlevel -= 3
if(M.powerlevel < 0)
M.powerlevel = 0
visible_message("<span class='danger'>The [M.name] has shocked [src]!</span>", \
"<span class='userdanger'>The [M.name] has shocked [src]!</span>")
visible_message("<span class='danger'>The [M.name] has shocked [src]!</span>", \
"<span class='userdanger'>The [M.name] has shocked [src]!</span>")
do_sparks(5, TRUE, src)
var/power = M.powerlevel + rand(0,3)
Knockdown(power*20)
if(stuttering < power)
stuttering = power
if (prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
do_sparks(5, TRUE, src)
var/power = M.powerlevel + rand(0,3)
Knockdown(power*20)
if(stuttering < power)
stuttering = power
if (prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
return 1
/mob/living/carbon/proc/dismembering_strike(mob/living/attacker, dam_zone)
if(!attacker.limb_destroyer)
@@ -243,7 +250,7 @@
shock_damage *= dna.species.siemens_coeff
if(shock_damage<1 && !override)
return 0
if(reagents.has_reagent(/datum/reagent/teslium))
if(reagents.has_reagent("teslium"))
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
if(illusion)
adjustStaminaLoss(shock_damage)
@@ -325,12 +332,12 @@
else
return
else if(check_zone(M.zone_selected) == "r_arm" || check_zone(M.zone_selected) == "l_arm")
M.visible_message( \
"<span class='notice'>[M] shakes [src]'s hand.</span>", \
"<span class='notice'>You shake [src]'s hand.</span>", )
else
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
@@ -40,7 +40,7 @@
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
rotate_on_lying = TRUE
var/rotate_on_lying = 1
var/tinttotal = 0 // Total level of visualy impairing items
-1
View File
@@ -22,7 +22,6 @@
muzzle_ignore = TRUE
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/carbon/clap/run_emote(mob/living/user, params)
. = ..()
@@ -255,7 +255,7 @@
else
msg += "<B>[t_He] [t_is] bleeding!</B>\n"
if(reagents.has_reagent(/datum/reagent/teslium))
if(reagents.has_reagent("teslium"))
msg += "[t_He] [t_is] emitting a gentle blue glow!\n"
if(islist(stun_absorption))
@@ -278,7 +278,7 @@
if(91.01 to INFINITY)
msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n"
if(reagents.has_reagent(/datum/reagent/fermi/astral))
if(reagents.has_reagent("astral"))
if(mind)
msg += "[t_He] has wild, spacey eyes and they have a strange, abnormal look to them.\n"
else
@@ -308,7 +308,7 @@
var/obj/item/organ/vocal_cords/Vc = user.getorganslot(ORGAN_SLOT_VOICE)
if(Vc)
if(istype(Vc, /obj/item/organ/vocal_cords/velvet))
if(client.prefs.cit_toggles & HYPNO)
if(client?.prefs.lewdchem)
msg += "<span class='velvet'><i>You feel your chords resonate looking at them.</i></span>\n"
@@ -67,36 +67,66 @@
P.setAngle(rand(0, 360))//SHING
return FALSE
return ..()
if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself
if(P.is_reflectable)
if(check_reflect(def_zone)) // Checks if you've passed a reflection% check
visible_message("<span class='danger'>The [P.name] gets reflected by [src]!</span>", \
"<span class='userdanger'>The [P.name] gets reflected by [src]!</span>")
// Find a turf near or on the original location to bounce to
if(P.starting)
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(src)
/mob/living/carbon/human/check_reflect(def_zone)
if(wear_suit?.IsReflect(def_zone))
return TRUE
return ..()
// redirect the projectile
P.original = locate(new_x, new_y, P.z)
P.starting = curloc
P.firer = src
P.yo = new_y - curloc.y
P.xo = new_x - curloc.x
var/new_angle_s = P.Angle + rand(120,240)
while(new_angle_s > 180) // Translate to regular projectile degrees
new_angle_s -= 360
P.setAngle(new_angle_s)
/mob/living/carbon/human/check_shields(atom/AM, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
. = ..()
if(.)
return
return -1 // complete projectile permutation
if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration))
P.on_hit(src, 100, def_zone)
return 2
return (..(P , def_zone))
/mob/living/carbon/human/proc/check_reflect(def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on the reflection chance of the object
if(wear_suit)
if(wear_suit.IsReflect(def_zone) == 1)
return 1
for(var/obj/item/I in held_items)
if(I.IsReflect(def_zone) == 1)
return 1
return 0
/mob/living/carbon/human/proc/check_shields(atom/AM, var/damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
var/block_chance_modifier = round(damage / -3)
for(var/obj/item/I in held_items)
if(!istype(I, /obj/item/clothing))
var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
if(I.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
if(wear_suit)
var/final_block_chance = wear_suit.block_chance - (CLAMP((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
if(wear_suit.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return TRUE
return 1
if(w_uniform)
var/final_block_chance = w_uniform.block_chance - (CLAMP((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
if(w_uniform.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return TRUE
return 1
if(wear_neck)
var/final_block_chance = wear_neck.block_chance - (CLAMP((armour_penetration-wear_neck.armour_penetration)/2,0,100)) + block_chance_modifier
if(wear_neck.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return TRUE
return FALSE
/mob/living/carbon/human/can_embed(obj/item/I)
if(I.get_sharpness() || is_pointed(I) || is_type_in_typecache(I, GLOB.can_embed_types))
return TRUE
return FALSE
return 1
return 0
/mob/living/carbon/human/proc/check_block()
if(mind)
@@ -105,7 +135,39 @@
return FALSE
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE)
return dna?.species?.spec_hitby(AM, src) || ..()
if(dna && dna.species)
var/spec_return = dna.species.spec_hitby(AM, src)
if(spec_return)
return spec_return
var/obj/item/I
var/throwpower = 30
if(istype(AM, /obj/item))
I = AM
throwpower = I.throwforce
if(I.thrownby == src) //No throwing stuff at yourself to trigger hit reactions
return ..()
if(check_shields(AM, throwpower, "\the [AM.name]", THROWN_PROJECTILE_ATTACK))
hitpush = FALSE
skipcatch = TRUE
blocked = TRUE
else if(I)
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD && !(mind.martial_art && mind.martial_art.dodge_chance == 100))
if(can_embed(I))
if(prob(I.embedding.embed_chance) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE))
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
var/obj/item/bodypart/L = pick(bodyparts)
L.embedded_objects |= I
I.add_mob_blood(src)//it embedded itself in you, of course it's bloody!
I.forceMove(src)
L.receive_damage(I.w_class*I.embedding.embedded_impact_pain_multiplier)
visible_message("<span class='danger'>[I] embeds itself in [src]'s [L.name]!</span>","<span class='userdanger'>[I] embeds itself in your [L.name]!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
hitpush = FALSE
skipcatch = TRUE //can't catch the now embedded item
if (mind)
if (mind.martial_art && mind.martial_art.dodge_chance == 100)
skipcatch = FALSE
return ..()
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (HAS_TRAIT(src, TRAIT_FAT)) && ismonkey(pulling))
@@ -139,12 +201,12 @@
return dna.species.spec_attacked_by(I, user, affecting, a_intent, src)
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
. = ..(user, TRUE)
if(.)
return
var/hulk_verb = pick("smash","pummel")
if(check_shields(user, 15, "the [hulk_verb]ing"))
return
..(user, 1)
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
var/message = "[user] has [hulk_verb]ed [src]!"
visible_message("<span class='danger'>[message]</span>", \
@@ -153,8 +215,7 @@
return 1
/mob/living/carbon/human/attack_hand(mob/user)
. = ..()
if(.) //To allow surgery to return properly.
if(..()) //to allow surgery to return properly.
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
@@ -166,7 +227,8 @@
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
if(M.a_intent == INTENT_HELP)
return ..() //shaking
..() //shaking
return 0
if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead.
var/obj/item/I = get_active_held_item()
@@ -187,69 +249,78 @@
if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites.
if(..()) //successful monkey bite, this handles disease contraction.
var/damage = rand(1, 3)
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
if(check_shields(M, damage, "the [M.name]"))
return 0
if(stat != DEAD)
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
return 1
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
. = ..()
if(!.)
return
if(M.a_intent == INTENT_HARM)
if (w_uniform)
w_uniform.add_fingerprint(M)
var/damage = prob(90) ? 20 : 0
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
"<span class='userdanger'>[M] has lunged at [src]!</span>")
return 0
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
var/armor_block = run_armor_check(affecting, "melee", null, null,10)
if(check_shields(M, 0, "the M.name"))
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
return 0
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>")
log_combat(M, src, "attacked")
if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful
return 1
apply_damage(damage, BRUTE, affecting, armor_block)
if(..())
if(M.a_intent == INTENT_HARM)
if (w_uniform)
w_uniform.add_fingerprint(M)
var/damage = prob(90) ? 20 : 0
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
"<span class='userdanger'>[M] has lunged at [src]!</span>")
return 0
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
var/armor_block = run_armor_check(affecting, "melee", null, null,10)
if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stun instead.
var/obj/item/I = get_active_held_item()
if(I && dropItemToGround(I))
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
"<span class='userdanger'>[M] disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(!lying) //CITADEL EDIT
Knockdown(100, TRUE, FALSE, 30, 25)
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>")
log_combat(M, src, "attacked")
if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful
return 1
apply_damage(damage, BRUTE, affecting, armor_block)
if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stun instead.
var/obj/item/I = get_active_held_item()
if(I && dropItemToGround(I))
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
"<span class='userdanger'>[M] disarmed [src]!</span>")
else
Knockdown(100)
log_combat(M, src, "tackled")
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
"<span class='userdanger'>[M] has tackled down [src]!</span>")
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(!lying) //CITADEL EDIT
Knockdown(100, TRUE, FALSE, 30, 25)
else
Knockdown(100)
log_combat(M, src, "tackled")
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
"<span class='userdanger'>[M] has tackled down [src]!</span>")
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
. = ..()
if(!.) //unsuccessful larva bite.
return
var/damage = rand(1, 3)
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
if(..()) //successful larva bite.
var/damage = rand(1, 3)
if(check_shields(L, damage, "the [L.name]"))
return 0
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
. = ..()
if(.)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
if(check_shields(M, damage, "the [M.name]", MELEE_ATTACK, M.armour_penetration))
return FALSE
var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
if(!dam_zone) //Dismemberment successful
return TRUE
@@ -261,22 +332,23 @@
/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
. = ..()
if(!.) //unsuccessful slime attack
return
var/damage = rand(5, 25)
if(M.is_adult)
damage = rand(10, 35)
if(..()) //successful slime attack
var/damage = rand(5, 25)
if(M.is_adult)
damage = rand(10, 35)
var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
if(!dam_zone) //Dismemberment successful
return 1
if(check_shields(M, damage, "the [M.name]"))
return 0
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
if(!dam_zone) //Dismemberment successful
return 1
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
if(M.occupant.a_intent == INTENT_HARM)
@@ -333,7 +405,7 @@
switch (severity)
if (1)
if(bomb_armor)
b_loss = (350*bomb_armor)+150
b_loss = 500*bomb_armor
var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
throw_at(throw_target, 200, 4)
damage_clothes(400*bomb_armor, BRUTE, "bomb")
@@ -580,7 +652,7 @@
if(mind)
if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") )
gain = 100
if(HAS_TRAIT(mind, TRAIT_CLOWN_MENTALITY))
if(mind.assigned_role == "Clown")
gain = rand(-300, 300)
investigate_log("([key_name(src)]) has been consumed by the singularity.", INVESTIGATE_SINGULO) //Oh that's where the clown ended up!
gib()
+50 -39
View File
@@ -290,7 +290,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
// this needs to be FIRST because qdel calls update_body which checks if we have DIGITIGRADE legs or not and if not then removes DIGITIGRADE from species_traits
if(("legs" in C.dna.species.mutant_bodyparts) && (C.dna.features["legs"] == "Digitigrade" || C.dna.features["legs"] == "Avian"))
species_traits |= DIGITIGRADE
species_traits += DIGITIGRADE
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(FALSE)
@@ -545,20 +545,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//Underwear, Undershirts & Socks
if(!(NO_UNDERWEAR in species_traits))
if(H.socks && H.get_num_legs(FALSE) >= 2)
if(H.hidden_socks)
H.socks = "Nude"
else
H.socks = H.saved_socks
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
if(S)
var/digilegs = ((DIGITIGRADE in species_traits) && S.has_digitigrade) ? "_d" : ""
var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
if(S.has_color)
MA.color = "#[H.socks_color]"
standing += MA
if(H.underwear)
if(H.hidden_underwear)
H.underwear = "Nude"
@@ -566,9 +552,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.underwear = H.saved_underwear
var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
if(B)
var/digilegs = ((DIGITIGRADE in species_traits) && B.has_digitigrade) ? "_d" : ""
var/mutable_appearance/MA = mutable_appearance(B.icon, "[B.icon_state][digilegs]", -BODY_LAYER)
if(B.has_color)
var/mutable_appearance/MA = mutable_appearance(B.icon, B.icon_state, -BODY_LAYER)
if(UNDIE_COLORABLE(B))
MA.color = "#[H.undie_color]"
standing += MA
@@ -579,16 +564,28 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.undershirt = H.saved_undershirt
var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
if(T)
var/state = "[T.icon_state][((DIGITIGRADE in species_traits) && T.has_digitigrade) ? "_d" : ""]"
var/mutable_appearance/MA
if(H.dna.species.sexes && H.gender == FEMALE)
MA = wear_female_version(state, T.icon, BODY_LAYER)
MA = wear_female_version(T.icon_state, T.icon, BODY_LAYER)
else
MA = mutable_appearance(T.icon, state, -BODY_LAYER)
if(T.has_color)
MA = mutable_appearance(T.icon, T.icon_state, -BODY_LAYER)
if(UNDIE_COLORABLE(T))
MA.color = "#[H.shirt_color]"
standing += MA
if(H.socks && H.get_num_legs(FALSE) >= 2)
if(H.hidden_socks)
H.socks = "Nude"
else
H.socks = H.saved_socks
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
if(S)
var/digilegs = (DIGITIGRADE in species_traits) ? "_d" : ""
var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
if(UNDIE_COLORABLE(S))
MA.color = "#[H.socks_color]"
standing += MA
if(standing.len)
H.overlays_standing[BODY_LAYER] = standing
@@ -611,34 +608,34 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
var/tauric = H.dna.features["taur"] && H.dna.features["taur"] != "None"
if("tail_lizard" in mutant_bodyparts)
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
bodyparts_to_add -= "tail_lizard"
if("waggingtail_lizard" in mutant_bodyparts)
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
bodyparts_to_add -= "waggingtail_lizard"
else if ("tail_lizard" in mutant_bodyparts)
bodyparts_to_add -= "waggingtail_lizard"
if("tail_human" in mutant_bodyparts)
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
bodyparts_to_add -= "tail_human"
if("waggingtail_human" in mutant_bodyparts)
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
bodyparts_to_add -= "waggingtail_human"
else if ("tail_human" in mutant_bodyparts)
bodyparts_to_add -= "waggingtail_human"
if("spines" in mutant_bodyparts)
if(!H.dna.features["spines"] || H.dna.features["spines"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR))
if(!H.dna.features["spines"] || H.dna.features["spines"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT))
bodyparts_to_add -= "spines"
if("waggingspines" in mutant_bodyparts)
if(!H.dna.features["spines"] || H.dna.features["spines"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR))
if(!H.dna.features["spines"] || H.dna.features["spines"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT))
bodyparts_to_add -= "waggingspines"
else if ("tail" in mutant_bodyparts)
bodyparts_to_add -= "waggingspines"
@@ -688,11 +685,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//Other Races
if("mam_tail" in mutant_bodyparts)
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
bodyparts_to_add -= "mam_tail"
if("mam_waggingtail" in mutant_bodyparts)
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
bodyparts_to_add -= "mam_waggingtail"
else if ("mam_tail" in mutant_bodyparts)
bodyparts_to_add -= "mam_waggingtail"
@@ -706,7 +703,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
bodyparts_to_add -= "mam_snouts"
if("taur" in mutant_bodyparts)
if(!tauric || (H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)))
if(!H.dna.features["taur"] || H.dna.features["taur"] == "None" || (H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)))
bodyparts_to_add -= "taur"
//END EDIT
@@ -723,10 +720,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
species_traits += DIGITIGRADE
var/should_be_squished = FALSE
if(H.wear_suit)
if(!(H.wear_suit.mutantrace_variation & STYLE_DIGITIGRADE) || (tauric && (H.wear_suit.mutantrace_variation & STYLE_ALL_TAURIC))) //digitigrade/taur suits
if(H.wear_suit.mutantrace_variation == NO_MUTANTRACE_VARIATION) //we got digitigrade suits now fam
should_be_squished = TRUE
if(H.w_uniform && !H.wear_suit)
if(!(H.w_uniform.mutantrace_variation & STYLE_DIGITIGRADE))
if(H.w_uniform.mutantrace_variation == NO_MUTANTRACE_VARIATION)
should_be_squished = TRUE
if(O.use_digitigrade == FULL_DIGITIGRADE && should_be_squished)
O.use_digitigrade = SQUISHED_DIGITIGRADE
@@ -1270,9 +1267,9 @@ 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.id == exotic_blood)
H.blood_volume = min(H.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM)
H.reagents.del_reagent(chem.type)
H.reagents.del_reagent(chem.id)
return 1
return FALSE
@@ -1592,11 +1589,20 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
user.adjustStaminaLossBuffered(3)
return FALSE
else if(aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin))
if(target.client?.prefs.cit_toggles & NO_ASS_SLAP)
to_chat(user,"A force stays your hand, preventing you from slapping \the [target]'s ass!")
return FALSE
user.do_attack_animation(target, ATTACK_EFFECT_ASS_SLAP)
user.adjustStaminaLossBuffered(3)
if(HAS_TRAIT(target, TRAIT_ASSBLASTUSA))
var/hit_zone = (user.held_index_to_dir(user.active_hand_index) == "l" ? "l_":"r_") + "arm"
user.adjustStaminaLoss(20, affected_zone = hit_zone)
user.visible_message(\
"<span class='danger'>\The [user] slaps \the [target]'s ass, but their hand bounces off like they hit metal!</span>",\
"<span class='danger'>You slap [user == target ? "your" : "\the [target]'s"] ass, but feel an intense amount of pain as you realise their buns are harder than steel!</span>",\
"You hear a slap."
)
playsound(target.loc, 'sound/weapons/tap.ogg', 50, 1, -1)
user.emote("scream")
return FALSE
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
user.visible_message(\
"<span class='danger'>\The [user] slaps \the [target]'s ass!</span>",\
@@ -1685,6 +1691,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
attacker_style = M.mind.martial_art
if(attacker_style?.pacifism_check && HAS_TRAIT(M, TRAIT_PACIFISM)) // most martial arts are quite harmful, alas.
attacker_style = null
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
log_combat(M, H, "attempted to touch")
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
return 0
SEND_SIGNAL(M, COMSIG_MOB_ATTACK_HAND, M, H, attacker_style)
switch(M.a_intent)
if("help")
help(M, H, attacker_style)
@@ -7,18 +7,18 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
id = "dwarf" //Also called Homo sapiens pumilionis
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NO_UNDERWEAR)
inherent_traits = list()
inherent_traits = list()
default_features = list("mcolor" = "FFF", "wings" = "None")
limbs_id = "human"
use_skintones = 1
say_mod = "bellows" //high energy, EXTRA BIOLOGICAL FUEL
damage_overlay_type = "human"
damage_overlay_type = "human"
skinned_type = /obj/item/stack/sheet/animalhide/human
liked_food = ALCOHOL | MEAT | DAIRY //Dwarves like alcohol, meat, and dairy products.
disliked_food = JUNKFOOD | FRIED //Dwarves hate foods that have no nutrition other than alcohol.
mutant_organs = list(/obj/item/organ/dwarfgland) //Dwarven alcohol gland, literal gland warrior
mutantliver = /obj/item/organ/liver/dwarf //Dwarven super liver (Otherwise they r doomed)
/mob/living/carbon/human/species/dwarf //species admin spawn path
race = /datum/species/dwarf //and the race the path is set to.
@@ -30,7 +30,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
/datum/species/dwarf/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
var/dwarf_hair = pick("Beard (Dwarf)", "Beard (Very Long)", "Beard (Long)") //beard roullette
var/mob/living/carbon/human/H = C
var/mob/living/carbon/human/H = C
H.facial_hair_style = dwarf_hair
H.update_hair()
H.transform = H.transform.Scale(1, 0.8) //We use scale, and yeah. Dwarves can become gnomes with DWARFISM.
@@ -95,7 +95,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
/obj/item/organ/dwarfgland/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent(/datum/reagent/consumable/ethanol, stored_alcohol/10)
S.reagents.add_reagent("ethanol", stored_alcohol/10)
return S
/obj/item/organ/dwarfgland/on_life() //Primary loop to hook into to start delayed loops for other loops..
@@ -108,8 +108,8 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
return //We make sure they are not dead, so they don't increment any tickers.
dwarf_eth_ticker++
dwarf_filth_ticker++
if(dwarf_filth_ticker >= 4) //Should be around 4-8 seconds since a tick is around 2 seconds.
if(dwarf_filth_ticker >= 4) //Should be around 4-8 seconds since a tick is around 2 seconds.
dwarf_filth_cycle() //On_life will adjust regarding other factors, so we are along for the ride.
dwarf_filth_ticker = 0 //We set the ticker back to 0 to go again.
if(dwarf_eth_ticker >= 1) //Alcohol reagent check should be around 2 seconds, since a tick is around 2 seconds.
@@ -13,9 +13,9 @@
exotic_bloodtype = "BUG"
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.type == /datum/reagent/toxin/pestkiller)
if(chem.id == "pestkiller")
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
return 1
@@ -70,6 +70,20 @@
damage_overlay_type = "xeno"
liked_food = MEAT
/datum/species/xeno/on_species_gain(mob/living/carbon/human/C, datum/species/old_species)
if(("legs" in C.dna.species.mutant_bodyparts) && (C.dna.features["legs"] == "Digitigrade" || C.dna.features["legs"] == "Avian"))
species_traits += DIGITIGRADE
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(FALSE)
. = ..()
/datum/species/xeno/on_species_loss(mob/living/carbon/human/C, datum/species/new_species)
if(("legs" in C.dna.species.mutant_bodyparts) && C.dna.features["legs"] == "Plantigrade")
species_traits -= DIGITIGRADE
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(TRUE)
. = ..()
//Praise the Omnissiah, A challange worthy of my skills - HS
//EXOTIC//
@@ -305,9 +305,9 @@
H.take_overall_damage(2,0)
/datum/species/golem/wood/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.type == /datum/reagent/toxin/plantbgone)
if(chem.id == "plantbgone")
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
return 1
//Radioactive
@@ -619,14 +619,14 @@
C.RemoveSpell(dominate)
/datum/species/golem/runic/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.type == /datum/reagent/water/holywater)
if(chem.id == "holywater")
H.adjustFireLoss(4)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
if(chem.type == /datum/reagent/fuel/unholywater)
if(chem.id == "unholywater")
H.adjustBruteLoss(-4)
H.adjustFireLoss(-4)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
/datum/species/golem/clockwork
@@ -12,7 +12,7 @@
inherent_traits = list(TRAIT_TOXINLOVER)
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
gib_types = list(/obj/effect/gibspawner/slime, /obj/effect/gibspawner/slime/bodypartless)
exotic_blood = /datum/reagent/blood/jellyblood
exotic_blood = "jellyblood"
exotic_bloodtype = "GEL"
damage_overlay_type = ""
var/datum/action/innate/regenerate_limbs/regenerate_limbs
@@ -73,6 +73,19 @@
mutant_bodyparts |= "spines"
H.update_body()
/datum/species/lizard/on_species_gain(mob/living/carbon/human/C, datum/species/old_species)
if(("legs" in C.dna.species.mutant_bodyparts) && (C.dna.features["legs"] == "Digitigrade" || C.dna.features["legs"] == "Avian"))
species_traits += DIGITIGRADE
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(FALSE)
return ..()
/datum/species/lizard/on_species_loss(mob/living/carbon/human/C, datum/species/new_species)
if(("legs" in C.dna.species.mutant_bodyparts) && C.dna.features["legs"] == "Plantigrade")
species_traits -= DIGITIGRADE
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(TRUE)
/*
Lizard subspecies: ASHWALKERS
*/
@@ -37,24 +37,19 @@
H.dna.features["caps"] = "Round"
handle_mutant_bodyparts(H)
H.faction |= "mushroom"
mush = new()
mush.teach(H, TRUE)
RegisterSignal(C, COMSIG_MOB_ON_NEW_MIND, .proc/on_new_mind)
/datum/species/mush/proc/on_new_mind(mob/owner)
mush.teach(owner, TRUE) //make_temporary TRUE as it shouldn't carry over to other mobs on mind transfer_to.
mush = new(null)
mush.teach(H)
/datum/species/mush/on_species_loss(mob/living/carbon/C)
. = ..()
UnregisterSignal(C, COMSIG_MOB_ON_NEW_MIND)
C.faction -= "mushroom"
mush.remove(C)
QDEL_NULL(mush)
/datum/species/mush/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.type == /datum/reagent/toxin/plantbgone/weedkiller)
if(chem.id == "weedkiller")
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
return TRUE
/datum/species/mush/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
@@ -47,9 +47,9 @@
H.take_overall_damage(2,0)
/datum/species/pod/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.type == /datum/reagent/toxin/plantbgone)
if(chem.id == "plantbgone")
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
return 1
/datum/species/pod/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
@@ -51,7 +51,11 @@
. = ..()
to_chat(C, "[info_text]")
C.fully_replace_character_name("[pick(GLOB.nightmare_names)]")
C.real_name = "[pick(GLOB.nightmare_names)]"
C.name = C.real_name
if(C.mind)
C.mind.name = C.real_name
C.dna.real_name = C.real_name
/datum/species/shadow/nightmare/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
var/turf/T = H.loc
@@ -123,8 +127,8 @@
/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
respawn_progress = 0
if(blade && special != HEART_SPECIAL_SHADOWIFY)
M.visible_message("<span class='warning'>\The [blade] disintegrates!</span>")
QDEL_NULL(blade)
M.visible_message("<span class='warning'>\The [blade] disintegrates!</span>")
..()
/obj/item/organ/heart/nightmare/Stop()
@@ -179,21 +183,15 @@
. = ..()
if(!proximity)
return
if(isopenturf(AM))
var/turf/open/T = AM
if(T.light_range && !isspaceturf(T)) //no fairy grass or light tile can escape the fury of the darkness.
to_chat(user, "<span class='notice'>You scrape away [T] with your [name] and snuff out its lights.</span>")
T.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
else if(isliving(AM))
if(isopenturf(AM)) //So you can actually melee with it
return
if(isliving(AM))
var/mob/living/L = AM
if(iscyborg(AM))
var/mob/living/silicon/robot/borg = AM
if(borg.lamp_intensity)
if(!borg.lamp_cooldown)
borg.update_headlamp(TRUE, INFINITY)
to_chat(borg, "<span class='danger'>Your headlamp is fried! You'll need a human to help replace it.</span>")
for(var/obj/item/assembly/flash/cyborg/F in borg.held_items)
if(!F.crit_fail)
F.burn_out()
else
for(var/obj/item/O in AM)
if(O.light_range && O.light_power)
@@ -36,9 +36,9 @@
UnregisterSignal(H, COMSIG_MOB_SAY)
/datum/species/synth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.type == /datum/reagent/medicine/synthflesh)
if(chem.id == "synthflesh")
chem.reaction_mob(H, TOUCH, 2 ,0) //heal a little
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
return 1
else
return ..()
@@ -119,25 +119,24 @@ There are several things that need to be remembered:
var/t_color = U.item_color
if(!t_color)
t_color = U.icon_state
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d"
if(U.suit_style == NORMAL_SUIT_STYLE)
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d"
var/alt_worn = U.alternate_worn_icon || 'icons/mob/uniform.dmi'
var/variant_flag = NONE
var/alt_worn = U.alternate_worn_icon
if((DIGITIGRADE in dna.species.species_traits) && U.mutantrace_variation & STYLE_DIGITIGRADE)
if(!U.force_alternate_icon && U.mutantrace_variation && U.suit_style == DIGITIGRADE_SUIT_STYLE)
alt_worn = 'icons/mob/uniform_digi.dmi'
variant_flag |= STYLE_DIGITIGRADE
var/mutable_appearance/uniform_overlay
if(dna && dna.species.sexes)
var/G = (gender == FEMALE) ? "f" : "m"
if(G == "f" && U.fitted != NO_FEMALE_UNIFORM)
uniform_overlay = U.build_worn_icon(t_color, UNIFORM_LAYER, alt_worn, FALSE, U.fitted, variant_flag, FALSE)
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = (alt_worn ? alt_worn : 'icons/mob/uniform.dmi'), isinhands = FALSE, femaleuniform = U.fitted)
if(!uniform_overlay)
uniform_overlay = U.build_worn_icon(t_color, UNIFORM_LAYER, alt_worn, FALSE, NO_FEMALE_UNIFORM, variant_flag, FALSE)
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = (alt_worn ? alt_worn : 'icons/mob/uniform.dmi'), isinhands = FALSE)
if(OFFSET_UNIFORM in dna.species.offset_features)
@@ -165,7 +164,7 @@ There are several things that need to be remembered:
update_observer_view(wear_id)
//TODO: add an icon file for ID slot stuff, so it's less snowflakey
id_overlay = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi')
id_overlay = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = ((wear_id.alternate_worn_icon) ? wear_id.alternate_worn_icon : 'icons/mob/mob.dmi'))
if(OFFSET_ID in dna.species.offset_features)
id_overlay.pixel_x += dna.species.offset_features[OFFSET_ID][1]
id_overlay.pixel_y += dna.species.offset_features[OFFSET_ID][2]
@@ -200,7 +199,7 @@ There are several things that need to be remembered:
var/t_state = gloves.item_state
if(!t_state)
t_state = gloves.icon_state
overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(state = t_state, default_layer = GLOVES_LAYER, default_icon_file = 'icons/mob/hands.dmi')
overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(state = t_state, default_layer = GLOVES_LAYER, default_icon_file = ((gloves.alternate_worn_icon) ? gloves.alternate_worn_icon : 'icons/mob/hands.dmi'))
gloves_overlay = overlays_standing[GLOVES_LAYER]
if(OFFSET_GLOVES in dna.species.offset_features)
gloves_overlay.pixel_x += dna.species.offset_features[OFFSET_GLOVES][1]
@@ -226,7 +225,7 @@ There are several things that need to be remembered:
client.screen += glasses //Either way, add the item to the HUD
update_observer_view(glasses,1)
if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES)))
overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi')
overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = ((glasses.alternate_worn_icon) ? glasses.alternate_worn_icon : 'icons/mob/eyes.dmi'))
var/mutable_appearance/glasses_overlay = overlays_standing[GLASSES_LAYER]
if(glasses_overlay)
if(OFFSET_GLASSES in dna.species.offset_features)
@@ -253,7 +252,7 @@ There are several things that need to be remembered:
client.screen += ears //add it to the client's screen
update_observer_view(ears,1)
overlays_standing[EARS_LAYER] = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi')
overlays_standing[EARS_LAYER] = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = ((ears.alternate_worn_icon) ? ears.alternate_worn_icon : 'icons/mob/ears.dmi'))
var/mutable_appearance/ears_overlay = overlays_standing[EARS_LAYER]
if(OFFSET_EARS in dna.species.offset_features)
ears_overlay.pixel_x += dna.species.offset_features[OFFSET_EARS][1]
@@ -271,6 +270,32 @@ There are several things that need to be remembered:
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
inv.update_icon()
/*
if(!shoes && bloody_feet)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
if(dna.features["taur"] != "None")
if(dna.features["taur"] in GLOB.noodle_taurs)
bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "snekbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
if(get_num_legs() < 2)
if(has_left_leg())
bloody_overlay.icon_state = "snekbloodyfeet_left"
else if(has_right_leg())
bloody_overlay.icon_state = "snekbloodyfeet_right"
else if(dna.features["taur"] in GLOB.paw_taurs)
bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "pawbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
if(get_num_legs() < 2)
if(has_left_leg())
bloody_overlay.icon_state = "pawbloodyfeet_left"
else if(has_right_leg())
bloody_overlay.icon_state = "pawbloodyfeet_right"
else
if(get_num_legs() < 2)
if(has_left_leg())
bloody_overlay.icon_state = "bloodyfeet_left"
else if(has_right_leg())
bloody_overlay.icon_state = "bloodyfeet_right"
overlays_standing[GLOVES_LAYER] = bloody_overlay*/
if(shoes)
var/obj/item/clothing/shoes/S = shoes
@@ -279,17 +304,15 @@ There are several things that need to be remembered:
if(hud_used.inventory_shown) //if the inventory is open
client.screen += shoes //add it to client's screen
update_observer_view(shoes,1)
var/alt_icon = S.alternate_worn_icon || 'icons/mob/feet.dmi'
var/variation_flag = NONE
if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE)
alt_icon = 'icons/mob/feet_digi.dmi'
variation_flag |= STYLE_DIGITIGRADE
if(S.mutantrace_variation)
if(S.adjusted == ALT_STYLE)
S.alternate_worn_icon = 'icons/mob/feet_digi.dmi'
else
S.alternate_worn_icon = null
var/t_state = shoes.item_state
if (!t_state)
t_state = shoes.icon_state
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(t_state, SHOES_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(state = t_state, default_layer = SHOES_LAYER, default_icon_file = ((shoes.alternate_worn_icon) ? shoes.alternate_worn_icon : 'icons/mob/feet.dmi'))
var/mutable_appearance/shoes_overlay = overlays_standing[SHOES_LAYER]
if(OFFSET_SHOES in dna.species.offset_features)
shoes_overlay.pixel_x += dna.species.offset_features[OFFSET_SHOES][1]
@@ -327,18 +350,13 @@ There are several things that need to be remembered:
if(head)
remove_overlay(HEAD_LAYER)
var/obj/item/clothing/head/H = head
var/alt_icon = H.alternate_worn_icon || 'icons/mob/head.dmi'
var/muzzled = FALSE
var/variation_flag = NONE
if(("mam_snouts" in dna.species.default_features) && dna.features["mam_snouts"] != "None")
muzzled = TRUE
if(!muzzled && ("snout" in dna.species.default_features) && dna.features["snout"] != "None")
muzzled = TRUE
if(muzzled && H.mutantrace_variation & STYLE_MUZZLE)
alt_icon = 'icons/mob/head_muzzled.dmi'
variation_flag |= STYLE_MUZZLE
if(H.mutantrace_variation)
if(H.muzzle_var == ALT_STYLE)
H.alternate_worn_icon = 'icons/mob/head_muzzled.dmi'
else
H.alternate_worn_icon = null
overlays_standing[HEAD_LAYER] = H.build_worn_icon(H.icon_state, HEAD_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
overlays_standing[HEAD_LAYER] = H.build_worn_icon(state = H.icon_state, default_layer = HEAD_LAYER, default_icon_file = ((head.alternate_worn_icon) ? H.alternate_worn_icon : 'icons/mob/head.dmi'))
var/mutable_appearance/head_overlay = overlays_standing[HEAD_LAYER]
if(OFFSET_HEAD in dna.species.offset_features)
@@ -364,7 +382,7 @@ There are several things that need to be remembered:
if(!t_state)
t_state = belt.icon_state
overlays_standing[BELT_LAYER] = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = 'icons/mob/belt.dmi')
overlays_standing[BELT_LAYER] = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = ((belt.alternate_worn_icon) ? belt.alternate_worn_icon : 'icons/mob/belt.dmi'))
var/mutable_appearance/belt_overlay = overlays_standing[BELT_LAYER]
if(OFFSET_BELT in dna.species.offset_features)
belt_overlay.pixel_x += dna.species.offset_features[OFFSET_BELT][1]
@@ -391,41 +409,30 @@ There are several things that need to be remembered:
client.screen += wear_suit
update_observer_view(wear_suit,1)
var/worn_icon = wear_suit.alternate_worn_icon || 'icons/mob/suit.dmi'
var/center = FALSE
var/dimension_x = 32
var/dimension_y = 32
var/variation_flag = NONE
var/datum/sprite_accessory/taur/T
if("taur" in dna.species.mutant_bodyparts)
T = GLOB.taur_list[dna.features["taur"]]
if(!item_level_support && !S.force_alternate_icon)
if(S.mutantrace_variation) //Just make sure we've got this checked too
if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE) //are we not a taur, but we have Digitigrade legs? Run this check first, then.
S.alternate_worn_icon = 'icons/mob/suit_digi.dmi'
else
S.alternate_worn_icon = null
if(!item_level_support && S.mutantrace_variation)
if(T?.taur_mode)
var/init_worn_icon = worn_icon
variation_flag |= S.mutantrace_variation & T.taur_mode || S.mutantrace_variation & T.alt_taur_mode
switch(variation_flag)
if(STYLE_HOOF_TAURIC)
worn_icon = 'icons/mob/taur_hooved.dmi'
if(STYLE_SNEK_TAURIC)
worn_icon = 'icons/mob/taur_naga.dmi'
if(STYLE_PAW_TAURIC)
worn_icon = 'icons/mob/taur_canine.dmi'
if(worn_icon != init_worn_icon) //worn icon sprite was changed, taur offsets will have to be applied.
center = T.center
dimension_x = T.dimension_x
dimension_y = T.dimension_y
else if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE) //not a taur, but digitigrade legs.
worn_icon = 'icons/mob/suit_digi.dmi'
variation_flag |= STYLE_DIGITIGRADE
if(S.tauric == TRUE) //Are we a suit with tauric mode possible?
if(S.taurmode == SNEK_TAURIC)
S.alternate_worn_icon = 'icons/mob/taur_naga.dmi'
if(S.taurmode == PAW_TAURIC)
S.alternate_worn_icon = 'icons/mob/taur_canine.dmi'
if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE)
S.alternate_worn_icon = 'icons/mob/suit_digi.dmi'
else if(S.taurmode == NOT_TAURIC && S.adjusted == NORMAL_STYLE)
S.alternate_worn_icon = null
overlays_standing[SUIT_LAYER] = S.build_worn_icon(wear_suit.icon_state, SUIT_LAYER, worn_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
overlays_standing[SUIT_LAYER] = S.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = ((wear_suit.alternate_worn_icon) ? S.alternate_worn_icon : 'icons/mob/suit.dmi'))
var/mutable_appearance/suit_overlay = overlays_standing[SUIT_LAYER]
if(OFFSET_SUIT in dna.species.offset_features)
suit_overlay.pixel_x += dna.species.offset_features[OFFSET_SUIT][1]
suit_overlay.pixel_y += dna.species.offset_features[OFFSET_SUIT][2]
if(center)
suit_overlay = center_image(suit_overlay, dimension_x, dimension_y)
if(!item_level_support && S.center)
suit_overlay = center_image(suit_overlay, S.dimension_x, S.dimension_y)
overlays_standing[SUIT_LAYER] = suit_overlay
update_hair()
update_mutant_bodyparts()
@@ -461,18 +468,13 @@ There are several things that need to be remembered:
if(wear_mask)
var/obj/item/clothing/mask/M = wear_mask
remove_overlay(FACEMASK_LAYER)
var/alt_icon = M.alternate_worn_icon || 'icons/mob/mask.dmi'
var/muzzled = FALSE
var/variation_flag = NONE
if(("mam_snouts" in dna.species.default_features) && dna.features["mam_snouts"] != "None")
muzzled = TRUE
if(!muzzled && ("snout" in dna.species.default_features) && dna.features["snout"] != "None")
muzzled = TRUE
if(muzzled && M.mutantrace_variation & STYLE_MUZZLE)
alt_icon = 'icons/mob/mask_muzzled.dmi'
variation_flag |= STYLE_MUZZLE
if(M.mutantrace_variation)
if(M.muzzle_var == ALT_STYLE)
M.alternate_worn_icon = 'icons/mob/mask_muzzled.dmi'
else
M.alternate_worn_icon = null
overlays_standing[FACEMASK_LAYER] = M.build_worn_icon(wear_mask.icon_state, FACEMASK_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
overlays_standing[FACEMASK_LAYER] = M.build_worn_icon(state = wear_mask.icon_state, default_layer = FACEMASK_LAYER, default_icon_file = ((wear_mask.alternate_worn_icon) ? M.alternate_worn_icon : 'icons/mob/mask.dmi'))
var/mutable_appearance/mask_overlay = overlays_standing[FACEMASK_LAYER]
if(OFFSET_FACEMASK in dna.species.offset_features)
@@ -494,11 +496,11 @@ There are several things that need to be remembered:
apply_overlay(BACK_LAYER)
/proc/wear_female_version(t_color, icon, layer, type)
var/index = "[t_color]-[icon]"
var/index = t_color
var/icon/female_clothing_icon = GLOB.female_clothing_icons[index]
if(!female_clothing_icon) //Create standing/laying icons if they don't exist
generate_female_clothing(index,t_color,icon,type)
return mutable_appearance(GLOB.female_clothing_icons[index], layer = -layer)
return mutable_appearance(GLOB.female_clothing_icons[t_color], layer = -layer)
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
var/list/out = new
@@ -570,11 +572,11 @@ generate/load female uniform sprites matching all previously decided variables
*/
/obj/item/proc/build_worn_icon(state = "", default_layer = 0, default_icon_file = null, isinhands = FALSE, femaleuniform = NO_FEMALE_UNIFORM, style_flags = NONE, use_alt_icon = TRUE)
/obj/item/proc/build_worn_icon(var/state = "", var/default_layer = 0, var/default_icon_file = null, var/isinhands = FALSE, var/femaleuniform = NO_FEMALE_UNIFORM)
//Find a valid icon file from variables+arguments
var/file2use
if(!isinhands && alternate_worn_icon && use_alt_icon)
if(!isinhands && alternate_worn_icon)
file2use = alternate_worn_icon
if(!file2use)
file2use = default_icon_file
@@ -594,7 +596,7 @@ generate/load female uniform sprites matching all previously decided variables
//Get the overlays for this item when it's being worn
//eg: ammo counters, primed grenade flashes, etc.
var/list/worn_overlays = worn_overlays(isinhands, file2use, style_flags)
var/list/worn_overlays = worn_overlays(isinhands, file2use)
if(worn_overlays && worn_overlays.len)
standing.overlays.Add(worn_overlays)
@@ -673,8 +675,6 @@ generate/load female uniform sprites matching all previously decided variables
. += "-robotic"
if(BP.use_digitigrade)
. += "-digitigrade[BP.use_digitigrade]"
if(BP.digitigrade_type)
. += "-[BP.digitigrade_type]"
if(BP.dmg_overlay_type)
. += "-[BP.dmg_overlay_type]"
if(BP.body_markings)
+3 -3
View File
@@ -80,7 +80,7 @@
//Second link in a breath chain, calls check_breath()
/mob/living/carbon/proc/breathe()
var/obj/item/organ/lungs = getorganslot(ORGAN_SLOT_LUNGS)
if(reagents.has_reagent(/datum/reagent/toxin/lexorin))
if(reagents.has_reagent("lexorin"))
return
if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
return
@@ -156,7 +156,7 @@
//CRIT
if(!breath || (breath.total_moles() == 0) || !lungs)
if(reagents.has_reagent(/datum/reagent/medicine/epinephrine) && lungs)
if(reagents.has_reagent("epinephrine") && lungs)
return
adjustOxyLoss(1)
@@ -357,7 +357,7 @@
return
// No decay if formaldehyde in corpse or when the corpse is charred
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 15) || HAS_TRAIT(src, TRAIT_HUSK))
if(reagents.has_reagent("formaldehyde", 15) || HAS_TRAIT(src, TRAIT_HUSK))
return
// Also no decay if corpse chilled or not organic/undead
@@ -369,23 +369,6 @@
retaliate(L)
return ..()
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M)
if(M.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB))
retaliate(M)
else if(M.a_intent == INTENT_DISARM && prob(MONKEY_RETALIATE_DISARM_PROB))
retaliate(M)
return ..()
/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L)
if(L.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB))
retaliate(L)
return ..()
/mob/living/carbon/monkey/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
if(user.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB))
retaliate(user)
return ..()
/mob/living/carbon/monkey/attack_paw(mob/living/L)
if(L.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB))
retaliate(L)
@@ -66,7 +66,7 @@
. = ..()
remove_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE)
var/amount
if(reagents.has_reagent(/datum/reagent/medicine/morphine))
if(reagents.has_reagent("morphine"))
amount = -1
if(amount)
add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
@@ -6,55 +6,37 @@
..()
/mob/living/carbon/monkey/attack_paw(mob/living/M)
. = ..()
if(!.) //unsuccessful monkey bite.
return
var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
if(M.limb_destroyer)
dismembering_strike(M, affecting.body_zone)
var/dmg = rand(1, 5)
apply_damage(dmg, BRUTE, affecting)
/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L)
. = ..()
if(!.) //unsuccessful larva bite
return
var/damage = rand(1, 3)
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
if(..()) //successful monkey bite.
var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
apply_damage(damage, BRUTE, affecting)
if(M.limb_destroyer)
dismembering_strike(M, affecting.body_zone)
if(stat != DEAD)
var/dmg = rand(1, 5)
apply_damage(dmg, BRUTE, affecting)
/mob/living/carbon/monkey/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
. = ..(user, TRUE)
if(.)
return
var/hulk_verb = pick("smash","pummel")
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
var/message = "[user] has [hulk_verb]ed [src]!"
visible_message("<span class='danger'>[message]</span>", \
"<span class='userdanger'>[message]</span>")
adjustBruteLoss(15)
return TRUE
/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L)
if(..()) //successful larva bite.
var/damage = rand(1, 3)
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
apply_damage(damage, BRUTE, affecting)
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M)
. = ..()
if(.) //To allow surgery to return properly.
if(..()) //To allow surgery to return properly.
return
switch(M.a_intent)
if(INTENT_HELP)
if("help")
help_shake_act(M)
if(INTENT_GRAB)
if("grab")
grabbedby(M)
if(INTENT_HARM)
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt [src]!</span>")
return
if("harm")
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
if (prob(75))
visible_message("<span class='danger'>[M] has punched [name]!</span>", \
@@ -78,7 +60,7 @@
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [name]!</span>", \
"<span class='userdanger'>[M] has attempted to punch [name]!</span>", null, COMBAT_MESSAGE_RANGE)
if(INTENT_DISARM)
if("disarm")
if(!IsUnconscious())
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
if (prob(25))
@@ -92,51 +74,50 @@
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", "<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M)
. = ..()
if(!.) // the attack was blocked or was help/grab intent
return
if (M.a_intent == INTENT_HARM)
if ((prob(95) && health > 0))
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
var/damage = rand(15, 30)
if (damage >= 25)
damage = rand(20, 40)
if(AmountUnconscious() < 300)
Unconscious(rand(200, 300))
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
"<span class='userdanger'>[M] has wounded [name]!</span>", null, COMBAT_MESSAGE_RANGE)
if(..()) //if harm or disarm intent.
if (M.a_intent == INTENT_HARM)
if ((prob(95) && health > 0))
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
var/damage = rand(15, 30)
if (damage >= 25)
damage = rand(20, 40)
if(AmountUnconscious() < 300)
Unconscious(rand(200, 300))
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
"<span class='userdanger'>[M] has wounded [name]!</span>", null, COMBAT_MESSAGE_RANGE)
else
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
"<span class='userdanger'>[M] has slashed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
log_combat(M, src, "attacked")
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
if(!dismembering_strike(M, affecting.body_zone)) //Dismemberment successful
return 1
apply_damage(damage, BRUTE, affecting)
else
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
"<span class='userdanger'>[M] has slashed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>", null, COMBAT_MESSAGE_RANGE)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
log_combat(M, src, "attacked")
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
if(!dismembering_strike(M, affecting.body_zone)) //Dismemberment successful
return 1
apply_damage(damage, BRUTE, affecting)
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>", null, COMBAT_MESSAGE_RANGE)
else
var/obj/item/I = null
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(prob(95))
Knockdown(20)
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
"<span class='userdanger'>[M] has tackled down [name]!</span>", null, COMBAT_MESSAGE_RANGE)
else
I = get_active_held_item()
if(dropItemToGround(I))
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", "<span class='userdanger'>[M] has disarmed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
if (M.a_intent == INTENT_DISARM)
var/obj/item/I = null
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(prob(95))
Knockdown(20)
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
"<span class='userdanger'>[M] has tackled down [name]!</span>", null, COMBAT_MESSAGE_RANGE)
else
I = null
log_combat(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
updatehealth()
I = get_active_held_item()
if(dropItemToGround(I))
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", "<span class='userdanger'>[M] has disarmed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
else
I = null
log_combat(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
updatehealth()
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
. = ..()
@@ -151,19 +132,17 @@
apply_damage(damage, M.melee_damage_type, affecting)
/mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M)
. = ..()
if(!.) //unsuccessful slime attack
return
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(20, 40)
var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
if(!dam_zone) //Dismemberment successful
return 1
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
apply_damage(damage, BRUTE, affecting)
if(..()) //successful slime attack
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(20, 40)
var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
if(!dam_zone) //Dismemberment successful
return 1
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
apply_damage(damage, BRUTE, affecting)
/mob/living/carbon/monkey/acid_act(acidpwr, acid_volume, bodyzone_hit)
. = 1
+29 -1
View File
@@ -1,3 +1,31 @@
//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
/mob/living/carbon/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/final_pixel_y = pixel_y
var/final_dir = dir
var/changed = 0
if(lying != lying_prev && rotate_on_lying)
changed++
ntransform.TurnTo(lying_prev,lying)
if(lying == 0) //Lying to standing
final_pixel_y = get_standard_pixel_y_offset()
else //if(lying != 0)
if(lying_prev == 0) //Standing to lying
pixel_y = get_standard_pixel_y_offset()
final_pixel_y = get_standard_pixel_y_offset(lying)
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
if(resize != RESIZE_DEFAULT_SIZE)
changed++
ntransform.Scale(resize)
resize = RESIZE_DEFAULT_SIZE
if(changed)
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
/mob/living/carbon
var/list/overlays_standing[TOTAL_LAYERS]
@@ -200,7 +228,7 @@
//Overlays for the worn overlay so you can overlay while you overlay
//eg: ammo counters, primed grenade flashing, etc.
//"icon_file" is used automatically for inhands etc. to make sure it gets the right inhand file
/obj/item/proc/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
/obj/item/proc/worn_overlays(isinhands = FALSE, icon_file)
. = list()
+1 -3
View File
@@ -91,9 +91,7 @@
if(mind && mind.name && mind.active && !istype(T.loc, /area/ctf) && !(signal & COMPONENT_BLOCK_DEATH_BROADCAST))
var/rendered = "<span class='deadsay'><b>[mind.name]</b> has died at <b>[get_area_name(T)]</b>.</span>"
deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
if (client && client.prefs && client.prefs.auto_ooc)
if (!(client.prefs.chat_toggles & CHAT_OOC))
client.prefs.chat_toggles ^= CHAT_OOC
if (client)
client.move_delay = initial(client.move_delay)
+3 -3
View File
@@ -1225,7 +1225,7 @@
clamp_unconscious_to = 0,
clamp_immobility_to = 0,
reset_misc = TRUE,
healing_chems = list(/datum/reagent/medicine/inaprovaline = 3, /datum/reagent/medicine/synaptizine = 10, /datum/reagent/medicine/regen_jelly = 10, /datum/reagent/medicine/stimulants = 10),
healing_chems = list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10),
message = "<span class='boldnotice'>You feel a surge of energy!</span>",
stamina_buffer_boost = 0, //restores stamina buffer rather than just health
scale_stamina_loss_recovery, //defaults to null. if this is set, restores loss * this stamina. make sure it's a fraction.
@@ -1252,5 +1252,5 @@
updatehealth()
update_stamina()
update_canmove()
if(healing_chems)
reagents.add_reagent_list(healing_chems)
for(var/chem in healing_chems)
reagents.add_reagent(chem, healing_chems[chem])
+19 -114
View File
@@ -36,50 +36,7 @@
/mob/living/proc/on_hit(obj/item/projectile/P)
return
/mob/living/proc/check_shields(atom/AM, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
var/block_chance_modifier = round(damage / -3)
for(var/obj/item/I in held_items)
if(!istype(I, /obj/item/clothing))
var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
if(I.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return TRUE
return FALSE
/mob/living/proc/check_reflect(def_zone) //Reflection checks for anything in your hands, based on the reflection chance of the object(s)
for(var/obj/item/I in held_items)
if(I.IsReflect(def_zone))
return TRUE
return FALSE
/mob/living/proc/reflect_bullet_check(obj/item/projectile/P, def_zone)
if(P.is_reflectable && check_reflect(def_zone)) // Checks if you've passed a reflection% check
visible_message("<span class='danger'>The [P.name] gets reflected by [src]!</span>", \
"<span class='userdanger'>The [P.name] gets reflected by [src]!</span>")
// Find a turf near or on the original location to bounce to
if(P.starting)
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(src)
// redirect the projectile
P.original = locate(new_x, new_y, P.z)
P.starting = curloc
P.firer = src
P.yo = new_y - curloc.y
P.xo = new_x - curloc.x
var/new_angle_s = P.Angle + rand(120,240)
while(new_angle_s > 180) // Translate to regular projectile degrees
new_angle_s -= 360
P.setAngle(new_angle_s)
return TRUE
return FALSE
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
if(reflect_bullet_check(P, def_zone))
return -1 // complete projectile permutation
if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration))
P.on_hit(src, 100, def_zone)
return 2
var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null)
if(!P.nodamage)
apply_damage(P.damage, P.damage_type, def_zone, armor)
@@ -98,32 +55,9 @@
else
return 0
/mob/living/proc/catch_item(obj/item/I, skip_throw_mode_check = FALSE)
return FALSE
/mob/living/proc/embed_item(obj/item/I)
return
/mob/living/proc/can_embed(obj/item/I)
return FALSE
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE)
var/obj/item/I
var/throwpower = 30
if(isitem(AM))
I = AM
throwpower = I.throwforce
if(check_shields(AM, throwpower, "\the [AM.name]", THROWN_PROJECTILE_ATTACK))
hitpush = FALSE
skipcatch = TRUE
blocked = TRUE
else if(I && I.throw_speed >= EMBED_THROWSPEED_THRESHOLD && can_embed(I, src) && prob(I.embedding.embed_chance) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE) && (!HAS_TRAIT(src, TRAIT_AUTO_CATCH_ITEM) || incapacitated() || get_active_held_item()))
embed_item(I)
hitpush = FALSE
skipcatch = TRUE //can't catch the now embedded item
if(I)
if(!skipcatch && isturf(I.loc) && catch_item(I))
return TRUE
if(istype(AM, /obj/item))
var/obj/item/I = AM
var/zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
var/dtype = BRUTE
var/volume = I.get_volume_by_throwforce_and_or_w_class()
@@ -280,24 +214,6 @@
Move(user.loc)
return 1
/mob/living/attack_hand(mob/user)
..() //Ignoring parent return value here.
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_HAND, user)
if((user != src) && user.a_intent != INTENT_HELP && check_shields(user, 0, user.name, attack_type = UNARMED_ATTACK))
log_combat(user, src, "attempted to touch")
visible_message("<span class='warning'>[user] attempted to touch [src]!</span>")
return TRUE
/mob/living/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
if(user.a_intent == INTENT_HARM)
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='notice'>You don't want to hurt [src]!</span>")
return TRUE
var/hulk_verb = pick("smash","pummel")
if(user != src && check_shields(user, 15, "the [hulk_verb]ing"))
return TRUE
..()
return FALSE
/mob/living/attack_slime(mob/living/simple_animal/slime/M)
if(!SSticker.HasRoundStarted())
@@ -313,12 +229,6 @@
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(20, 40)
if(check_shields(M, damage, "the [M.name]"))
return FALSE
if (stat != DEAD)
log_combat(M, src, "attacked")
M.do_attack_animation(src)
@@ -335,8 +245,7 @@
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
if(check_shields(M, rand(M.melee_damage_lower, M.melee_damage_upper), "the [M.name]", MELEE_ATTACK, M.armour_penetration))
return FALSE
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
M.do_attack_animation(src)
@@ -347,6 +256,10 @@
/mob/living/attack_paw(mob/living/carbon/monkey/M)
if(isturf(loc) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return FALSE
if (M.a_intent == INTENT_HARM)
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
@@ -355,8 +268,6 @@
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
to_chat(M, "<span class='warning'>You can't bite with your mouth covered!</span>")
return FALSE
if(check_shields(M, 0, "the [M.name]"))
return FALSE
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
if (prob(75))
log_combat(M, src, "attacked")
@@ -371,16 +282,15 @@
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
switch(L.a_intent)
if(INTENT_HELP)
if("help")
visible_message("<span class='notice'>[L.name] rubs its head against [src].</span>")
return FALSE
else
if(HAS_TRAIT(L, TRAIT_PACIFISM))
to_chat(L, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
if(L != src && check_shields(L, rand(1, 3), "the [L.name]"))
return FALSE
return
L.do_attack_animation(src)
if(prob(90))
log_combat(L, src, "attacked")
@@ -391,29 +301,24 @@
else
visible_message("<span class='danger'>[L.name] has attempted to bite [src]!</span>", \
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return FALSE
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
if((M != src) && M.a_intent != INTENT_HELP && check_shields(M, 0, "the [M.name]"))
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
return FALSE
switch(M.a_intent)
if (INTENT_HELP)
if(!isalien(src)) //I know it's ugly, but the alien vs alien attack_alien behaviour is a bit different.
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
if ("help")
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
return FALSE
if (INTENT_GRAB)
if ("grab")
grabbedby(M)
return FALSE
if(INTENT_HARM)
if("harm")
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
if(!isalien(src))
M.do_attack_animation(src)
M.do_attack_animation(src)
return TRUE
if(INTENT_DISARM)
if(!isalien(src))
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
if("disarm")
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
return TRUE
/mob/living/ex_act(severity, target, origin)
@@ -464,7 +369,7 @@
to_chat(src, "<span class='userdanger'>You resist Nar'Sie's influence... but not all of it. <i>Run!</i></span>")
adjustBruteLoss(35)
if(src && reagents)
reagents.add_reagent(/datum/reagent/toxin/heparin, 5)
reagents.add_reagent("heparin", 5)
return FALSE
if(GLOB.cult_narsie && GLOB.cult_narsie.souls_needed[src])
GLOB.cult_narsie.souls_needed -= src
+1 -3
View File
@@ -111,6 +111,4 @@
var/list/diseases = list() // list of all diseases in a mob
var/list/disease_resistances = list()
var/drag_slowdown = TRUE //Whether the mob is slowed down when dragging another prone mob
var/rotate_on_lying = FALSE
var/drag_slowdown = TRUE //Whether the mob is slowed down when dragging another prone mob
+12 -8
View File
@@ -260,6 +260,15 @@
viewalerts = 1
src << browse(dat, "window=aialerts&can_close=0")
/mob/living/silicon/ai/proc/ai_roster()
var/dat = "<html><head><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
dat += GLOB.data_core.get_manifest()
dat += "</body></html>"
src << browse(dat, "window=airoster")
onclose(src, "airoster")
/mob/living/silicon/ai/proc/ai_call_shuttle()
if(control_disabled)
to_chat(usr, "<span class='warning'>Wireless control is disabled!</span>")
@@ -672,23 +681,18 @@
"green face" = 'icons/mob/ai.dmi',
"xeno queen" = 'icons/mob/alien.dmi',
"horror" = 'icons/mob/ai.dmi',
"creature" = 'icons/mob/ai.dmi',
"custom"
"creature" = 'icons/mob/ai.dmi'
)
input = input("Please select a hologram:") as null|anything in icon_list
if(input)
qdel(holo_icon)
switch(input)
if("custom")
if(client?.prefs?.custom_holoform_icon)
holo_icon = client.prefs.get_filtered_holoform(HOLOFORM_FILTER_AI)
else
holo_icon = getHologramIcon(icon('icons/mob/ai.dmi', "female"))
else if("xeno queen")
if("xeno queen")
holo_icon = getHologramIcon(icon(icon_list[input],"alienq"))
else
holo_icon = getHologramIcon(icon(icon_list[input], input))
return
/mob/living/silicon/ai/proc/corereturn()
set category = "Malfunction"
@@ -1,9 +1,15 @@
/mob/living/silicon/ai/attacked_by(obj/item/I, mob/living/user, def_zone)
. = ..()
if(!.)
return FALSE
if(I.force && I.damtype != STAMINA && stat != DEAD) //only sparks if real damage is dealt.
spark_system.start()
return ..()
/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M)
if(!SSticker.HasRoundStarted())
to_chat(M, "You cannot attack people before the game has started.")
return
..()
/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user)
return //immune to slimes
@@ -68,7 +68,7 @@
// Use this when setting the aiEye's location.
// It will also stream the chunk that the new loc is in.
/mob/camera/aiEye/proc/setLoc(T, force_update = FALSE, dir)
/mob/camera/aiEye/proc/setLoc(T, force_update = FALSE)
if(ai)
if(!isturf(ai.loc))
return
@@ -88,7 +88,7 @@
//Holopad
if(istype(ai.current, /obj/machinery/holopad))
var/obj/machinery/holopad/H = ai.current
H.move_hologram(ai, T, dir)
H.move_hologram(ai, T)
if(ai.camera_light_on)
ai.light_cameras()
if(ai.master_multicam)
@@ -139,7 +139,7 @@
for(var/i = 0; i < max(user.sprint, initial); i += 20)
var/turf/step = get_turf(get_step(user.eyeobj, direct))
if(step)
user.eyeobj.setLoc(step, null, direct)
user.eyeobj.setLoc(step)
user.cooldown = world.timeofday + 5
if(user.acceleration)
@@ -1,28 +0,0 @@
/mob/living/silicon/verb/clear_custom_holoform()
set name = "Clear Custom Holoform"
set desc = "Clear your current custom holoform"
set category = "OOC"
if(!client.prefs)
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
return
client.prefs.custom_holoform_icon = null
client.prefs.cached_holoform_icons = null
to_chat(src, "<span class='boldnotice'>Holoform removed.</span>")
/mob/living/silicon/verb/set_custom_holoform()
set name = "Set Custom Holoform"
set desc = "Set your custom holoform using your current preferences slot and a specified set of gear."
set category = "OOC"
if(!client.prefs)
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
return
if(client.prefs.last_custom_holoform > world.time - CUSTOM_HOLOFORM_DELAY)
to_chat(src, "<span class='warning'>You are attempting to change custom holoforms too fast!</span>")
var/icon/new_holoform = user_interface_custom_holoform(client)
if(new_holoform)
client.prefs.custom_holoform_icon = new_holoform
client.prefs.cached_holoform_icons = null
client.prefs.last_custom_holoform = world.time
to_chat(src, "<span class='boldnotice'>Holoform set.</span>")
+16 -151
View File
@@ -58,12 +58,10 @@
var/canholo = TRUE
var/obj/item/card/id/access_card = null
var/chassis = "repairbot"
var/dynamic_chassis
var/dynamic_chassis_sit = FALSE //whether we're sitting instead of resting spritewise
var/dynamic_chassis_bellyup = FALSE //whether we're lying down bellyup
var/list/possible_chassis //initialized in initialize.
var/list/dynamic_chassis_icons //ditto.
var/list/chassis_pixel_offsets_x //stupid dogborgs
var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE,
"fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE, "borgi" = FALSE ,
"parrot" = FALSE, "bear" = FALSE , "mushroom" = FALSE, "crow" = FALSE ,
"fairy" = FALSE , "spiderbot" = FALSE) //assoc value is whether it can be picked up.
var/static/item_head_icon = 'icons/mob/pai_item_head.dmi'
var/static/item_lh_icon = 'icons/mob/pai_item_lh.dmi'
var/static/item_rh_icon = 'icons/mob/pai_item_rh.dmi'
@@ -71,20 +69,22 @@
var/emitterhealth = 20
var/emittermaxhealth = 20
var/emitterregen = 0.25
var/emitter_next_use = 0
var/emitter_emp_cd = 300
var/emittercd = 50
var/emitteroverloadcd = 100
var/emittersemicd = FALSE
var/radio_short = FALSE
var/radio_short_cooldown = 5 MINUTES
var/radio_short_timerid
var/overload_ventcrawl = 0
var/overload_bulletblock = 0 //Why is this a good idea?
var/overload_maxhealth = 0
canmove = FALSE
var/silent = FALSE
var/brightness_power = 5
var/icon/custom_holoform_icon
/mob/living/silicon/pai/can_unbuckle()
return FALSE
/mob/living/silicon/pai/can_buckle()
return FALSE
/mob/living/silicon/pai/Destroy()
if (loc != card)
@@ -118,13 +118,6 @@
pda.owner = text("[]", src)
pda.name = pda.owner + " (" + pda.ownjob + ")"
possible_chassis = typelist(NAMEOF(src, possible_chassis), list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE,
"fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE, "borgi" = FALSE ,
"parrot" = FALSE, "bear" = FALSE , "mushroom" = FALSE, "crow" = FALSE ,
"fairy" = FALSE , "spiderbot" = FALSE)) //assoc value is whether it can be picked up.
dynamic_chassis_icons = typelist(NAMEOF(src, dynamic_chassis_icons), initialize_dynamic_chassis_icons())
chassis_pixel_offsets_x = typelist(NAMEOF(src, chassis_pixel_offsets_x), default_chassis_pixel_offsets_x())
. = ..()
var/datum/action/innate/pai/software/SW = new
@@ -140,7 +133,8 @@
AR.Grant(src)
AL.Grant(src)
ALM.Grant(src)
emitter_next_use = world.time + 10 SECONDS
emittersemicd = TRUE
addtimer(CALLBACK(src, .proc/emittercool), 600)
/mob/living/silicon/pai/Life()
if(hacking)
@@ -234,7 +228,7 @@
/datum/action/innate/pai/shell/Trigger()
..()
if(P.holoform)
P.fold_in(FALSE)
P.fold_in(0)
else
P.fold_out()
@@ -298,132 +292,3 @@
/mob/living/silicon/pai/process()
emitterhealth = CLAMP((emitterhealth + emitterregen), -50, emittermaxhealth)
/mob/living/silicon/pai/proc/short_radio()
if(radio_short_timerid)
deltimer(radio_short_timerid)
radio_short = TRUE
to_chat(src, "<span class='danger'>Your radio shorts out!</span>")
radio_short_timerid = addtimer(CALLBACK(src, .proc/unshort_radio), radio_short_cooldown, flags = TIMER_STOPPABLE)
/mob/living/silicon/pai/proc/unshort_radio()
radio_short = FALSE
to_chat(src, "<span class='danger'>You feel your radio is operational once more.</span>")
if(radio_short_timerid)
deltimer(radio_short_timerid)
/mob/living/silicon/pai/proc/initialize_dynamic_chassis_icons()
. = list()
var/icon/curr //for inserts
//This is a horrible system and I wish I was not as lazy and did something smarter, like just generating a new icon in memory which is probably more efficient.
//Basic /tg/ cyborgs
.["Cyborg - Engineering (default)"] = process_holoform_icon_filter(icon('icons/mob/robots.dmi', "engineer"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (loaderborg)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "loaderborg"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (handyeng)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "handyeng"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (sleekeng)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "sleekeng"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (marinaeng)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "marinaeng"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (default)"] = process_holoform_icon_filter(icon('icons/mob/robots.dmi', "medical"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (marinamed)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "marinamed"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (eyebotmed)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "eyebotmed"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (default)"] = process_holoform_icon_filter(icon('icons/mob/robots.dmi', "sec"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (sleeksec)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "sleeksec"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (marinasec)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "marinasec"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Clown (default)"] = process_holoform_icon_filter(icon('icons/mob/robots.dmi', "clown"), HOLOFORM_FILTER_PAI, FALSE)
//Citadel dogborgs
//Engi
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valeeng")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeeng-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeeng-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeeng-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (dog - valeeng)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "pupdozer")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "pupdozer-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "pupdozer-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "pupdozer-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (dog - pupdozer)"] = curr
//Med
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "medihound")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihound-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihound-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihound-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (dog - medihound)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "medihounddark")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihounddark-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihounddark-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihounddark-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (dog - medihounddark)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valemed")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valemed-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valemed-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valemed-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (dog - valemed)"] = curr
//Sec
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "k9")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (dog - k9)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "k9dark")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9dark-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9dark-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9dark-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (dog - k9dark)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valesec")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesec-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesec-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesec-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (dog - valesec)"] = curr
//Service
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valeserv")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeserv-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeserv-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeserv-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Service (dog - valeserv)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valeservdark")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeservdark-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeservdark-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeservdark-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Service (dog - valeservdark)"] = curr
//Sci
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valesci")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesci-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesci-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesci-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Science (dog - valesci)"] = curr
//Misc
.["Cyborg - Misc (dog - blade)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/widerobot.dmi', "blade"), HOLOFORM_FILTER_PAI, FALSE)
/mob/living/silicon/pai/proc/default_chassis_pixel_offsets_x()
. = list()
//Engi
.["Cyborg - Engineering (dog - valeeng)"] = -16
.["Cyborg - Engineering (dog - pupdozer)"] = -16
//Med
.["Cyborg - Medical (dog - medihound)"] = -16
.["Cyborg - Medical (dog - medihounddark)"] = -16
.["Cyborg - Medical (dog - valemed)"] = -16
//Sec
.["Cyborg - Security (dog - k9)"] = -16
.["Cyborg - Security (dog - valesec)"] = -16
.["Cyborg - Security (dog - k9dark)"] = -16
//Service
.["Cyborg - Service (dog - valeserv)"] = -16
.["Cyborg - Service (dog - valeservdark)"] = -16
//Sci
.["Cyborg - Security (dog - valesci)"] = -16
//Misc
.["Cyborg - Misc (dog - blade)"] = -16
@@ -8,10 +8,9 @@
return
take_holo_damage(50/severity)
Knockdown(400/severity)
silent = max((3 MINUTES)/severity, silent)
silent = max(30/severity, silent)
if(holoform)
fold_in(force = TRUE)
emitter_next_use = world.time + emitter_emp_cd
//Need more effects that aren't instadeath or permanent law corruption.
/mob/living/silicon/pai/ex_act(severity, target)
@@ -27,14 +26,13 @@
fold_in(force = 1)
Knockdown(200)
//ATTACK HAND IGNORING PARENT RETURN VALUE
/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user)
switch(user.a_intent)
if(INTENT_HELP)
if("help")
visible_message("<span class='notice'>[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.</span>")
if(INTENT_DISARM)
if("disarm")
visible_message("<span class='notice'>[user] boops [src] on the head!</span>")
if(INTENT_HARM)
if("harm")
user.do_attack_animation(src)
if (user.name == master)
visible_message("<span class='notice'>Responding to its master's touch, [src] disengages its holochassis emitter, rapidly losing coherence.</span>")
@@ -43,19 +41,14 @@
if(user.put_in_hands(card))
user.visible_message("<span class='notice'>[user] promptly scoops up [user.p_their()] pAI's card.</span>")
else
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='notice'>You don't want to hurt [src]!</span>")
return
visible_message("<span class='danger'>[user] stomps on [src]!.</span>")
take_holo_damage(2)
else
grabbedby(user)
/mob/living/silicon/pai/bullet_act(obj/item/projectile/P, def_zone)
if(P.stun)
/mob/living/silicon/pai/bullet_act(obj/item/projectile/Proj)
if(Proj.stun)
fold_in(force = TRUE)
visible_message("<span class='warning'>The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!</span>")
. = ..()
src.visible_message("<span class='warning'>The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!</span>")
. = ..(Proj)
/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>")
@@ -70,8 +63,7 @@
emitterhealth = CLAMP((emitterhealth - amount), -50, emittermaxhealth)
if(emitterhealth < 0)
fold_in(force = TRUE)
if(amount > 0)
to_chat(src, "<span class='userdanger'>The impact degrades your holochassis!</span>")
to_chat(src, "<span class='userdanger'>The impact degrades your holochassis!</span>")
return amount
/mob/living/silicon/pai/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
@@ -12,11 +12,12 @@
. = fold_in(force)
return
if(world.time < emitter_next_use)
if(emittersemicd)
to_chat(src, "<span class='warning'>Error: Holochassis emitters recycling. Please try again later.</span>")
return FALSE
emitter_next_use = world.time + emittercd
emittersemicd = TRUE
addtimer(CALLBACK(src, .proc/emittercool), emittercd)
canmove = TRUE
density = TRUE
if(istype(card.loc, /obj/item/pda))
@@ -45,17 +46,20 @@
visible_message("<span class='boldnotice'>[src] folds out its holochassis emitter and forms a holoshell around itself!</span>")
holoform = TRUE
/mob/living/silicon/pai/proc/emittercool()
emittersemicd = FALSE
/mob/living/silicon/pai/proc/fold_in(force = FALSE)
emitter_next_use = world.time + (force? emitteroverloadcd : emittercd)
emittersemicd = TRUE
if(!force)
addtimer(CALLBACK(src, .proc/emittercool), emittercd)
else
addtimer(CALLBACK(src, .proc/emittercool), emitteroverloadcd)
icon_state = "[chassis]"
if(!holoform)
. = fold_out(force)
return
if(force)
short_radio()
visible_message("<span class='warning'>[src] shorts out, collapsing back into their storage card, sparks emitted from their radio antenna!</span>")
else
visible_message("<span class='notice'>[src] deactivates its holochassis emitter and folds back into a compact card!</span>")
visible_message("<span class='notice'>[src] deactivates its holochassis emitter and folds back into a compact card!</span>")
stop_pulling()
if(client)
client.perspective = EYE_PERSPECTIVE
@@ -74,39 +78,28 @@
if(!isturf(loc) && loc != card)
to_chat(src, "<span class='boldwarning'>You can not change your holochassis composite while not on the ground or in your card!</span>")
return FALSE
var/list/choices = list("Preset - Basic", "Preset - Dynamic")
if(CONFIG_GET(flag/pai_custom_holoforms))
choices += "Custom"
var/choicetype = input(src, "What type of chassis do you want to use?") as null|anything in choices
if(!choicetype)
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in possible_chassis
if(!choice)
return FALSE
switch(choicetype)
if("Custom")
chassis = "custom"
if("Preset - Basic")
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in possible_chassis
if(!choice)
return FALSE
chassis = choice
if("Preset - Dynamic")
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in dynamic_chassis_icons
if(!choice)
return FALSE
chassis = "dynamic"
dynamic_chassis = choice
resist_a_rest(FALSE, TRUE)
update_icon()
chassis = choice
icon_state = "[chassis]"
if(resting)
icon_state = "[chassis]_rest"
to_chat(src, "<span class='boldnotice'>You switch your holochassis projection composite to [chassis]</span>")
/mob/living/silicon/pai/lay_down()
. = ..()
if(loc != card)
visible_message("<span class='notice'>[src] [resting? "lays down for a moment..." : "perks up from the ground"]</span>")
update_icon()
..()
update_resting_icon(resting)
/mob/living/silicon/pai/start_pulling(atom/movable/AM, gs)
if(ispAI(AM))
return ..()
/mob/living/silicon/pai/proc/update_resting_icon(rest)
if(rest)
icon_state = "[chassis]_rest"
else
icon_state = "[chassis]"
if(loc != card)
visible_message("<span class='notice'>[src] [rest? "lays down for a moment..." : "perks up from the ground"]</span>")
/mob/living/silicon/pai/start_pulling(atom/movable/AM)
return FALSE
/mob/living/silicon/pai/proc/toggle_integrated_light()
@@ -129,22 +122,3 @@
to_chat(user, "<span class='warning'>[src]'s current form isn't able to be carried!</span>")
return FALSE
return ..()
/mob/living/silicon/pai/verb/toggle_chassis_sit()
set name = "Toggle Chassis Sit"
set category = "IC"
set desc = "Whether or not to try to use a sitting icon versus a resting icon. Takes priority over belly-up resting."
dynamic_chassis_sit = !dynamic_chassis_sit
to_chat(usr, "<span class='boldnotice'>You are now [dynamic_chassis_sit? "sitting" : "lying down"].</span>")
update_icon()
/mob/living/silicon/pai/verb/toggle_chassis_bellyup()
set name = "Toggle Chassis Belly Up"
set category = "IC"
set desc = "Whether or not to try to use a belly up icon while resting. Overridden by sitting."
dynamic_chassis_bellyup = !dynamic_chassis_bellyup
to_chat(usr, "<span class='boldnotice'>You are now lying on your [dynamic_chassis_bellyup? "back" : "front"].</span>")
update_icon()
/mob/living/silicon/pai/can_buckle_others(mob/living/target, atom/buckle_to)
return ispAI(target) && ..()
+1 -8
View File
@@ -5,11 +5,4 @@
..(message)
/mob/living/silicon/pai/binarycheck()
return FALSE
/mob/living/silicon/pai/radio(message, message_mode, list/spans, language)
if((message_mode == "robot") || (message_mode in GLOB.radiochannels))
if(radio_short)
to_chat(src, "<span class='warning'>Your radio is shorted out!</span>")
return ITALICS | REDUCE_RANGE
return ..()
return 0
@@ -283,10 +283,7 @@
dat += "<A href='byond://?src=[REF(src)];software=refresh'>Refresh</A><br>"
// Built-in
dat += "<A href='byond://?src=[REF(src)];software=directives'>Directives</A><br>"
if(radio_short)
dat += "\[RADIO SHORTED - Recalibrating!\]"
else
dat += "<A href='byond://?src=[REF(src)];software=radio;sub=0'>Radio Configuration</A><br>"
dat += "<A href='byond://?src=[REF(src)];software=radio;sub=0'>Radio Configuration</A><br>"
dat += "<A href='byond://?src=[REF(src)];software=image'>Screen Display</A><br>"
//dat += "Text Messaging <br>"
dat += "<br>"
@@ -1,27 +0,0 @@
/mob/living/silicon/pai/update_icon()
if(chassis == "custom") //Make sure custom exists if it's set to custom
custom_holoform_icon = client?.prefs?.get_filtered_holoform(HOLOFORM_FILTER_PAI)
if(!custom_holoform_icon)
chassis = pick(possible_chassis - "custom")
if(chassis == "dynamic") //handle dynamic generated icons
icon = dynamic_chassis_icons[dynamic_chassis]
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)
icon_state = "sit"
else if(dynamic_chassis_bellyup && ("bellyup") in states)
icon_state = "bellyup"
else if("rest" in states)
icon_state = "rest"
rotate_on_lying = FALSE
else if(chassis == "custom")
icon = custom_holoform_icon
icon_state = ""
rotate_on_lying = TRUE
else
icon = initial(icon)
icon_state = "[chassis][resting? "_rest" : (stat == DEAD? "_dead" : "")]"
rotate_on_lying = FALSE
pixel_x = ((chassis == "dynamic") && chassis_pixel_offsets_x[dynamic_chassis]) || 0
update_transform()
+1 -13
View File
@@ -114,10 +114,6 @@
var/cansprint = 1
var/orebox = null
/mob/living/silicon/robot
/mob/living/silicon/robot/get_cell()
return cell
@@ -1302,12 +1298,4 @@
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_health = 1)
if(istype(cell))
cell.charge -= amount*5
/mob/living/silicon/robot/verb/viewmanifest()
set category = "Robot Commands"
set name = "View Crew Manifest"
if(usr.stat == DEAD)
return //won't work if dead
ai_roster()
cell.charge -= amount*5
@@ -13,19 +13,7 @@
spark_system.start()
return ..()
/mob/living/silicon/robot/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
. = ..()
if(.)
spark_system.start()
spawn(0)
step_away(src,user,15)
sleep(3)
step_away(src,user,15)
/mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M)
. = ..()
if(!.) // the attack was blocked or was help/grab intent
return
if (M.a_intent == INTENT_DISARM)
if(!(lying))
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
@@ -42,19 +30,24 @@
visible_message("<span class='danger'>[M] has forced back [src]!</span>", \
"<span class='userdanger'>[M] has forced back [src]!</span>", null, COMBAT_MESSAGE_RANGE)
playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1)
else
..()
return
/mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M)
. = ..()
if(!.) //unsuccessful slime shock
return
var/stunprob = M.powerlevel * 7 + 10
var/damage = M.powerlevel * rand(6,10)
if(prob(stunprob) && M.powerlevel >= 8)
flash_act(affect_silicon = TRUE) //my borg eyes!
if(..()) //successful slime shock
flash_act()
var/stunprob = M.powerlevel * 7 + 10
if(prob(stunprob) && M.powerlevel >= 8)
adjustBruteLoss(M.powerlevel * rand(6,10))
var/damage = rand(1, 3)
if(M.is_adult)
damage += rand(10, 20)
damage = rand(20, 40)
else
damage += rand(2, 17)
damage = rand(5, 35)
damage = round(damage / 2) // borgs receive half damage
adjustBruteLoss(damage)
updatehealth()
@@ -63,17 +56,23 @@
//ATTACK HAND IGNORING PARENT RETURN VALUE
/mob/living/silicon/robot/attack_hand(mob/living/carbon/human/user)
add_fingerprint(user)
if(opened && !wiresexposed && cell && !issilicon(user))
cell.update_icon()
cell.add_fingerprint(user)
user.put_in_active_hand(cell)
to_chat(user, "<span class='notice'>You remove \the [cell].</span>")
cell = null
update_icons()
diag_hud_set_borgcell()
if(opened && !wiresexposed && !issilicon(user))
if(cell)
cell.update_icon()
cell.add_fingerprint(user)
user.put_in_active_hand(cell)
to_chat(user, "<span class='notice'>You remove \the [cell].</span>")
cell = null
update_icons()
diag_hud_set_borgcell()
if(!opened)
return ..()
if(..()) // hulk attack
spark_system.start()
spawn(0)
step_away(src,user,15)
sleep(3)
step_away(src,user,15)
/mob/living/silicon/robot/fire_act()
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
@@ -183,9 +182,9 @@
if (stat != DEAD)
adjustBruteLoss(30)
/mob/living/silicon/robot/bullet_act(obj/item/projectile/P, def_zone)
..()
/mob/living/silicon/robot/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
updatehealth()
if(prob(75) && P.damage > 0)
if(prob(75) && Proj.damage > 0)
spark_system.start()
return 2
@@ -121,10 +121,6 @@
else if(istype(S, /obj/item/stack/marker_beacon))
S.cost = 1
S.source = get_or_create_estorage(/datum/robot_energy_storage/beacon)
else if(istype(S, /obj/item/stack/packageWrap))
S.cost = 1
S.source = get_or_create_estorage(/datum/robot_energy_storage/wrapping_paper)
if(S && S.source)
S.materials = list()
@@ -143,9 +139,6 @@
//Adds flavoursome dogborg items to dogborg variants without mechanical benefits
/obj/item/robot_module/proc/dogborg_equip()
has_snowflake_deadsprite = TRUE
cyborg_pixel_offset = -16
hat_offset = INFINITY
var/obj/item/I = new /obj/item/analyzer/nose/flavour(src)
basic_modules += I
I = new /obj/item/soap/tongue/flavour(src)
@@ -369,21 +362,30 @@
sleeper_overlay = "msleeper"
moduleselect_icon = "medihound"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
hat_offset = INFINITY
if("Medihound Dark")
cyborg_base_icon = "medihounddark"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "mdsleeper"
moduleselect_icon = "medihound"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
hat_offset = INFINITY
if("Vale")
cyborg_base_icon = "valemed"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "valemedsleeper"
moduleselect_icon = "medihound"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
hat_offset = INFINITY
if("Alina")
cyborg_base_icon = "alina-med"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
@@ -391,7 +393,10 @@
sleeper_overlay = "alinasleeper"
moduleselect_icon = "medihound"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
hat_offset = INFINITY
return ..()
/obj/item/robot_module/engineering
@@ -472,20 +477,29 @@
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Pup Dozer")
cyborg_base_icon = "pupdozer"
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "dozersleeper"
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "dozersleeper"
if("Vale")
cyborg_base_icon = "valeeng"
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "valeengsleeper"
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "valeengsleeper"
if("Alina")
cyborg_base_icon = "alina-eng"
special_light_key = "alina"
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "alinasleeper"
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "alinasleeper"
return ..()
/obj/item/robot_module/security
@@ -544,24 +558,36 @@
if("K9")
cyborg_base_icon = "k9"
sleeper_overlay = "ksleeper"
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
if("Alina")
cyborg_base_icon = "alina-sec"
special_light_key = "alina"
sleeper_overlay = "alinasleeper"
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
if("K9 Dark")
cyborg_base_icon = "k9dark"
sleeper_overlay = "k9darksleeper"
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
if("Vale")
cyborg_base_icon = "valesec"
sleeper_overlay = "valesecsleeper"
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
return ..()
/obj/item/robot_module/security/Initialize()
@@ -647,11 +673,11 @@
/obj/item/reagent_containers/spray/cyborg_drying
name = "drying agent spray"
color = "#A000A0"
list_reagents = list(/datum/reagent/drying_agent = 250)
list_reagents = list("drying_agent" = 250)
/obj/item/reagent_containers/spray/cyborg_lube
name = "lube spray"
list_reagents = list(/datum/reagent/lube = 250)
list_reagents = list("lube" = 250)
/obj/item/robot_module/clown
name = "Clown"
@@ -725,17 +751,17 @@
var/obj/item/reagent_containers/O = locate(/obj/item/reagent_containers/food/condiment/enzyme) in basic_modules
var/obj/item/lightreplacer/LR = locate(/obj/item/lightreplacer) in basic_modules
if(O)
O.reagents.add_reagent(/datum/reagent/consumable/enzyme, 2 * coeff)
O.reagents.add_reagent("enzyme", 2 * coeff)
if(LR)
for(var/i in 1 to coeff)
LR.Charge(R)
var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules
if(CD)
CD.reagents.add_reagent(/datum/reagent/drying_agent, 5 * coeff)
CD.reagents.add_reagent("drying_agent", 5 * coeff)
var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules
if(CL)
CL.reagents.add_reagent(/datum/reagent/lube, 2 * coeff)
CL.reagents.add_reagent("lube", 2 * coeff)
/obj/item/robot_module/butler/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
@@ -769,18 +795,24 @@
if("(Service) DarkK9")
cyborg_base_icon = "k50"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "ksleeper"
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "ksleeper"
if("(Service) Vale")
cyborg_base_icon = "valeserv"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "valeservsleeper"
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "valeservsleeper"
if("(Service) ValeDark")
cyborg_base_icon = "valeservdark"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "valeservsleeper"
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "valeservsleeper"
if("(Janitor) Default")
cyborg_base_icon = "janitor"
if("(Janitor) Marina")
@@ -798,8 +830,10 @@
if("(Janitor) Scrubpuppy")
cyborg_base_icon = "scrubpup"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "jsleeper"
has_snowflake_deadsprite = TRUE
cyborg_pixel_offset = -16
dogborg = TRUE
sleeper_overlay = "jsleeper"
return ..()
/obj/item/robot_module/miner
@@ -811,19 +845,13 @@
/obj/item/borg/sight/meson,
/obj/item/storage/bag/ore/cyborg,
/obj/item/pickaxe/drill/cyborg,
/obj/item/twohanded/kinetic_crusher/cyborg,
/obj/item/shovel,
/obj/item/weldingtool/mini,
/obj/item/storage/bag/sheetsnatcher/borg,
/obj/item/t_scanner/adv_mining_scanner,
/obj/item/gun/energy/kinetic_accelerator/cyborg,
/obj/item/gun/energy/plasmacutter/cyborg,
/obj/item/gps/cyborg,
/obj/item/weapon/gripper/mining,
/obj/item/cyborg_clamp,
/obj/item/card/id/miningborg,
/obj/item/stack/marker_beacon,
/obj/item/destTagger,
/obj/item/stack/packageWrap)
/obj/item/stack/marker_beacon)
emag_modules = list(/obj/item/borg/stun)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/miner,
@@ -835,7 +863,7 @@
/obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid", "Blade")
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid")
if(!borg_icon)
return FALSE
switch(borg_icon)
@@ -863,11 +891,6 @@
if("Heavy")
cyborg_base_icon = "heavymin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Blade")
cyborg_base_icon = "blade"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "bladesleeper"
dogborg = TRUE
return ..()
/obj/item/robot_module/syndicate
@@ -1013,8 +1036,3 @@
max_energy = 30
recharge_rate = 1
name = "Marker Beacon Storage"
/datum/robot_energy_storage/wrapping_paper
max_energy = 30
recharge_rate = 1
name = "Wrapping Paper Storage"
@@ -389,15 +389,6 @@
if (aicamera)
return aicamera.selectpicture(user)
/mob/living/silicon/proc/ai_roster()
var/dat = "<html><head><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
dat += GLOB.data_core.get_manifest()
dat += "</body></html>"
src << browse(dat, "window=airoster")
onclose(src, "airoster")
/mob/living/silicon/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/changed = 0
@@ -6,10 +6,7 @@
return 2
/mob/living/silicon/attack_alien(mob/living/carbon/alien/humanoid/M)
. = ..()
if(!.) // the attack was blocked or was help/grab intent
return
if(M.a_intent == INTENT_HARM)
if(..()) //if harm or disarm intent
var/damage = 20
if (prob(90))
log_combat(M, src, "attacked")
@@ -52,33 +49,34 @@
/mob/living/silicon/attack_paw(mob/living/user)
return attack_hand(user)
/mob/living/silicon/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
/mob/living/silicon/attack_larva(mob/living/carbon/alien/larva/L)
if(L.a_intent == INTENT_HELP)
visible_message("[L.name] rubs its head against [src].")
/mob/living/silicon/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
. = ..(user, TRUE)
if(.)
return
..(user, 1)
adjustBruteLoss(rand(10, 15))
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has punched [src]!</span>", \
"<span class='userdanger'>[user] has punched [src]!</span>")
return TRUE
return FALSE
return 1
return 0
//ATTACK HAND IGNORING PARENT RETURN VALUE
/mob/living/silicon/attack_hand(mob/living/carbon/human/M)
. = ..()
if(.) //the attack was blocked
return
switch(M.a_intent)
if (INTENT_HELP)
if ("help")
M.visible_message("[M] pets [src].", \
"<span class='notice'>You pet [src].</span>")
if(INTENT_GRAB)
if("grab")
grabbedby(M)
else
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
playsound(src.loc, 'sound/effects/bang.ogg', 10, 1)
visible_message("<span class='danger'>[M] punches [src], but doesn't leave a dent.</span>", \
"<span class='warning'>[M] punches [src], but doesn't leave a dent.</span>", null, COMBAT_MESSAGE_RANGE)
return 0
/mob/living/silicon/attack_drone(mob/living/simple_animal/drone/M)
if(M.a_intent == INTENT_HARM)
@@ -110,25 +108,19 @@
M.visible_message("<span class='boldwarning'>[M] is thrown off of [src]!</span>")
flash_act(affect_silicon = 1)
/mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone)
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
if(reflect_bullet_check(P, def_zone))
return -1 // complete projectile permutation
if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration))
P.on_hit(src, 100, def_zone)
return 2
if((P.damage_type == BRUTE || P.damage_type == BURN))
adjustBruteLoss(P.damage)
if(prob(P.damage*1.5))
/mob/living/silicon/bullet_act(obj/item/projectile/Proj)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
adjustBruteLoss(Proj.damage)
if(prob(Proj.damage*1.5))
for(var/mob/living/M in buckled_mobs)
M.visible_message("<span class='boldwarning'>[M] is knocked off of [src]!</span>")
unbuckle_mob(M)
M.Knockdown(40)
if(P.stun || P.knockdown)
if(Proj.stun || Proj.knockdown)
for(var/mob/living/M in buckled_mobs)
unbuckle_mob(M)
M.visible_message("<span class='boldwarning'>[M] is knocked off of [src] by the [P]!</span>")
P.on_hit(src)
M.visible_message("<span class='boldwarning'>[M] is knocked off of [src] by the [Proj]!</span>")
Proj.on_hit(src)
return 2
/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash/static)
@@ -1,22 +1,20 @@
/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M)
. = ..()
if(.) //the attack was blocked
return
..()
switch(M.a_intent)
if(INTENT_HELP)
if("help")
if (health > 0)
visible_message("<span class='notice'>[M] [response_help] [src].</span>")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(INTENT_GRAB)
if("grab")
if(grab_state >= GRAB_AGGRESSIVE && isliving(pulling))
vore_attack(M, pulling)
else
grabbedby(M)
if(INTENT_HARM, INTENT_DISARM)
if("harm", "disarm")
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt [src]!</span>")
return
@@ -29,11 +27,12 @@
updatehealth()
return TRUE
/mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
/mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
. = ..(user, TRUE)
if(.)
return
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='notice'>You don't want to hurt [src]!</span>")
return FALSE
..(user, 1)
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has punched [src]!</span>", \
"<span class='userdanger'>[user] has punched [src]!</span>", null, COMBAT_MESSAGE_RANGE)
@@ -41,32 +40,32 @@
return TRUE
/mob/living/simple_animal/attack_paw(mob/living/carbon/monkey/M)
. = ..()
if(.) //successful larva bite
var/damage = rand(1, 3)
attack_threshold_check(damage)
return 1
if(..()) //successful monkey bite.
if(stat != DEAD)
var/damage = rand(1, 3)
attack_threshold_check(damage)
return 1
if (M.a_intent == INTENT_HELP)
if (health > 0)
visible_message("<span class='notice'>[M.name] [response_help] [src].</span>")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
/mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M)
. = ..()
if(!.) // the attack was blocked or was help/grab intent
return
if(M.a_intent == INTENT_DISARM)
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] [response_disarm] [name]!</span>", \
"<span class='userdanger'>[M] [response_disarm] [name]!</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(M, src, "disarmed")
else
var/damage = rand(15, 30)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>", null, COMBAT_MESSAGE_RANGE)
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
attack_threshold_check(damage)
log_combat(M, src, "attacked")
if(..()) //if harm or disarm intent.
if(M.a_intent == INTENT_DISARM)
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] [response_disarm] [name]!</span>", \
"<span class='userdanger'>[M] [response_disarm] [name]!</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(M, src, "disarmed")
else
var/damage = rand(15, 30)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>", null, COMBAT_MESSAGE_RANGE)
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
attack_threshold_check(damage)
log_combat(M, src, "attacked")
return 1
/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L)
. = ..()
@@ -83,8 +82,7 @@
return attack_threshold_check(damage, M.melee_damage_type)
/mob/living/simple_animal/attack_slime(mob/living/simple_animal/slime/M)
. = ..()
if(.) //successful slime shock
if(..()) //successful slime attack
var/damage = rand(15, 25)
if(M.is_adult)
damage = rand(20, 35)
@@ -44,7 +44,7 @@
if(isliving(A))
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(H.reagents.has_reagent(/datum/reagent/fermi/astral) && !H.mind)
if(H.reagents.has_reagent("astral") && !H.mind)
var/datum/reagent/fermi/astral/As = locate(/datum/reagent/fermi/astral) in H.reagents.reagent_list
if(As.originalmind == src.mind && As.current_cycle < 10 && H.stat != DEAD) //So you can return to your body.
to_chat(src, "<span class='warning'><b><i>The intensity of the astrogen in your body is too much allow you to return to yourself yet!</b></i></span>")
@@ -318,9 +318,9 @@
sleep(50)
if(mode == BOT_REPAIRING && src.loc == target_turf)
if(autotile) //Build the floor and include a tile.
target_turf.PlaceOnTop(/turf/open/floor/plasteel, flags = CHANGETURF_INHERIT_AIR)
target_turf.PlaceOnTop(/turf/open/floor/plasteel)
else //Build a hull plating without a floor tile.
target_turf.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
target_turf.PlaceOnTop(/turf/open/floor/plating)
else
var/turf/open/floor/F = target_turf
@@ -334,7 +334,7 @@
if(mode == BOT_REPAIRING && F && src.loc == F)
F.broken = 0
F.burnt = 0
F.PlaceOnTop(/turf/open/floor/plasteel, flags = CHANGETURF_INHERIT_AIR)
F.PlaceOnTop(/turf/open/floor/plasteel)
if(replacetiles && F.type != initial(tiletype.turf_type) && specialtiles && !isplatingturf(F))
anchored = TRUE
@@ -345,7 +345,7 @@
if(mode == BOT_REPAIRING && F && src.loc == F)
F.broken = 0
F.burnt = 0
F.PlaceOnTop(initial(tiletype.turf_type), flags = CHANGETURF_INHERIT_AIR)
F.PlaceOnTop(initial(tiletype.turf_type))
specialtiles -= 1
if(specialtiles == 0)
speak("Requesting refill of custom floortiles to continue replacing.")
@@ -113,7 +113,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
mode = BOT_HUNT
/mob/living/simple_animal/bot/honkbot/attack_hand(mob/living/carbon/human/H)
if(H.a_intent == INTENT_HARM)
if(H.a_intent == "harm")
retaliate(H)
addtimer(CALLBACK(src, .proc/react_buzz), 5)
return ..()
@@ -43,17 +43,17 @@
var/declare_cooldown = 0 //Prevents spam of critical patient alerts.
var/stationary_mode = 0 //If enabled, the Medibot will not move automatically.
//Setting which reagents to use to treat what by default. By id.
var/treatment_brute_avoid = /datum/reagent/medicine/tricordrazine
var/treatment_brute = /datum/reagent/medicine/bicaridine
var/treatment_brute_avoid = "tricordrazine"
var/treatment_brute = "bicaridine"
var/treatment_oxy_avoid = null
var/treatment_oxy = /datum/reagent/medicine/dexalin
var/treatment_fire_avoid = /datum/reagent/medicine/tricordrazine
var/treatment_fire = /datum/reagent/medicine/kelotane
var/treatment_tox_avoid = /datum/reagent/medicine/tricordrazine
var/treatment_tox = /datum/reagent/medicine/charcoal
var/treatment_tox_toxlover = /datum/reagent/toxin
var/treatment_oxy = "dexalin"
var/treatment_fire_avoid = "tricordrazine"
var/treatment_fire = "kelotane"
var/treatment_tox_avoid = "tricordrazine"
var/treatment_tox = "charcoal"
var/treatment_tox_toxlover = "toxin"
var/treatment_virus_avoid = null
var/treatment_virus = /datum/reagent/medicine/spaceacillin
var/treatment_virus = "spaceacillin"
var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible.
var/shut_up = 0 //self explanatory :)
@@ -61,9 +61,9 @@
name = "\improper Mysterious Medibot"
desc = "International Medibot of mystery."
skin = "bezerk"
treatment_brute = /datum/reagent/medicine/tricordrazine
treatment_fire = /datum/reagent/medicine/tricordrazine
treatment_tox = /datum/reagent/medicine/tricordrazine
treatment_brute = "tricordrazine"
treatment_fire = "tricordrazine"
treatment_tox = "tricordrazine"
/mob/living/simple_animal/bot/medbot/derelict
name = "\improper Old Medibot"
@@ -71,13 +71,13 @@
skin = "bezerk"
heal_threshold = 0
declare_crit = 0
treatment_oxy = /datum/reagent/toxin/pancuronium
treatment_oxy = "pancuronium"
treatment_brute_avoid = null
treatment_brute = /datum/reagent/toxin/pancuronium
treatment_brute = "pancuronium"
treatment_fire_avoid = null
treatment_fire = /datum/reagent/toxin/sodium_thiopental
treatment_fire = "sodium_thiopental"
treatment_tox_avoid = null
treatment_tox = /datum/reagent/toxin/sodium_thiopental
treatment_tox = "sodium_thiopental"
/mob/living/simple_animal/bot/medbot/update_icon()
cut_overlays()
@@ -369,9 +369,8 @@
//If they're injured, we're using a beaker, and don't have one of our WONDERCHEMS.
if((reagent_glass) && (use_beaker) && ((C.getBruteLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getOxyLoss() >= (heal_threshold + 15))))
for(var/A in reagent_glass.reagents.reagent_list)
var/datum/reagent/R = A
if(!C.reagents.has_reagent(R.type))
for(var/datum/reagent/R in reagent_glass.reagents.reagent_list)
if(!C.reagents.has_reagent(R.id))
return TRUE
//They're injured enough for it!
@@ -478,9 +477,8 @@
//If the patient is injured but doesn't have our special reagent in them then we should give it to them first
if(reagent_id && use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
for(var/A in reagent_glass.reagents.reagent_list)
var/datum/reagent/R = A
if(!C.reagents.has_reagent(R.type))
for(var/datum/reagent/R in reagent_glass.reagents.reagent_list)
if(!C.reagents.has_reagent(R.id))
reagent_id = "internal_beaker"
break
@@ -151,8 +151,7 @@
return
/mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj)
. = ..()
if(. && !QDELETED(src)) //Got hit and not blown up yet.
if(..())
if(prob(50) && !isnull(load))
unload(0)
if(prob(25))
@@ -54,7 +54,7 @@
var/atom/Tsec = drop_location()
new /obj/item/stock_parts/cell/potato(Tsec)
var/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/S = new(Tsec)
S.reagents.add_reagent(/datum/reagent/consumable/ethanol/whiskey, 15)
S.reagents.add_reagent("whiskey", 15)
S.on_reagent_change(ADD_REAGENT)
..()
@@ -38,10 +38,6 @@
. = ..()
verbs += /mob/living/proc/lay_down
/mob/living/simple_animal/pet/cat/ComponentInitialize()
. = ..()
AddElement(/datum/element/wuv, "purrs!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "hisses!", EMOTE_AUDIBLE)
/mob/living/simple_animal/pet/cat/update_canmove()
..()
if(client && stat != DEAD)
@@ -233,6 +229,24 @@
stop_automated_movement = 1
walk_to(src,movement_target,0,3)
/mob/living/simple_animal/pet/cat/attack_hand(mob/living/carbon/human/M)
. = ..()
switch(M.a_intent)
if("help")
wuv(1, M)
if("harm")
wuv(-1, M)
/mob/living/simple_animal/pet/cat/proc/wuv(change, mob/M)
if(change)
if(change > 0)
if(M && stat != DEAD)
new /obj/effect/temp_visual/heart(loc)
emote("me", EMOTE_VISIBLE, "purrs!")
else
if(M && stat != DEAD)
emote("me", EMOTE_VISIBLE, "hisses!")
/mob/living/simple_animal/pet/cat/cak //I told you I'd do it, Remie
name = "Keeki"
desc = "It's a cat made out of cake."
@@ -276,12 +290,10 @@
D.decorate_donut()
/mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L)
. = ..()
if(.) //the attack was blocked
return
..()
if(L.a_intent == INTENT_HARM && L.reagents && !stat)
L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4)
L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4)
L.reagents.add_reagent("nutriment", 0.4)
L.reagents.add_reagent("vitamin", 0.4)
//Cat made
/mob/living/simple_animal/pet/cat/custom_cat
@@ -16,11 +16,6 @@
do_footstep = TRUE
can_be_held = TRUE
/mob/living/simple_animal/pet/dog/ComponentInitialize()
. = ..()
AddElement(/datum/element/wuv, "yaps_happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE)
//Corgis and pugs are now under one dog subtype
/mob/living/simple_animal/pet/dog/corgi
@@ -273,7 +268,7 @@
return
if(!item_to_add)
user.visible_message("[user] pets [src].","<span class='notice'>You rest your hand on [src]'s head for a moment.</span>")
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, src, /datum/mood_event/pet_animal, src)
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "pet_corgi", /datum/mood_event/pet_corgi)
return
if(user && !user.temporarilyRemoveItemFromInventory(item_to_add))
@@ -644,3 +639,22 @@
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
setDir(i)
sleep(1)
/mob/living/simple_animal/pet/dog/attack_hand(mob/living/carbon/human/M)
. = ..()
switch(M.a_intent)
if("help")
wuv(1,M)
if("harm")
wuv(-1,M)
/mob/living/simple_animal/pet/dog/proc/wuv(change, mob/M)
if(change)
if(change > 0)
if(M && stat != DEAD) // Added check to see if this mob (the dog) is dead to fix issue 2454
new /obj/effect/temp_visual/heart(loc)
emote("me", EMOTE_VISIBLE, "yaps happily!")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "pet_corgi", /datum/mood_event/pet_corgi)
else
if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case)
emote("me", EMOTE_VISIBLE, "growls!")
@@ -130,7 +130,6 @@
hacked = TRUE
visualAppearence = CLOCKDRONE
can_be_held = FALSE
mouse_opacity = MOUSE_OPACITY_OPAQUE
flavortext = "<b><span class='nezbere'>You are a cogscarab,</span> a tiny building construct of Ratvar. While you're weak and can't recite scripture, \
you have a set of quick tools, as well as a replica fabricator that can create brass and convert objects.<br><br>Work with the servants of Ratvar \
to construct and maintain defenses at the City of Cogs. If there are no servants, use this time to experiment with base designs!"
@@ -31,9 +31,9 @@
//picky up the drone c:
/mob/living/simple_animal/drone/attack_hand(mob/user)
if(user.a_intent != INTENT_HELP)
return ..() // TODO: convert picking up mobs into an element or component.
mob_try_pickup(user)
..()
if(user.a_intent == INTENT_HELP)
mob_try_pickup(user)
/mob/living/simple_animal/drone/proc/try_reactivate(mob/living/user)
var/mob/dead/observer/G = get_ghost()
@@ -455,12 +455,12 @@
/obj/item/udder/Initialize()
create_reagents(50)
reagents.add_reagent(/datum/reagent/consumable/milk, 20)
reagents.add_reagent("milk", 20)
. = ..()
/obj/item/udder/proc/generateMilk()
if(prob(5))
reagents.add_reagent(/datum/reagent/consumable/milk, rand(5, 10))
reagents.add_reagent("milk", rand(5, 10))
/obj/item/udder/proc/milkAnimal(obj/O, mob/user)
var/obj/item/reagent_containers/glass/G = O
@@ -117,9 +117,9 @@
icon_state = "mouse_gray_dead"
bitesize = 3
eatverb = "devour"
list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2)
list_reagents = list("nutriment" = 3, "vitamin" = 2)
foodtype = GROSS | MEAT | RAW
grind_results = list(/datum/reagent/blood = 20, /datum/reagent/liquidgibs = 5)
grind_results = list("blood" = 20, "liquidgibs" = 5)
/obj/item/reagent_containers/food/snacks/deadmouse/on_grind()
reagents.clear_reagents()
@@ -1,6 +1,6 @@
/mob/living/simple_animal/hostile/retaliate/poison
var/poison_per_bite = 0
var/poison_type = /datum/reagent/toxin
var/poison_type = "toxin"
/mob/living/simple_animal/hostile/retaliate/poison/AttackingTarget()
. = ..()
@@ -424,9 +424,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/mob/living/simple_animal/hostile/guardian/G = input(src, "Pick the guardian you wish to reset", "Guardian Reset") as null|anything in guardians
if(G)
to_chat(src, "<span class='holoparasite'>You attempt to reset <font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font>'s personality...</span>")
var/list/mob/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
if(LAZYLEN(candidates))
var/mob/C = pick(candidates)
var/mob/dead/observer/C = pick(candidates)
to_chat(G, "<span class='holoparasite'>Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.</span>")
to_chat(src, "<span class='holoparasite bold'>Your <font color=\"[G.namedatum.colour]\">[G.real_name]</font> has been successfully reset.</span>")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])")
@@ -498,10 +498,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
return
used = TRUE
to_chat(user, "[use_message]")
var/list/mob/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_HOLOPARASITE)
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_HOLOPARASITE)
if(LAZYLEN(candidates))
var/mob/C = pick(candidates)
var/mob/dead/observer/C = pick(candidates)
spawn_guardian(user, C.key)
else
to_chat(user, "[failure_message]")
@@ -54,8 +54,10 @@
var/blocked = FALSE
if(hasmatchingsummoner(A)) //if the summoner matches don't hurt them
blocked = TRUE
if(L.check_shields(src, 90, "[name]", attack_type = THROWN_PROJECTILE_ATTACK))
blocked = TRUE
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(H.check_shields(src, 90, "[name]", attack_type = THROWN_PROJECTILE_ATTACK))
blocked = TRUE
if(!blocked)
L.drop_all_held_items()
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] slams into you!</span>")
@@ -96,10 +96,10 @@
icon_state = "bananaspider"
bitesize = 3
eatverb = "devours"
list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2)
list_reagents = list("nutriment" = 3, "vitamin" = 2)
foodtype = GROSS | MEAT | RAW
grind_results = list(/datum/reagent/blood = 20, /datum/reagent/liquidgibs = 5)
juice_results = list(/datum/reagent/consumable/banana = 0)
grind_results = list("blood" = 20, "liquidgibs" = 5)
juice_results = list("banana" = 0)
/obj/item/reagent_containers/food/snacks/deadbanana_spider/Initialize()
@@ -140,7 +140,7 @@
var/mob/living/L = target
if(L.reagents)
beegent.reaction_mob(L, INJECT)
L.reagents.add_reagent(beegent.type, rand(1,5))
L.reagents.add_reagent(beegent.id, rand(1,5))
/mob/living/simple_animal/hostile/poison/bees/proc/assign_reagent(datum/reagent/R)
@@ -205,7 +205,7 @@
/mob/living/simple_animal/hostile/poison/bees/toxin/Initialize()
. = ..()
var/datum/reagent/R = pick(typesof(/datum/reagent/toxin))
assign_reagent(GLOB.chemical_reagents_list[R])
assign_reagent(GLOB.chemical_reagents_list[initial(R.id)])
/mob/living/simple_animal/hostile/poison/bees/queen
name = "queen bee"
@@ -225,7 +225,7 @@
if(. && beegent && isliving(target))
var/mob/living/L = target
beegent.reaction_mob(L, TOUCH)
L.reagents.add_reagent(beegent.type, rand(1,5))
L.reagents.add_reagent(beegent.id, rand(1,5))
//PEASENT BEES
@@ -236,7 +236,7 @@
/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B)
if(!B)
return FALSE
if(B.beegent && beegent && B.beegent.type != beegent.type || B.beegent && !beegent || !B.beegent && beegent)
if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent)
return TRUE
return FALSE
@@ -253,10 +253,9 @@
/obj/item/queen_bee/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/syringe))
var/obj/item/reagent_containers/syringe/S = I
var/jelly_amount = S.reagents.get_reagent_amount(/datum/reagent/royal_bee_jelly)
if(jelly_amount)
if(jelly_amount >= 5)
S.reagents.remove_reagent(/datum/reagent/royal_bee_jelly, 5)
if(S.reagents.has_reagent("royal_bee_jelly")) //checked twice, because I really don't want royal bee jelly to be duped
if(S.reagents.has_reagent("royal_bee_jelly",5))
S.reagents.remove_reagent("royal_bee_jelly", 5)
var/obj/item/queen_bee/qb = new(user.drop_location())
qb.queen = new(qb)
if(queen && queen.beegent)
@@ -267,8 +266,8 @@
to_chat(user, "<span class='warning'>You don't have enough royal bee jelly to split a bee in two!</span>")
else
var/datum/reagent/R = GLOB.chemical_reagents_list[S.reagents.get_master_reagent_id()]
if(R && S.reagents.has_reagent(R.type, 5))
S.reagents.remove_reagent(R.type,5)
if(R && S.reagents.has_reagent(R.id, 5))
S.reagents.remove_reagent(R.id,5)
queen.assign_reagent(R)
user.visible_message("<span class='warning'>[user] injects [src]'s genome with [R.name], mutating it's DNA!</span>","<span class='warning'>You inject [src]'s genome with [R.name], mutating it's DNA!</span>")
name = queen.name
@@ -6,7 +6,7 @@
/mob/living/simple_animal/hostile/poison
var/poison_per_bite = 5
var/poison_type = /datum/reagent/toxin
var/poison_type = "toxin"
/mob/living/simple_animal/hostile/poison/AttackingTarget()
. = ..()
@@ -158,7 +158,7 @@
melee_damage_upper = 1
poison_per_bite = 12
move_to_delay = 4
poison_type = /datum/reagent/toxin/venom //all in venom, glass cannon. you bite 5 times and they are DEFINITELY dead, but 40 health and you are extremely obvious. Ambush, maybe?
poison_type = "venom" //all in venom, glass cannon. you bite 5 times and they are DEFINITELY dead, but 40 health and you are extremely obvious. Ambush, maybe?
speed = 1
gold_core_spawnable = NO_SPAWN
@@ -217,7 +217,7 @@
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 1500
poison_type = /datum/reagent/consumable/frostoil
poison_type = "frostoil"
color = rgb(114,228,250)
gold_core_spawnable = NO_SPAWN
@@ -226,7 +226,7 @@
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 1500
poison_type = /datum/reagent/consumable/frostoil
poison_type = "frostoil"
color = rgb(114,228,250)
gold_core_spawnable = NO_SPAWN
@@ -235,7 +235,7 @@
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 1500
poison_type = /datum/reagent/consumable/frostoil
poison_type = "frostoil"
color = rgb(114,228,250)
gold_core_spawnable = NO_SPAWN
@@ -42,7 +42,7 @@
..()
if(iscarbon(target))
var/mob/living/carbon/C = target
C.reagents.add_reagent(/datum/reagent/toxin/leaper_venom, 5)
C.reagents.add_reagent("leaper_venom", 5)
return
if(isanimal(target))
var/mob/living/simple_animal/L = target
@@ -96,7 +96,7 @@
L.Knockdown(50)
if(iscarbon(L))
var/mob/living/carbon/C = L
C.reagents.add_reagent(/datum/reagent/toxin/leaper_venom, 5)
C.reagents.add_reagent("leaper_venom", 5)
if(isanimal(L))
var/mob/living/simple_animal/A = L
A.adjustHealth(25)
@@ -105,6 +105,7 @@
/datum/reagent/toxin/leaper_venom
name = "Leaper venom"
id = "leaper_venom"
description = "A toxin spat out by leapers that, while harmless in small doses, quickly creates a toxic reaction if too much is in the body."
color = "#801E28" // rgb: 128, 30, 40
toxpwr = 0
@@ -486,7 +486,10 @@ Difficulty: Very Hard
if(isturf(Stuff))
var/turf/T = Stuff
if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors)
var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR)
var/turf/open/O = T.ChangeTurf(NewTerrainFloors)
if(O.air)
var/datum/gas_mixture/G = O.air
G.copy_from_turf(O)
if(prob(florachance) && NewFlora.len && !is_blocked_turf(O, TRUE))
var/atom/Picked = pick(NewFlora)
new Picked(O)
@@ -594,15 +594,12 @@ Difficulty: Normal
var/list/hit_things = list() //we hit these already, ignore them
var/friendly_fire_check = FALSE
var/bursting = FALSE //if we're bursting and need to hit anyone crossing us
var/list/nohurt
/obj/effect/temp_visual/hierophant/blast/Initialize(mapload, new_caster, friendly_fire, list/only_hit_once, list/donthurt = null)
/obj/effect/temp_visual/hierophant/blast/Initialize(mapload, new_caster, friendly_fire, list/only_hit_once)
. = ..()
if(only_hit_once)
hit_things = only_hit_once
friendly_fire_check = friendly_fire
if(donthurt)
hit_things += donthurt
if(new_caster)
hit_things += new_caster
if(ismineralturf(loc)) //drill mineral turfs
@@ -25,7 +25,7 @@
mob_size = MOB_SIZE_LARGE
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
var/list/crusher_loot
var/medal_type
var/score_type = BOSS_SCORE
@@ -24,8 +24,7 @@
var/list/attack_action_types = list()
var/can_talk = FALSE
var/obj/loot_drop = null
var/owner
//Gives player-controlled variants the ability to swap attacks
/mob/living/simple_animal/hostile/asteroid/elite/Initialize(mapload)
. = ..()
@@ -54,14 +53,14 @@
if(ismineralturf(target))
var/turf/closed/mineral/M = target
M.gets_drilled()
//Elites can't talk (normally)!
/mob/living/simple_animal/hostile/asteroid/elite/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
if(can_talk)
. = ..()
return TRUE
return FALSE
/*Basic setup for elite attacks, based on Whoneedspace's megafauna attack setup.
While using this makes the system rely on OnFire, it still gives options for timers not tied to OnFire, and it makes using attacks consistent accross the board for player-controlled elites.*/
@@ -83,11 +82,11 @@ While using this makes the system rely on OnFire, it still gives options for tim
/datum/action/innate/elite_attack/Activate()
M.chosen_attack = chosen_attack_num
to_chat(M, chosen_message)
/mob/living/simple_animal/hostile/asteroid/elite/updatehealth()
. = ..()
update_health_hud()
/mob/living/simple_animal/hostile/asteroid/elite/update_health_hud()
if(hud_used)
var/severity = 0
@@ -145,7 +144,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
gpstag = "Menacing Signal"
desc = "You're not quite sure how a signal can be menacing."
invisibility = 100
/obj/structure/elite_tumor/attack_hand(mob/user)
. = ..()
if(ishuman(user))
@@ -180,7 +179,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
activity = TUMOR_INACTIVE
activator = null
obj/structure/elite_tumor/proc/spawn_elite(var/mob/dead/observer/elitemind)
var/selectedspawn = pick(potentialspawns)
mychild = new selectedspawn(loc)
@@ -200,18 +199,18 @@ obj/structure/elite_tumor/proc/return_elite()
if(boosted)
mychild.maxHealth = mychild.maxHealth * 2
mychild.health = mychild.maxHealth
/obj/structure/elite_tumor/Initialize(mapload)
. = ..()
internal = new/obj/item/gps/internal/elite(src)
START_PROCESSING(SSobj, src)
/obj/structure/elite_tumor/Destroy()
STOP_PROCESSING(SSobj, src)
mychild = null
activator = null
return ..()
/obj/structure/elite_tumor/process()
if(isturf(loc))
for(var/mob/living/simple_animal/hostile/asteroid/elite/elitehere in loc)
@@ -219,7 +218,7 @@ obj/structure/elite_tumor/proc/return_elite()
mychild.adjustHealth(-mychild.maxHealth*0.05)
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(mychild))
H.color = "#FF0000"
/obj/structure/elite_tumor/attackby(obj/item/I, mob/user, params)
. = ..()
if(istype(I, /obj/item/organ/regenerative_core) && activity == TUMOR_INACTIVE && !boosted)
@@ -233,22 +232,21 @@ obj/structure/elite_tumor/proc/return_elite()
desc = "[desc] This one seems to glow with a strong intensity."
qdel(core)
return TRUE
/obj/structure/elite_tumor/proc/arena_checks()
if(activity != TUMOR_ACTIVE || QDELETED(src))
return
INVOKE_ASYNC(src, .proc/fighters_check) //Checks to see if our fighters died.
INVOKE_ASYNC(src, .proc/arena_trap) //Gets another arena trap queued up for when this one runs out.
INVOKE_ASYNC(src, .proc/border_check) //Checks to see if our fighters got out of the arena somehow.
if(!QDELETED(src))
addtimer(CALLBACK(src, .proc/arena_checks), 50)
addtimer(CALLBACK(src, .proc/arena_checks), 50)
/obj/structure/elite_tumor/proc/fighters_check()
if(activator != null && activator.stat == DEAD || activity == TUMOR_ACTIVE && QDELETED(activator))
onEliteWon()
if(mychild != null && mychild.stat == DEAD || activity == TUMOR_ACTIVE && QDELETED(mychild))
onEliteLoss()
/obj/structure/elite_tumor/proc/arena_trap()
var/turf/T = get_turf(src)
if(loc == null)
@@ -259,7 +257,7 @@ obj/structure/elite_tumor/proc/return_elite()
newwall = new /obj/effect/temp_visual/elite_tumor_wall(t, src)
newwall.activator = src.activator
newwall.ourelite = src.mychild
/obj/structure/elite_tumor/proc/border_check()
if(activator != null && get_dist(src, activator) >= 12)
activator.forceMove(loc)
@@ -269,7 +267,7 @@ obj/structure/elite_tumor/proc/return_elite()
mychild.forceMove(loc)
visible_message("<span class='boldwarning'>[mychild] suddenly reappears above [src]!</span>")
playsound(loc,'sound/effects/phasein.ogg', 200, 0, 50, TRUE, TRUE)
obj/structure/elite_tumor/proc/onEliteLoss()
playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, 0, 50, TRUE, TRUE)
visible_message("<span class='boldwarning'>[src] begins to convulse violently before beginning to dissipate.</span>")
@@ -288,7 +286,7 @@ obj/structure/elite_tumor/proc/onEliteLoss()
mychild = null
activator = null
qdel(src)
obj/structure/elite_tumor/proc/onEliteWon()
activity = TUMOR_PASSIVE
activator = null
@@ -302,7 +300,7 @@ obj/structure/elite_tumor/proc/onEliteWon()
to_chat(mychild, "<span class='boldwarning'>As the life in the activator's eyes fade, the forcefield around you dies out and you feel your power subside.\nDespite this inferno being your home, you feel as if you aren't welcome here anymore.\nWithout any guidance, your purpose is now for you to decide.</span>")
to_chat(mychild, "<b>Your max health has been halved, but can now heal by standing on your tumor. Note, it's your only way to heal.\nBear in mind, if anyone interacts with your tumor, you'll be resummoned here to carry out another fight. In such a case, you will regain your full max health.\nAlso, be weary of your fellow inhabitants, they likely won't be happy to see you!</b>")
to_chat(mychild, "<span class='big bold'>Note that you are a lavaland monster, and thus not allied to the station. You should not cooperate or act friendly with any station crew unless under extreme circumstances!</span>")
/obj/item/tumor_shard
name = "tumor shard"
desc = "A strange, sharp, crystal shard from an odd tumor on Lavaland. Stabbing the corpse of a lavaland elite with this will revive them, assuming their soul still lingers. Revived lavaland elites only have half their max health, but are completely loyal to their reviver."
@@ -315,7 +313,7 @@ obj/structure/elite_tumor/proc/onEliteWon()
w_class = WEIGHT_CLASS_SMALL
throw_speed = 3
throw_range = 5
/obj/item/tumor_shard/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
if(istype(target, /mob/living/simple_animal/hostile/asteroid/elite) && proximity_flag)
@@ -333,11 +331,10 @@ obj/structure/elite_tumor/proc/onEliteWon()
E.health = E.maxHealth
E.desc = "[E.desc] However, this one appears appears less wild in nature, and calmer around people."
E.sentience_type = SENTIENCE_ORGANIC
E.owner = user
qdel(src)
else
to_chat(user, "<span class='info'>[src] only works on the corpse of a sentient lavaland elite.</span>")
/obj/effect/temp_visual/elite_tumor_wall
name = "magic wall"
icon = 'icons/turf/walls/hierophant_wall_temp.dmi'
@@ -350,7 +347,7 @@ obj/structure/elite_tumor/proc/onEliteWon()
color = rgb(255,0,0)
light_range = MINIMUM_USEFUL_LIGHT_RANGE
light_color = LIGHT_COLOR_RED
/obj/effect/temp_visual/elite_tumor_wall/Initialize(mapload, new_caster)
. = ..()
queue_smooth_neighbors(src)
@@ -44,34 +44,34 @@
/datum/action/innate/elite_attack/magic_box,
/datum/action/innate/elite_attack/pandora_teleport,
/datum/action/innate/elite_attack/aoe_squares)
var/sing_shot_length = 8
var/cooldown_time = 20
/datum/action/innate/elite_attack/singular_shot
name = "Singular Shot"
button_icon_state = "singular_shot"
chosen_message = "<span class='boldwarning'>You are now creating a single linear magic square.</span>"
chosen_attack_num = SINGULAR_SHOT
/datum/action/innate/elite_attack/magic_box
name = "Magic Box"
button_icon_state = "magic_box"
chosen_message = "<span class='boldwarning'>You are now attacking with a box of magic squares.</span>"
chosen_attack_num = MAGIC_BOX
/datum/action/innate/elite_attack/pandora_teleport
name = "Line Teleport"
button_icon_state = "pandora_teleport"
chosen_message = "<span class='boldwarning'>You will now teleport to your target.</span>"
chosen_attack_num = PANDORA_TELEPORT
/datum/action/innate/elite_attack/aoe_squares
name = "AOE Blast"
button_icon_state = "aoe_squares"
chosen_message = "<span class='boldwarning'>Your attacks will spawn an AOE blast at your target location.</span>"
chosen_attack_num = AOE_SQUARES
/mob/living/simple_animal/hostile/asteroid/elite/pandora/OpenFire()
if(client)
switch(chosen_attack)
@@ -94,7 +94,7 @@
pandora_teleport(target)
if(AOE_SQUARES)
aoe_squares(target)
/mob/living/simple_animal/hostile/asteroid/elite/pandora/Life()
. = ..()
if(health >= maxHealth * 0.5)
@@ -105,28 +105,28 @@
return
else
cooldown_time = 10
/mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/singular_shot(target)
/mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/singular_shot(target)
ranged_cooldown = world.time + (cooldown_time * 0.5)
var/dir_to_target = get_dir(get_turf(src), get_turf(target))
var/turf/T = get_step(get_turf(src), dir_to_target)
singular_shot_line(sing_shot_length, dir_to_target, T)
/mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/singular_shot_line(var/procsleft, var/angleused, var/turf/T)
if(procsleft <= 0)
return
new /obj/effect/temp_visual/hierophant/blast/pandora(T, src, null, null, list(owner))
new /obj/effect/temp_visual/hierophant/blast/pandora(T, src)
T = get_step(T, angleused)
procsleft = procsleft - 1
addtimer(CALLBACK(src, .proc/singular_shot_line, procsleft, angleused, T), 2)
/mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/magic_box(target)
ranged_cooldown = world.time + cooldown_time
var/turf/T = get_turf(target)
for(var/t in spiral_range_turfs(3, T))
if(get_dist(t, T) > 1)
new /obj/effect/temp_visual/hierophant/blast/pandora(t, src, null, null, list(owner))
new /obj/effect/temp_visual/hierophant/blast/pandora(t, src)
/mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/pandora_teleport(target)
ranged_cooldown = world.time + cooldown_time
var/turf/T = get_turf(target)
@@ -135,45 +135,45 @@
new /obj/effect/temp_visual/hierophant/telegraph(source, src)
playsound(source,'sound/machines/airlockopen.ogg', 200, 1)
addtimer(CALLBACK(src, .proc/pandora_teleport_2, T, source), 2)
/mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/pandora_teleport_2(var/turf/T, var/turf/source)
new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, src)
new /obj/effect/temp_visual/hierophant/telegraph/teleport(source, src)
for(var/t in RANGE_TURFS(1, T))
new /obj/effect/temp_visual/hierophant/blast/pandora(t, src, null, null, list(owner))
new /obj/effect/temp_visual/hierophant/blast/pandora(t, src)
for(var/t in RANGE_TURFS(1, source))
new /obj/effect/temp_visual/hierophant/blast/pandora(t, src, null, null, list(owner))
new /obj/effect/temp_visual/hierophant/blast/pandora(t, src)
animate(src, alpha = 0, time = 2, easing = EASE_OUT) //fade out
visible_message("<span class='hierophant_warning'>[src] fades out!</span>")
density = FALSE
addtimer(CALLBACK(src, .proc/pandora_teleport_3, T), 2)
/mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/pandora_teleport_3(var/turf/T)
forceMove(T)
animate(src, alpha = 255, time = 2, easing = EASE_IN) //fade IN
density = TRUE
visible_message("<span class='hierophant_warning'>[src] fades in!</span>")
/mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/aoe_squares(target)
ranged_cooldown = world.time + cooldown_time
var/turf/T = get_turf(target)
new /obj/effect/temp_visual/hierophant/blast/pandora(T, src, null, null, list(owner))
new /obj/effect/temp_visual/hierophant/blast/pandora(T, src)
var/max_size = 2
addtimer(CALLBACK(src, .proc/aoe_squares_2, T, 0, max_size), 2)
/mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/aoe_squares_2(var/turf/T, var/ring, var/max_size)
if(ring > max_size)
return
for(var/t in spiral_range_turfs(ring, T))
if(get_dist(t, T) == ring)
new /obj/effect/temp_visual/hierophant/blast/pandora(t, src, null, null, list(owner))
new /obj/effect/temp_visual/hierophant/blast/pandora(t, src)
addtimer(CALLBACK(src, .proc/aoe_squares_2, T, (ring + 1), max_size), 2)
//The specific version of hiero's squares pandora uses
/obj/effect/temp_visual/hierophant/blast/pandora
damage = 20
monster_damage_boost = FALSE
//Pandora's loot: Hope
/obj/item/clothing/accessory/pandora_hope
name = "Hope"
@@ -181,7 +181,7 @@
icon = 'icons/obj/lavaland/elite_trophies.dmi'
icon_state = "hope"
resistance_flags = FIRE_PROOF
/obj/item/clothing/accessory/pandora_hope/on_uniform_equip(obj/item/clothing/under/U, user)
var/mob/living/L = user
if(L && L.mind)
@@ -131,7 +131,7 @@
/obj/item/udder/gutlunch/generateMilk()
if(prob(60))
reagents.add_reagent(/datum/reagent/consumable/cream, rand(2, 5))
reagents.add_reagent("cream", rand(2, 5))
if(prob(45))
reagents.add_reagent(/datum/reagent/medicine/salglu_solution, rand(2,5))
reagents.add_reagent("salglu_solution", rand(2,5))
@@ -20,7 +20,7 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
mob_size = MOB_SIZE_LARGE
var/icon_aggro = null
var/crusher_drop_mod = 25
var/crusher_drop_mod = 5
/mob/living/simple_animal/hostile/asteroid/Initialize(mapload)
. = ..()
@@ -58,7 +58,7 @@
/mob/living/simple_animal/hostile/asteroid/death(gibbed)
SSblackbox.record_feedback("tally", "mobs_killed_mining", 1, type)
var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
if(C && crusher_loot && prob((C.total_damage/maxHealth) * crusher_drop_mod)) //on average, you'll need to kill 4 creatures before getting the item
if(C && crusher_loot && prob((C.total_damage/maxHealth) * crusher_drop_mod)) //on average, you'll need to kill 20 creatures before getting the item
spawn_crusher_loot()
..(gibbed)
@@ -91,5 +91,5 @@
visible_message("<span class='boldannounce'>The tendril falls inward, the ground around it widening into a yawning chasm!</span>")
for(var/turf/T in range(2,src))
if(!T.density)
T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland, flags = CHANGETURF_INHERIT_AIR)
T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland)
qdel(src)
@@ -166,9 +166,7 @@
..()
/mob/living/simple_animal/hostile/mushroom/attack_hand(mob/living/carbon/human/M)
. = ..()
if(.) // the attack was blocked
return
..()
if(M.a_intent == INTENT_HARM)
Bruise()
@@ -187,6 +185,6 @@
var/counter
for(counter=0, counter<=powerlevel, counter++)
var/obj/item/reagent_containers/food/snacks/hugemushroomslice/S = new /obj/item/reagent_containers/food/snacks/hugemushroomslice(src.loc)
S.reagents.add_reagent(/datum/reagent/drug/mushroomhallucinogen, powerlevel)
S.reagents.add_reagent(/datum/reagent/medicine/omnizine, powerlevel)
S.reagents.add_reagent(/datum/reagent/medicine/synaptizine, powerlevel)
S.reagents.add_reagent("mushroomhallucinogen", powerlevel)
S.reagents.add_reagent("omnizine", powerlevel)
S.reagents.add_reagent("synaptizine", powerlevel)
@@ -141,9 +141,9 @@
. = ..()
remove_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE)
var/amount = 0
if(reagents.has_reagent(/datum/reagent/medicine/morphine)) // morphine slows slimes down
if(reagents.has_reagent("morphine")) // morphine slows slimes down
amount = 2
if(reagents.has_reagent(/datum/reagent/consumable/frostoil)) // Frostoil also makes them move VEEERRYYYYY slow
if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow
amount = 5
if(amount)
add_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
@@ -253,34 +253,33 @@
return
/mob/living/simple_animal/slime/attack_slime(mob/living/simple_animal/slime/M)
. = ..()
if(!. || M == src) //unsuccessful slime shock
return
if(buckled)
Feedstop(silent = TRUE)
visible_message("<span class='danger'>[M] pulls [src] off!</span>")
return
attacked += 5
if(nutrition >= 100) //steal some nutrition. negval handled in life()
nutrition -= (50 + (40 * M.is_adult))
M.add_nutrition(50 + (40 * M.is_adult))
if(health > 0)
M.adjustBruteLoss(-10 + (-10 * M.is_adult))
M.updatehealth()
if(..()) //successful slime attack
if(M == src)
return
if(buckled)
Feedstop(silent = TRUE)
visible_message("<span class='danger'>[M] pulls [src] off!</span>")
return
attacked += 5
if(nutrition >= 100) //steal some nutrition. negval handled in life()
nutrition -= (50 + (40 * M.is_adult))
M.add_nutrition(50 + (40 * M.is_adult))
if(health > 0)
M.adjustBruteLoss(-10 + (-10 * M.is_adult))
M.updatehealth()
/mob/living/simple_animal/slime/attack_animal(mob/living/simple_animal/M)
. = ..()
if(.)
attacked += 10
/mob/living/simple_animal/slime/attack_paw(mob/living/carbon/monkey/M)
. = ..()
if(.)//successful monkey bite.
if(..()) //successful monkey bite.
attacked += 10
/mob/living/simple_animal/slime/attack_larva(mob/living/carbon/alien/larva/L)
. = ..()
if(.) //successful larva bite.
if(..()) //successful larva bite.
attacked += 10
/mob/living/simple_animal/slime/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
@@ -322,11 +321,9 @@
attacked += 10
/mob/living/simple_animal/slime/attack_alien(mob/living/carbon/alien/humanoid/M)
. = ..()
if(!.) // the attack was blocked or was help/grab intent
return
attacked += 10
discipline_slime(M)
if(..()) //if harm or disarm intent.
attacked += 10
discipline_slime(M)
/mob/living/simple_animal/slime/attackby(obj/item/W, mob/living/user, params)
-26
View File
@@ -1,26 +0,0 @@
//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
/mob/living/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/final_pixel_y = pixel_y
var/final_dir = dir
var/changed = 0
if(lying != lying_prev && rotate_on_lying)
changed++
ntransform.TurnTo(lying_prev,lying)
if(lying == 0) //Lying to standing
final_pixel_y = get_standard_pixel_y_offset()
else //if(lying != 0)
if(lying_prev == 0) //Standing to lying
pixel_y = get_standard_pixel_y_offset()
final_pixel_y = get_standard_pixel_y_offset(lying)
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
if(resize != RESIZE_DEFAULT_SIZE)
changed++
ntransform.Scale(resize)
resize = RESIZE_DEFAULT_SIZE
if(changed)
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
+11 -18
View File
@@ -459,11 +459,6 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
if(!ckey || !new_mob)
CRASH("transfer_ckey() called [ckey ? "" : "on a ckey-less mob[new_mob ? "" : " and "]"][new_mob ? "" : "without a valid mob target"]!")
SEND_SIGNAL(new_mob, COMSIG_MOB_PRE_PLAYER_CHANGE, new_mob, src)
if (client && client.prefs && client.prefs.auto_ooc)
if (client.prefs.chat_toggles & CHAT_OOC && isliving(new_mob))
client.prefs.chat_toggles ^= CHAT_OOC
if (!(client.prefs.chat_toggles & CHAT_OOC) && isdead(new_mob))
client.prefs.chat_toggles ^= CHAT_OOC
new_mob.ckey = ckey
if(send_signal)
SEND_SIGNAL(src, COMSIG_MOB_KEY_CHANGE, new_mob, src)
@@ -567,9 +562,9 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/proc/is_muzzled()
return 0
/mob/Stat()
..()
/mob/Stat(delayoverride)
. = ..()
var/statdelay = delayoverride || 10
if(statpanel("Status"))
if (client)
stat(null, "Ping: [round(client.lastping, 1)]ms (Average: [round(client.avgping, 1)]ms)")
@@ -577,7 +572,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
var/datum/map_config/cached = SSmapping.next_map_config
if(cached)
stat(null, "Next Map: [cached.map_name]")
stat(null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]")
stat(null, "Round ID: [GLOB.round_id || "NULL"]")
stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]")
stat(null, "Round Time: [WORLDTIME2TEXT("hh:mm:ss")]")
stat(null, "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]")
@@ -587,8 +582,9 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
if(ETA)
stat(null, "[ETA] [SSshuttle.emergency.getTimerStr()]")
if(client && client.holder)
if(client?.holder)
if(statpanel("MC"))
statdelay = 0 //It's assumed that if you're doing this you are doing debug stuff, don't do ioditic things.
var/turf/T = get_turf(client.eye)
stat("Location:", COORD(T))
stat("CPU:", "[world.cpu]")
@@ -614,6 +610,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
GLOB.ahelp_tickets.stat_entry()
if(length(GLOB.sdql2_queries))
if(statpanel("SDQL2"))
statdelay = 0 //It's assumed that if you're doing this you are doing debug stuff, don't do ioditic things.
stat("Access Global SDQL2 List", GLOB.sdql2_vv_statobj)
for(var/i in GLOB.sdql2_queries)
var/datum/SDQL2_query/Q = i
@@ -637,14 +634,13 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
if(A.IsObscured())
continue
statpanel(listed_turf.name, null, A)
if(mind)
add_spells_to_statpanel(mind.spell_list)
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling)
add_stings_to_statpanel(changeling.purchasedpowers)
add_spells_to_statpanel(mob_spell_list)
sleep(statdelay)
/mob/proc/add_spells_to_statpanel(list/spells)
for(var/obj/effect/proc_holder/spell/S in spells)
@@ -801,14 +797,11 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
//can the mob be buckled to something by default?
/mob/proc/can_buckle()
return TRUE
return 1
//can the mob be unbuckled from something by default?
/mob/proc/can_unbuckle()
return TRUE
/mob/proc/can_buckle_others(mob/living/target, atom/buckle_to)
return TRUE
return 1
//Can the mob interact() with an atom?
/mob/proc/can_interact_with(atom/A)
@@ -960,4 +953,4 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/setMovetype(newval)
. = ..()
update_movespeed(FALSE)
update_movespeed(FALSE)
-1
View File
@@ -29,7 +29,6 @@
var/obj/machinery/machine = null
var/next_move = null
var/create_area_cooldown
var/notransform = null //Carbon
var/eye_blind = 0 //Carbon
var/eye_blurry = 0 //Carbon