Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into tggenetics
This commit is contained in:
@@ -27,12 +27,7 @@
|
||||
|
||||
/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
|
||||
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]"]
|
||||
var/datum/job/previewJob = get_highest_job()
|
||||
|
||||
if(previewJob)
|
||||
// Silicons only need a very basic preview since there is no customization for them.
|
||||
@@ -57,3 +52,11 @@
|
||||
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
|
||||
|
||||
@@ -27,28 +27,33 @@
|
||||
extra2 = TRUE
|
||||
center = TRUE
|
||||
dimension_x = 64
|
||||
var/taur_mode = NOT_TAURIC
|
||||
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.
|
||||
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 = HOOF_TAURIC
|
||||
taur_mode = STYLE_HOOF_TAURIC
|
||||
alt_taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/deer
|
||||
name = "Deer"
|
||||
icon_state = "deer"
|
||||
taur_mode = HOOF_TAURIC
|
||||
taur_mode = STYLE_HOOF_TAURIC
|
||||
alt_taur_mode = STYLE_PAW_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
|
||||
/datum/sprite_accessory/taur/drake
|
||||
name = "Drake"
|
||||
icon_state = "drake"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/drider
|
||||
name = "Drider"
|
||||
@@ -58,67 +63,68 @@
|
||||
/datum/sprite_accessory/taur/eevee
|
||||
name = "Eevee"
|
||||
icon_state = "eevee"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
|
||||
/datum/sprite_accessory/taur/fox
|
||||
name = "Fox"
|
||||
icon_state = "fox"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/husky
|
||||
name = "Husky"
|
||||
icon_state = "husky"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/horse
|
||||
name = "Horse"
|
||||
icon_state = "horse"
|
||||
taur_mode = HOOF_TAURIC
|
||||
taur_mode = STYLE_HOOF_TAURIC
|
||||
alt_taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/lab
|
||||
name = "Lab"
|
||||
icon_state = "lab"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/naga
|
||||
name = "Naga"
|
||||
icon_state = "naga"
|
||||
taur_mode = SNEK_TAURIC
|
||||
taur_mode = STYLE_SNEK_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/otie
|
||||
name = "Otie"
|
||||
icon_state = "otie"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/pede
|
||||
name = "Scolipede"
|
||||
icon_state = "pede"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
|
||||
/datum/sprite_accessory/taur/panther
|
||||
name = "Panther"
|
||||
icon_state = "panther"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/shepherd
|
||||
name = "Shepherd"
|
||||
icon_state = "shepherd"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/tentacle
|
||||
name = "Tentacle"
|
||||
icon_state = "tentacle"
|
||||
taur_mode = SNEK_TAURIC
|
||||
taur_mode = STYLE_SNEK_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
|
||||
/datum/sprite_accessory/taur/tiger
|
||||
name = "Tiger"
|
||||
icon_state = "tiger"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/wolf
|
||||
name = "Wolf"
|
||||
icon_state = "wolf"
|
||||
taur_mode = PAW_TAURIC
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
@@ -310,4 +310,40 @@
|
||||
name = "Tube Top"
|
||||
icon_state = "tubetop"
|
||||
has_color = TRUE
|
||||
gender = FEMALE
|
||||
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"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,3 @@
|
||||
|
||||
update_icon(preferred_form)
|
||||
updateghostimages()
|
||||
|
||||
client.reenter_round_timeout = max(client.reenter_round_timeout, clientless_round_timeout)
|
||||
clientless_round_timeout = client.reenter_round_timeout
|
||||
|
||||
@@ -19,7 +19,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
hud_type = /datum/hud/ghost
|
||||
movement_type = GROUND | FLYING
|
||||
var/can_reenter_corpse
|
||||
var/clientless_round_timeout = 0 //mobs will lack a client as long as their player is disconnected. See client_defines.dm "reenter_round_timeout"
|
||||
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.
|
||||
@@ -135,7 +134,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)
|
||||
@@ -270,23 +269,12 @@ 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(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)
|
||||
penalty += world.realtime
|
||||
if(penalty - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
if(client)
|
||||
client.reenter_round_timeout = penalty
|
||||
else //A disconnected player (quite likely for cryopods)
|
||||
ghost.clientless_round_timeout = penalty
|
||||
if (client && client.prefs && client.prefs.auto_ooc)
|
||||
if (!(client.prefs.chat_toggles & CHAT_OOC))
|
||||
client.prefs.chat_toggles ^= CHAT_OOC
|
||||
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
|
||||
|
||||
/*
|
||||
@@ -343,15 +331,7 @@ 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)
|
||||
var/timeout = clientless_round_timeout
|
||||
if(client)
|
||||
timeout = client.reenter_round_timeout
|
||||
if(timeout != CANT_REENTER_ROUND && timeout <= world.realtime)
|
||||
return TRUE
|
||||
if(!silent && client)
|
||||
to_chat(src, "<span class='warning'>You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/dead/observer/Move(NewLoc, direct)
|
||||
if(updatedir)
|
||||
@@ -497,6 +477,32 @@ 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"
|
||||
@@ -827,32 +833,6 @@ 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"
|
||||
|
||||
@@ -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 == "blood" || blood_id == "jellyblood") //normal blood
|
||||
if(blood_id == /datum/reagent/blood || blood_id == /datum/reagent/blood/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 == "blood" || blood_id == "jellyblood") //actual blood reagent
|
||||
if(blood_id == /datum/reagent/blood || /datum/reagent/blood/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.id] = R.volume
|
||||
temp_chem[R.type] = 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 "blood"
|
||||
return /datum/reagent/blood
|
||||
|
||||
/mob/living/carbon/monkey/get_blood_id()
|
||||
if(!(HAS_TRAIT(src, TRAIT_NOCLONE)))
|
||||
return "blood"
|
||||
return /datum/reagent/blood
|
||||
|
||||
/mob/living/carbon/get_blood_id()
|
||||
if(isjellyperson(src))
|
||||
return "jellyblood"
|
||||
return /datum/reagent/blood/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 "blood"
|
||||
return /datum/reagent/blood
|
||||
|
||||
// This is has more potential uses, and is probably faster than the old proc.
|
||||
/proc/get_safe_blood(bloodtype)
|
||||
|
||||
@@ -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("demonsblood"))
|
||||
else if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/consumable/ethanol/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("devilskiss"))
|
||||
if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/consumable/ethanol/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
|
||||
|
||||
@@ -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("neurine")) //Neurine fixes dead brains
|
||||
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent(/datum/reagent/medicine/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("neurine")
|
||||
var/datum/reagent/medicine/mannitol/M1 = reagents.has_reagent("mannitol")
|
||||
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)
|
||||
|
||||
if(O.reagents.has_reagent("mannitol"))//Just a quick way to bolster the effects if someone mixes up a batch.
|
||||
if(O.reagents.has_reagent(/datum/reagent/medicine/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("neurine", 10))
|
||||
if(!O.reagents.has_reagent(/datum/reagent/medicine/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("mannitol")) //attempt to heal the brain
|
||||
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent(/datum/reagent/medicine/mannitol)) //attempt to heal the brain
|
||||
. = TRUE //don't do attack animation.
|
||||
var/datum/reagent/medicine/mannitol/M = reagents.has_reagent("mannitol")
|
||||
var/datum/reagent/medicine/mannitol/M = reagents.has_reagent(/datum/reagent/medicine/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("mannitol", 10))
|
||||
if(!O.reagents.has_reagent(/datum/reagent/medicine/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)
|
||||
..(AM, skipcatch = TRUE, hitpush = FALSE)
|
||||
return ..(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(isturf(loc) && istype(loc.loc, /area/start))
|
||||
to_chat(M, "No attacking people at spawn, you jackass.")
|
||||
. = ..()
|
||||
if(!.) // the attack was blocked or was help/grab intent
|
||||
return
|
||||
|
||||
switch(M.a_intent)
|
||||
|
||||
if ("help")
|
||||
if (INTENT_HELP)
|
||||
if(!recoveringstam)
|
||||
resting = 0
|
||||
AdjustStun(-60)
|
||||
@@ -28,11 +28,7 @@ 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 ("grab")
|
||||
grabbedby(M)
|
||||
|
||||
else
|
||||
if(INTENT_DISARM, INTENT_HARM)
|
||||
if(health > 0)
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
|
||||
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
|
||||
@@ -50,28 +46,31 @@ 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 0
|
||||
|
||||
. = ..()
|
||||
if(.) //To allow surgery to return properly.
|
||||
return
|
||||
switch(M.a_intent)
|
||||
if("help")
|
||||
if(INTENT_HELP)
|
||||
help_shake_act(M)
|
||||
if("grab")
|
||||
if(INTENT_GRAB)
|
||||
grabbedby(M)
|
||||
if ("harm")
|
||||
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
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
|
||||
return 1
|
||||
if("disarm")
|
||||
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
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/carbon/alien/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(..())
|
||||
if (stat != DEAD)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(rand(1, 3), BRUTE, affecting)
|
||||
. = ..()
|
||||
if(.) //successful monkey bite.
|
||||
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)
|
||||
@@ -93,13 +92,15 @@ 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(..()) //successful slime attack
|
||||
var/damage = rand(5, 35)
|
||||
if(M.is_adult)
|
||||
damage = rand(10, 40)
|
||||
adjustBruteLoss(damage)
|
||||
log_combat(M, src, "attacked")
|
||||
updatehealth()
|
||||
. = ..()
|
||||
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()
|
||||
|
||||
/mob/living/carbon/alien/ex_act(severity, target, origin)
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
|
||||
@@ -63,12 +63,7 @@
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
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)
|
||||
if(!L.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
|
||||
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,9 +5,11 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
..(user, 1)
|
||||
. = ..(user, TRUE)
|
||||
if(.)
|
||||
return
|
||||
adjustBruteLoss(15)
|
||||
var/hitverb = "punched"
|
||||
if(mob_size < MOB_SIZE_LARGE)
|
||||
@@ -21,46 +23,46 @@
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
|
||||
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")
|
||||
. = ..()
|
||||
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>")
|
||||
else
|
||||
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)
|
||||
if (prob(50))
|
||||
dropItemToGround(get_active_held_item())
|
||||
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>")
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
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)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
/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,10 +14,9 @@
|
||||
var/max_grown = 100
|
||||
var/time_of_birth
|
||||
|
||||
rotate_on_lying = 0
|
||||
rotate_on_lying = FALSE
|
||||
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,26 +1,33 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
|
||||
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))
|
||||
. = ..()
|
||||
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))
|
||||
|
||||
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 = 0)
|
||||
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
..(user, 1)
|
||||
. = ..(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)
|
||||
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("sacid", 10)
|
||||
S.reagents.add_reagent(/datum/reagent/toxin/acid, 10)
|
||||
return S
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
/obj/item/organ/alien/plasmavessel/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
S.reagents.add_reagent("plasma", storedPlasma/10)
|
||||
S.reagents.add_reagent(/datum/reagent/toxin/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("sacid", 10)
|
||||
S.reagents.add_reagent(/datum/reagent/toxin/acid, 10)
|
||||
return S
|
||||
|
||||
/obj/item/organ/body_egg/alien_embryo/on_life()
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
|
||||
layer = MOB_LAYER
|
||||
max_integrity = 100
|
||||
mutantrace_variation = MUTANTRACE_VARIATION
|
||||
mutantrace_variation = STYLE_MUZZLE
|
||||
|
||||
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
|
||||
|
||||
|
||||
@@ -518,7 +518,7 @@
|
||||
add_splatter_floor(T)
|
||||
if(stun)
|
||||
adjustBruteLoss(3)
|
||||
else if(src.reagents.has_reagent("blazaam"))
|
||||
else if(src.reagents.has_reagent(/datum/reagent/consumable/ethanol/blazaam))
|
||||
if(T)
|
||||
T.add_vomit_floor(src, VOMIT_PURPLE)
|
||||
else
|
||||
|
||||
@@ -48,41 +48,42 @@
|
||||
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
|
||||
affecting.dismember(P.damtype)
|
||||
|
||||
/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)
|
||||
/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)
|
||||
return
|
||||
if(get_active_held_item())
|
||||
if(get_active_held_item() || restrained())
|
||||
return
|
||||
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
|
||||
..()
|
||||
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
|
||||
|
||||
/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!
|
||||
@@ -93,17 +94,6 @@
|
||||
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
|
||||
@@ -137,7 +127,9 @@
|
||||
|
||||
//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)
|
||||
@@ -152,8 +144,7 @@
|
||||
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 1
|
||||
return 0
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M)
|
||||
@@ -173,7 +164,8 @@
|
||||
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)
|
||||
@@ -181,26 +173,27 @@
|
||||
|
||||
|
||||
/mob/living/carbon/attack_slime(mob/living/simple_animal/slime/M)
|
||||
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
|
||||
. = ..()
|
||||
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
|
||||
|
||||
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()
|
||||
return 1
|
||||
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()
|
||||
|
||||
/mob/living/carbon/proc/dismembering_strike(mob/living/attacker, dam_zone)
|
||||
if(!attacker.limb_destroyer)
|
||||
@@ -250,7 +243,7 @@
|
||||
shock_damage *= dna.species.siemens_coeff
|
||||
if(shock_damage<1 && !override)
|
||||
return 0
|
||||
if(reagents.has_reagent("teslium"))
|
||||
if(reagents.has_reagent(/datum/reagent/teslium))
|
||||
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
|
||||
if(illusion)
|
||||
adjustStaminaLoss(shock_damage)
|
||||
@@ -332,12 +325,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
|
||||
|
||||
var/rotate_on_lying = 1
|
||||
rotate_on_lying = TRUE
|
||||
|
||||
var/tinttotal = 0 // Total level of visualy impairing items
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
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("teslium"))
|
||||
if(reagents.has_reagent(/datum/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("astral"))
|
||||
if(reagents.has_reagent(/datum/reagent/fermi/astral))
|
||||
if(mind)
|
||||
msg += "[t_He] has wild, spacey eyes and they have a strange, abnormal look to them.\n"
|
||||
else
|
||||
|
||||
@@ -67,66 +67,36 @@
|
||||
P.setAngle(rand(0, 360))//SHING
|
||||
return FALSE
|
||||
|
||||
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)
|
||||
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_reflect(def_zone)
|
||||
if(wear_suit?.IsReflect(def_zone))
|
||||
return TRUE
|
||||
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)
|
||||
/mob/living/carbon/human/check_shields(atom/AM, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
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 1
|
||||
return TRUE
|
||||
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 1
|
||||
return TRUE
|
||||
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 1
|
||||
return 0
|
||||
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
|
||||
|
||||
/mob/living/carbon/human/proc/check_block()
|
||||
if(mind)
|
||||
@@ -135,39 +105,7 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE)
|
||||
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 ..()
|
||||
return dna?.species?.spec_hitby(AM, src) || ..()
|
||||
|
||||
/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))
|
||||
@@ -201,12 +139,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 = 0)
|
||||
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
var/hulk_verb = pick("smash","pummel")
|
||||
if(check_shields(user, 15, "the [hulk_verb]ing"))
|
||||
. = ..(user, TRUE)
|
||||
if(.)
|
||||
return
|
||||
..(user, 1)
|
||||
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>", \
|
||||
@@ -215,7 +153,8 @@
|
||||
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
|
||||
@@ -227,8 +166,7 @@
|
||||
if(!affecting)
|
||||
affecting = get_bodypart(BODY_ZONE_CHEST)
|
||||
if(M.a_intent == INTENT_HELP)
|
||||
..() //shaking
|
||||
return 0
|
||||
return ..() //shaking
|
||||
|
||||
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()
|
||||
@@ -249,78 +187,69 @@
|
||||
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)
|
||||
if(check_shields(M, damage, "the [M.name]"))
|
||||
return 0
|
||||
if(stat != DEAD)
|
||||
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
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(check_shields(M, 0, "the M.name"))
|
||||
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
|
||||
return 0
|
||||
. = ..()
|
||||
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(..())
|
||||
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)
|
||||
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)
|
||||
|
||||
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>")
|
||||
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)
|
||||
else
|
||||
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>")
|
||||
|
||||
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(..()) //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)
|
||||
. = ..()
|
||||
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)
|
||||
|
||||
|
||||
/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
|
||||
@@ -332,23 +261,22 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(5, 25)
|
||||
if(M.is_adult)
|
||||
damage = rand(10, 35)
|
||||
. = ..()
|
||||
if(!.) //unsuccessful slime attack
|
||||
return
|
||||
var/damage = rand(5, 25)
|
||||
if(M.is_adult)
|
||||
damage = rand(10, 35)
|
||||
|
||||
if(check_shields(M, damage, "the [M.name]"))
|
||||
return 0
|
||||
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/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)
|
||||
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)
|
||||
@@ -405,7 +333,7 @@
|
||||
switch (severity)
|
||||
if (1)
|
||||
if(bomb_armor)
|
||||
b_loss = 500*bomb_armor
|
||||
b_loss = (350*bomb_armor)+150
|
||||
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")
|
||||
|
||||
@@ -291,7 +291,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)
|
||||
|
||||
@@ -620,34 +620,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) || (!H.dna.features["taur"] == "None"))
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "tail_lizard"
|
||||
|
||||
if("waggingtail_lizard" in mutant_bodyparts)
|
||||
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
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) || (!H.dna.features["taur"] == "None"))
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "tail_human"
|
||||
|
||||
|
||||
if("waggingtail_human" in mutant_bodyparts)
|
||||
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
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 & HIDEJUMPSUIT))
|
||||
if(!H.dna.features["spines"] || H.dna.features["spines"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR))
|
||||
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 & HIDEJUMPSUIT))
|
||||
if(!H.dna.features["spines"] || H.dna.features["spines"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR))
|
||||
bodyparts_to_add -= "waggingspines"
|
||||
else if ("tail" in mutant_bodyparts)
|
||||
bodyparts_to_add -= "waggingspines"
|
||||
@@ -697,11 +697,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) || (!H.dna.features["taur"] == "None"))
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "mam_tail"
|
||||
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR) || (!H.dna.features["taur"] == "None"))
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "mam_waggingtail"
|
||||
else if ("mam_tail" in mutant_bodyparts)
|
||||
bodyparts_to_add -= "mam_waggingtail"
|
||||
@@ -715,7 +715,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
bodyparts_to_add -= "mam_snouts"
|
||||
|
||||
if("taur" in mutant_bodyparts)
|
||||
if(!H.dna.features["taur"] || H.dna.features["taur"] == "None" || (H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)))
|
||||
if(!tauric || (H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)))
|
||||
bodyparts_to_add -= "taur"
|
||||
|
||||
//END EDIT
|
||||
@@ -732,10 +732,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 == NO_MUTANTRACE_VARIATION) //we got digitigrade suits now fam
|
||||
if(!(H.wear_suit.mutantrace_variation & STYLE_DIGITIGRADE) || (tauric && (H.wear_suit.mutantrace_variation & STYLE_ALL_TAURIC))) //digitigrade/taur suits
|
||||
should_be_squished = TRUE
|
||||
if(H.w_uniform && !H.wear_suit)
|
||||
if(H.w_uniform.mutantrace_variation == NO_MUTANTRACE_VARIATION)
|
||||
if(!(H.w_uniform.mutantrace_variation & STYLE_DIGITIGRADE))
|
||||
should_be_squished = TRUE
|
||||
if(O.use_digitigrade == FULL_DIGITIGRADE && should_be_squished)
|
||||
O.use_digitigrade = SQUISHED_DIGITIGRADE
|
||||
@@ -1279,9 +1279,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.id == exotic_blood)
|
||||
if(chem.type == exotic_blood)
|
||||
H.blood_volume = min(H.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM)
|
||||
H.reagents.del_reagent(chem.id)
|
||||
H.reagents.del_reagent(chem.type)
|
||||
return 1
|
||||
return FALSE
|
||||
|
||||
@@ -1694,11 +1694,6 @@ 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("ethanol", stored_alcohol/10)
|
||||
S.reagents.add_reagent(/datum/reagent/consumable/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.id == "pestkiller")
|
||||
if(chem.type == /datum/reagent/toxin/pestkiller)
|
||||
H.adjustToxLoss(3)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
@@ -70,20 +70,6 @@
|
||||
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.id == "plantbgone")
|
||||
if(chem.type == /datum/reagent/toxin/plantbgone)
|
||||
H.adjustToxLoss(3)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
H.reagents.remove_reagent(chem.type, 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.id == "holywater")
|
||||
if(chem.type == /datum/reagent/water/holywater)
|
||||
H.adjustFireLoss(4)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
|
||||
|
||||
if(chem.id == "unholywater")
|
||||
if(chem.type == /datum/reagent/fuel/unholywater)
|
||||
H.adjustBruteLoss(-4)
|
||||
H.adjustFireLoss(-4)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
H.reagents.remove_reagent(chem.type, 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 = "jellyblood"
|
||||
exotic_blood = /datum/reagent/blood/jellyblood
|
||||
exotic_bloodtype = "GEL"
|
||||
damage_overlay_type = ""
|
||||
var/datum/action/innate/regenerate_limbs/regenerate_limbs
|
||||
|
||||
@@ -74,19 +74,6 @@
|
||||
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,19 +37,24 @@
|
||||
H.dna.features["caps"] = "Round"
|
||||
handle_mutant_bodyparts(H)
|
||||
H.faction |= "mushroom"
|
||||
mush = new(null)
|
||||
mush.teach(H)
|
||||
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.
|
||||
|
||||
/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.id == "weedkiller")
|
||||
if(chem.type == /datum/reagent/toxin/plantbgone/weedkiller)
|
||||
H.adjustToxLoss(3)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
H.reagents.remove_reagent(chem.type, 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.id == "plantbgone")
|
||||
if(chem.type == /datum/reagent/toxin/plantbgone)
|
||||
H.adjustToxLoss(3)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
|
||||
return 1
|
||||
|
||||
/datum/species/pod/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
UnregisterSignal(H, COMSIG_MOB_SAY)
|
||||
|
||||
/datum/species/synth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
|
||||
if(chem.id == "synthflesh")
|
||||
if(chem.type == /datum/reagent/medicine/synthflesh)
|
||||
chem.reaction_mob(H, TOUCH, 2 ,0) //heal a little
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -119,24 +119,25 @@ 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.suit_style == NORMAL_SUIT_STYLE)
|
||||
if(U.adjusted == ALT_STYLE)
|
||||
t_color = "[t_color]_d"
|
||||
if(U.adjusted == ALT_STYLE)
|
||||
t_color = "[t_color]_d"
|
||||
|
||||
var/alt_worn = U.alternate_worn_icon
|
||||
var/alt_worn = U.alternate_worn_icon || 'icons/mob/uniform.dmi'
|
||||
var/variant_flag = NONE
|
||||
|
||||
if(!U.force_alternate_icon && U.mutantrace_variation && U.suit_style == DIGITIGRADE_SUIT_STYLE)
|
||||
if((DIGITIGRADE in dna.species.species_traits) && U.mutantrace_variation & STYLE_DIGITIGRADE)
|
||||
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(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = (alt_worn ? alt_worn : 'icons/mob/uniform.dmi'), isinhands = FALSE, femaleuniform = U.fitted)
|
||||
uniform_overlay = U.build_worn_icon(t_color, UNIFORM_LAYER, alt_worn, FALSE, U.fitted, variant_flag, FALSE)
|
||||
|
||||
if(!uniform_overlay)
|
||||
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)
|
||||
uniform_overlay = U.build_worn_icon(t_color, UNIFORM_LAYER, alt_worn, FALSE, NO_FEMALE_UNIFORM, variant_flag, FALSE)
|
||||
|
||||
|
||||
if(OFFSET_UNIFORM in dna.species.offset_features)
|
||||
@@ -164,7 +165,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 = ((wear_id.alternate_worn_icon) ? wear_id.alternate_worn_icon : 'icons/mob/mob.dmi'))
|
||||
id_overlay = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = '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]
|
||||
@@ -199,7 +200,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 = ((gloves.alternate_worn_icon) ? gloves.alternate_worn_icon : 'icons/mob/hands.dmi'))
|
||||
overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(state = t_state, default_layer = GLOVES_LAYER, default_icon_file = '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]
|
||||
@@ -225,7 +226,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 = ((glasses.alternate_worn_icon) ? glasses.alternate_worn_icon : 'icons/mob/eyes.dmi'))
|
||||
overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi')
|
||||
var/mutable_appearance/glasses_overlay = overlays_standing[GLASSES_LAYER]
|
||||
if(glasses_overlay)
|
||||
if(OFFSET_GLASSES in dna.species.offset_features)
|
||||
@@ -252,7 +253,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 = ((ears.alternate_worn_icon) ? ears.alternate_worn_icon : 'icons/mob/ears.dmi'))
|
||||
overlays_standing[EARS_LAYER] = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = '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]
|
||||
@@ -270,32 +271,6 @@ 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
|
||||
@@ -304,15 +279,17 @@ 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)
|
||||
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/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
|
||||
|
||||
var/t_state = shoes.item_state
|
||||
if (!t_state)
|
||||
t_state = shoes.icon_state
|
||||
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'))
|
||||
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(t_state, SHOES_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
|
||||
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]
|
||||
@@ -350,13 +327,18 @@ There are several things that need to be remembered:
|
||||
if(head)
|
||||
remove_overlay(HEAD_LAYER)
|
||||
var/obj/item/clothing/head/H = head
|
||||
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
|
||||
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
|
||||
|
||||
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'))
|
||||
overlays_standing[HEAD_LAYER] = H.build_worn_icon(H.icon_state, HEAD_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
|
||||
var/mutable_appearance/head_overlay = overlays_standing[HEAD_LAYER]
|
||||
|
||||
if(OFFSET_HEAD in dna.species.offset_features)
|
||||
@@ -382,7 +364,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 = ((belt.alternate_worn_icon) ? belt.alternate_worn_icon : 'icons/mob/belt.dmi'))
|
||||
overlays_standing[BELT_LAYER] = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = '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]
|
||||
@@ -409,30 +391,41 @@ There are several things that need to be remembered:
|
||||
client.screen += wear_suit
|
||||
update_observer_view(wear_suit,1)
|
||||
|
||||
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
|
||||
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(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
|
||||
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
|
||||
|
||||
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'))
|
||||
overlays_standing[SUIT_LAYER] = S.build_worn_icon(wear_suit.icon_state, SUIT_LAYER, worn_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
|
||||
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(!item_level_support && S.center)
|
||||
suit_overlay = center_image(suit_overlay, S.dimension_x, S.dimension_y)
|
||||
if(center)
|
||||
suit_overlay = center_image(suit_overlay, dimension_x, dimension_y)
|
||||
overlays_standing[SUIT_LAYER] = suit_overlay
|
||||
update_hair()
|
||||
update_mutant_bodyparts()
|
||||
@@ -468,13 +461,18 @@ There are several things that need to be remembered:
|
||||
if(wear_mask)
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
remove_overlay(FACEMASK_LAYER)
|
||||
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
|
||||
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
|
||||
|
||||
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'))
|
||||
overlays_standing[FACEMASK_LAYER] = M.build_worn_icon(wear_mask.icon_state, FACEMASK_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
|
||||
var/mutable_appearance/mask_overlay = overlays_standing[FACEMASK_LAYER]
|
||||
|
||||
if(OFFSET_FACEMASK in dna.species.offset_features)
|
||||
@@ -496,11 +494,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
|
||||
var/index = "[t_color]-[icon]"
|
||||
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[t_color], layer = -layer)
|
||||
return mutable_appearance(GLOB.female_clothing_icons[index], layer = -layer)
|
||||
|
||||
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
|
||||
var/list/out = new
|
||||
@@ -572,11 +570,11 @@ generate/load female uniform sprites matching all previously decided variables
|
||||
|
||||
|
||||
*/
|
||||
/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)
|
||||
/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)
|
||||
|
||||
//Find a valid icon file from variables+arguments
|
||||
var/file2use
|
||||
if(!isinhands && alternate_worn_icon)
|
||||
if(!isinhands && alternate_worn_icon && use_alt_icon)
|
||||
file2use = alternate_worn_icon
|
||||
if(!file2use)
|
||||
file2use = default_icon_file
|
||||
@@ -596,7 +594,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)
|
||||
var/list/worn_overlays = worn_overlays(isinhands, file2use, style_flags)
|
||||
if(worn_overlays && worn_overlays.len)
|
||||
standing.overlays.Add(worn_overlays)
|
||||
|
||||
@@ -675,6 +673,8 @@ 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)
|
||||
|
||||
@@ -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("lexorin"))
|
||||
if(reagents.has_reagent(/datum/reagent/toxin/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("epinephrine") && lungs)
|
||||
if(reagents.has_reagent(/datum/reagent/medicine/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("formaldehyde", 15) || HAS_TRAIT(src, TRAIT_HUSK))
|
||||
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 15) || HAS_TRAIT(src, TRAIT_HUSK))
|
||||
return
|
||||
|
||||
// Also no decay if corpse chilled or not organic/undead
|
||||
|
||||
@@ -369,6 +369,23 @@
|
||||
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("morphine"))
|
||||
if(reagents.has_reagent(/datum/reagent/medicine/morphine))
|
||||
amount = -1
|
||||
if(amount)
|
||||
add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
|
||||
|
||||
@@ -6,37 +6,55 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/attack_paw(mob/living/M)
|
||||
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)
|
||||
if(M.limb_destroyer)
|
||||
dismembering_strike(M, affecting.body_zone)
|
||||
if(stat != DEAD)
|
||||
var/dmg = rand(1, 5)
|
||||
apply_damage(dmg, BRUTE, affecting)
|
||||
. = ..()
|
||||
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(..()) //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)
|
||||
. = ..()
|
||||
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)
|
||||
apply_damage(damage, 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_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("help")
|
||||
if(INTENT_HELP)
|
||||
help_shake_act(M)
|
||||
if("grab")
|
||||
if(INTENT_GRAB)
|
||||
grabbedby(M)
|
||||
if("harm")
|
||||
if(INTENT_HARM)
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='notice'>You don't want to hurt [src]!</span>")
|
||||
return
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
|
||||
if (prob(75))
|
||||
visible_message("<span class='danger'>[M] has punched [name]!</span>", \
|
||||
@@ -60,7 +78,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("disarm")
|
||||
if(INTENT_DISARM)
|
||||
if(!IsUnconscious())
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
if (prob(25))
|
||||
@@ -74,50 +92,51 @@
|
||||
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(..()) //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)
|
||||
|
||||
. = ..()
|
||||
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)
|
||||
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)
|
||||
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed [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)
|
||||
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)
|
||||
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)
|
||||
else
|
||||
I = null
|
||||
log_combat(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
|
||||
updatehealth()
|
||||
|
||||
I = null
|
||||
log_combat(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
|
||||
updatehealth()
|
||||
|
||||
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
|
||||
. = ..()
|
||||
@@ -132,17 +151,19 @@
|
||||
apply_damage(damage, M.melee_damage_type, affecting)
|
||||
|
||||
/mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M)
|
||||
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)
|
||||
. = ..()
|
||||
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)
|
||||
|
||||
/mob/living/carbon/monkey/acid_act(acidpwr, acid_volume, bodyzone_hit)
|
||||
. = 1
|
||||
|
||||
@@ -1,31 +1,3 @@
|
||||
//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]
|
||||
|
||||
@@ -228,7 +200,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)
|
||||
/obj/item/proc/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
|
||||
. = list()
|
||||
|
||||
|
||||
|
||||
@@ -1225,7 +1225,7 @@
|
||||
clamp_unconscious_to = 0,
|
||||
clamp_immobility_to = 0,
|
||||
reset_misc = TRUE,
|
||||
healing_chems = list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10),
|
||||
healing_chems = list(/datum/reagent/medicine/inaprovaline = 3, /datum/reagent/medicine/synaptizine = 10, /datum/reagent/medicine/regen_jelly = 10, /datum/reagent/medicine/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()
|
||||
for(var/chem in healing_chems)
|
||||
reagents.add_reagent(chem, healing_chems[chem])
|
||||
if(healing_chems)
|
||||
reagents.add_reagent_list(healing_chems)
|
||||
|
||||
@@ -36,7 +36,50 @@
|
||||
/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)
|
||||
@@ -55,9 +98,32 @@
|
||||
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)
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
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
|
||||
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()
|
||||
@@ -214,6 +280,24 @@
|
||||
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())
|
||||
@@ -229,6 +313,12 @@
|
||||
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)
|
||||
@@ -245,7 +335,8 @@
|
||||
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)
|
||||
@@ -256,10 +347,6 @@
|
||||
|
||||
|
||||
/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>")
|
||||
@@ -268,6 +355,8 @@
|
||||
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")
|
||||
@@ -282,15 +371,16 @@
|
||||
|
||||
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
switch(L.a_intent)
|
||||
if("help")
|
||||
if(INTENT_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
|
||||
|
||||
return FALSE
|
||||
if(L != src && check_shields(L, rand(1, 3), "the [L.name]"))
|
||||
return FALSE
|
||||
L.do_attack_animation(src)
|
||||
if(prob(90))
|
||||
log_combat(L, src, "attacked")
|
||||
@@ -301,24 +391,29 @@
|
||||
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 ("help")
|
||||
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
|
||||
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>")
|
||||
return FALSE
|
||||
if ("grab")
|
||||
if (INTENT_GRAB)
|
||||
grabbedby(M)
|
||||
return FALSE
|
||||
if("harm")
|
||||
if(INTENT_HARM)
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
|
||||
return FALSE
|
||||
M.do_attack_animation(src)
|
||||
if(!isalien(src))
|
||||
M.do_attack_animation(src)
|
||||
return TRUE
|
||||
if("disarm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
if(INTENT_DISARM)
|
||||
if(!isalien(src))
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
return TRUE
|
||||
|
||||
/mob/living/ex_act(severity, target, origin)
|
||||
@@ -369,7 +464,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("heparin", 5)
|
||||
reagents.add_reagent(/datum/reagent/toxin/heparin, 5)
|
||||
return FALSE
|
||||
if(GLOB.cult_narsie && GLOB.cult_narsie.souls_needed[src])
|
||||
GLOB.cult_narsie.souls_needed -= src
|
||||
|
||||
@@ -111,4 +111,6 @@
|
||||
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/drag_slowdown = TRUE //Whether the mob is slowed down when dragging another prone mob
|
||||
|
||||
var/rotate_on_lying = FALSE
|
||||
@@ -260,15 +260,6 @@
|
||||
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>")
|
||||
@@ -681,18 +672,23 @@
|
||||
"green face" = 'icons/mob/ai.dmi',
|
||||
"xeno queen" = 'icons/mob/alien.dmi',
|
||||
"horror" = 'icons/mob/ai.dmi',
|
||||
"creature" = 'icons/mob/ai.dmi'
|
||||
"creature" = 'icons/mob/ai.dmi',
|
||||
"custom"
|
||||
)
|
||||
|
||||
input = input("Please select a hologram:") as null|anything in icon_list
|
||||
if(input)
|
||||
qdel(holo_icon)
|
||||
switch(input)
|
||||
if("xeno queen")
|
||||
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")
|
||||
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,15 +1,9 @@
|
||||
|
||||
/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)
|
||||
/mob/camera/aiEye/proc/setLoc(T, force_update = FALSE, dir)
|
||||
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)
|
||||
H.move_hologram(ai, T, dir)
|
||||
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)
|
||||
user.eyeobj.setLoc(step, null, direct)
|
||||
|
||||
user.cooldown = world.timeofday + 5
|
||||
if(user.acceleration)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/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>")
|
||||
@@ -58,10 +58,12 @@
|
||||
var/canholo = TRUE
|
||||
var/obj/item/card/id/access_card = null
|
||||
var/chassis = "repairbot"
|
||||
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/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/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'
|
||||
@@ -69,22 +71,20 @@
|
||||
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/overload_ventcrawl = 0
|
||||
var/overload_bulletblock = 0 //Why is this a good idea?
|
||||
var/overload_maxhealth = 0
|
||||
var/radio_short = FALSE
|
||||
var/radio_short_cooldown = 5 MINUTES
|
||||
var/radio_short_timerid
|
||||
|
||||
canmove = FALSE
|
||||
var/silent = FALSE
|
||||
var/brightness_power = 5
|
||||
|
||||
/mob/living/silicon/pai/can_unbuckle()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/can_buckle()
|
||||
return FALSE
|
||||
var/icon/custom_holoform_icon
|
||||
|
||||
/mob/living/silicon/pai/Destroy()
|
||||
if (loc != card)
|
||||
@@ -118,6 +118,13 @@
|
||||
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
|
||||
@@ -133,8 +140,7 @@
|
||||
AR.Grant(src)
|
||||
AL.Grant(src)
|
||||
ALM.Grant(src)
|
||||
emittersemicd = TRUE
|
||||
addtimer(CALLBACK(src, .proc/emittercool), 600)
|
||||
emitter_next_use = world.time + 10 SECONDS
|
||||
|
||||
/mob/living/silicon/pai/Life()
|
||||
if(hacking)
|
||||
@@ -228,7 +234,7 @@
|
||||
/datum/action/innate/pai/shell/Trigger()
|
||||
..()
|
||||
if(P.holoform)
|
||||
P.fold_in(0)
|
||||
P.fold_in(FALSE)
|
||||
else
|
||||
P.fold_out()
|
||||
|
||||
@@ -292,3 +298,132 @@
|
||||
|
||||
/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,9 +8,10 @@
|
||||
return
|
||||
take_holo_damage(50/severity)
|
||||
Knockdown(400/severity)
|
||||
silent = max(30/severity, silent)
|
||||
silent = max((3 MINUTES)/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)
|
||||
@@ -26,13 +27,14 @@
|
||||
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("help")
|
||||
if(INTENT_HELP)
|
||||
visible_message("<span class='notice'>[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.</span>")
|
||||
if("disarm")
|
||||
if(INTENT_DISARM)
|
||||
visible_message("<span class='notice'>[user] boops [src] on the head!</span>")
|
||||
if("harm")
|
||||
if(INTENT_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>")
|
||||
@@ -41,14 +43,19 @@
|
||||
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/Proj)
|
||||
if(Proj.stun)
|
||||
/mob/living/silicon/pai/bullet_act(obj/item/projectile/P, def_zone)
|
||||
if(P.stun)
|
||||
fold_in(force = TRUE)
|
||||
src.visible_message("<span class='warning'>The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!</span>")
|
||||
. = ..(Proj)
|
||||
visible_message("<span class='warning'>The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!</span>")
|
||||
. = ..()
|
||||
|
||||
/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>")
|
||||
|
||||
@@ -12,12 +12,11 @@
|
||||
. = fold_in(force)
|
||||
return
|
||||
|
||||
if(emittersemicd)
|
||||
if(world.time < emitter_next_use)
|
||||
to_chat(src, "<span class='warning'>Error: Holochassis emitters recycling. Please try again later.</span>")
|
||||
return FALSE
|
||||
|
||||
emittersemicd = TRUE
|
||||
addtimer(CALLBACK(src, .proc/emittercool), emittercd)
|
||||
emitter_next_use = world.time + emittercd
|
||||
canmove = TRUE
|
||||
density = TRUE
|
||||
if(istype(card.loc, /obj/item/pda))
|
||||
@@ -46,20 +45,17 @@
|
||||
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)
|
||||
emittersemicd = TRUE
|
||||
if(!force)
|
||||
addtimer(CALLBACK(src, .proc/emittercool), emittercd)
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/emittercool), emitteroverloadcd)
|
||||
emitter_next_use = world.time + (force? emitteroverloadcd : emittercd)
|
||||
icon_state = "[chassis]"
|
||||
if(!holoform)
|
||||
. = fold_out(force)
|
||||
return
|
||||
visible_message("<span class='notice'>[src] deactivates its holochassis emitter and folds back into a compact card!</span>")
|
||||
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>")
|
||||
stop_pulling()
|
||||
if(client)
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
@@ -78,28 +74,39 @@
|
||||
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/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in possible_chassis
|
||||
if(!choice)
|
||||
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)
|
||||
return FALSE
|
||||
chassis = choice
|
||||
icon_state = "[chassis]"
|
||||
if(resting)
|
||||
icon_state = "[chassis]_rest"
|
||||
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()
|
||||
to_chat(src, "<span class='boldnotice'>You switch your holochassis projection composite to [chassis]</span>")
|
||||
|
||||
/mob/living/silicon/pai/lay_down()
|
||||
..()
|
||||
update_resting_icon(resting)
|
||||
|
||||
/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>")
|
||||
visible_message("<span class='notice'>[src] [resting? "lays down for a moment..." : "perks up from the ground"]</span>")
|
||||
update_icon()
|
||||
|
||||
/mob/living/silicon/pai/start_pulling(atom/movable/AM)
|
||||
/mob/living/silicon/pai/start_pulling(atom/movable/AM, gs)
|
||||
if(ispAI(AM))
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/proc/toggle_integrated_light()
|
||||
@@ -122,3 +129,22 @@
|
||||
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) && ..()
|
||||
|
||||
@@ -5,4 +5,11 @@
|
||||
..(message)
|
||||
|
||||
/mob/living/silicon/pai/binarycheck()
|
||||
return 0
|
||||
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 ..()
|
||||
|
||||
@@ -283,7 +283,10 @@
|
||||
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>"
|
||||
dat += "<A href='byond://?src=[REF(src)];software=radio;sub=0'>Radio Configuration</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=image'>Screen Display</A><br>"
|
||||
//dat += "Text Messaging <br>"
|
||||
dat += "<br>"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/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()
|
||||
@@ -114,6 +114,10 @@
|
||||
|
||||
var/cansprint = 1
|
||||
|
||||
var/orebox = null
|
||||
|
||||
/mob/living/silicon/robot
|
||||
|
||||
/mob/living/silicon/robot/get_cell()
|
||||
return cell
|
||||
|
||||
@@ -1298,4 +1302,12 @@
|
||||
|
||||
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_health = 1)
|
||||
if(istype(cell))
|
||||
cell.charge -= amount*5
|
||||
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()
|
||||
@@ -13,7 +13,19 @@
|
||||
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)
|
||||
@@ -30,24 +42,19 @@
|
||||
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(..()) //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(!.) //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(M.is_adult)
|
||||
damage = rand(20, 40)
|
||||
damage += rand(10, 20)
|
||||
else
|
||||
damage = rand(5, 35)
|
||||
damage = round(damage / 2) // borgs receive half damage
|
||||
damage += rand(2, 17)
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
@@ -56,23 +63,17 @@
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/mob/living/silicon/robot/attack_hand(mob/living/carbon/human/user)
|
||||
add_fingerprint(user)
|
||||
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 && !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)
|
||||
if(..()) // hulk attack
|
||||
spark_system.start()
|
||||
spawn(0)
|
||||
step_away(src,user,15)
|
||||
sleep(3)
|
||||
step_away(src,user,15)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/fire_act()
|
||||
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
|
||||
@@ -182,9 +183,9 @@
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(30)
|
||||
|
||||
/mob/living/silicon/robot/bullet_act(var/obj/item/projectile/Proj)
|
||||
..(Proj)
|
||||
/mob/living/silicon/robot/bullet_act(obj/item/projectile/P, def_zone)
|
||||
..()
|
||||
updatehealth()
|
||||
if(prob(75) && Proj.damage > 0)
|
||||
if(prob(75) && P.damage > 0)
|
||||
spark_system.start()
|
||||
return 2
|
||||
|
||||
@@ -121,6 +121,10 @@
|
||||
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()
|
||||
@@ -139,6 +143,9 @@
|
||||
|
||||
//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)
|
||||
@@ -362,30 +369,21 @@
|
||||
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'
|
||||
@@ -393,10 +391,7 @@
|
||||
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
|
||||
@@ -477,29 +472,20 @@
|
||||
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'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "dozersleeper"
|
||||
dogborg = TRUE
|
||||
if("Vale")
|
||||
cyborg_base_icon = "valeeng"
|
||||
hat_offset = INFINITY
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "valeengsleeper"
|
||||
dogborg = TRUE
|
||||
if("Alina")
|
||||
cyborg_base_icon = "alina-eng"
|
||||
special_light_key = "alina"
|
||||
hat_offset = INFINITY
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "alinasleeper"
|
||||
dogborg = TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/security
|
||||
@@ -558,36 +544,24 @@
|
||||
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()
|
||||
@@ -673,11 +647,11 @@
|
||||
/obj/item/reagent_containers/spray/cyborg_drying
|
||||
name = "drying agent spray"
|
||||
color = "#A000A0"
|
||||
list_reagents = list("drying_agent" = 250)
|
||||
list_reagents = list(/datum/reagent/drying_agent = 250)
|
||||
|
||||
/obj/item/reagent_containers/spray/cyborg_lube
|
||||
name = "lube spray"
|
||||
list_reagents = list("lube" = 250)
|
||||
list_reagents = list(/datum/reagent/lube = 250)
|
||||
|
||||
/obj/item/robot_module/clown
|
||||
name = "Clown"
|
||||
@@ -751,17 +725,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("enzyme", 2 * coeff)
|
||||
O.reagents.add_reagent(/datum/reagent/consumable/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("drying_agent", 5 * coeff)
|
||||
CD.reagents.add_reagent(/datum/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("lube", 2 * coeff)
|
||||
CL.reagents.add_reagent(/datum/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
|
||||
@@ -795,24 +769,18 @@
|
||||
if("(Service) DarkK9")
|
||||
cyborg_base_icon = "k50"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "ksleeper"
|
||||
dogborg = TRUE
|
||||
if("(Service) Vale")
|
||||
cyborg_base_icon = "valeserv"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "valeservsleeper"
|
||||
dogborg = TRUE
|
||||
if("(Service) ValeDark")
|
||||
cyborg_base_icon = "valeservdark"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "valeservsleeper"
|
||||
dogborg = TRUE
|
||||
if("(Janitor) Default")
|
||||
cyborg_base_icon = "janitor"
|
||||
if("(Janitor) Marina")
|
||||
@@ -830,10 +798,8 @@
|
||||
if("(Janitor) Scrubpuppy")
|
||||
cyborg_base_icon = "scrubpup"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
dogborg = TRUE
|
||||
sleeper_overlay = "jsleeper"
|
||||
dogborg = TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/miner
|
||||
@@ -845,13 +811,19 @@
|
||||
/obj/item/borg/sight/meson,
|
||||
/obj/item/storage/bag/ore/cyborg,
|
||||
/obj/item/pickaxe/drill/cyborg,
|
||||
/obj/item/shovel,
|
||||
/obj/item/twohanded/kinetic_crusher/cyborg,
|
||||
/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/stack/marker_beacon)
|
||||
/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)
|
||||
emag_modules = list(/obj/item/borg/stun)
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg/miner,
|
||||
@@ -863,7 +835,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")
|
||||
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")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
@@ -891,6 +863,11 @@
|
||||
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
|
||||
@@ -1036,3 +1013,8 @@
|
||||
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,6 +389,15 @@
|
||||
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,7 +6,10 @@
|
||||
return 2
|
||||
|
||||
/mob/living/silicon/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(..()) //if harm or disarm intent
|
||||
. = ..()
|
||||
if(!.) // the attack was blocked or was help/grab intent
|
||||
return
|
||||
if(M.a_intent == INTENT_HARM)
|
||||
var/damage = 20
|
||||
if (prob(90))
|
||||
log_combat(M, src, "attacked")
|
||||
@@ -49,34 +52,33 @@
|
||||
/mob/living/silicon/attack_paw(mob/living/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/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)
|
||||
/mob/living/silicon/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
..(user, 1)
|
||||
. = ..(user, TRUE)
|
||||
if(.)
|
||||
return
|
||||
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 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//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 ("help")
|
||||
if (INTENT_HELP)
|
||||
M.visible_message("[M] pets [src].", \
|
||||
"<span class='notice'>You pet [src].</span>")
|
||||
if("grab")
|
||||
if(INTENT_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)
|
||||
@@ -108,19 +110,25 @@
|
||||
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/Proj)
|
||||
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
adjustBruteLoss(Proj.damage)
|
||||
if(prob(Proj.damage*1.5))
|
||||
/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))
|
||||
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(Proj.stun || Proj.knockdown)
|
||||
if(P.stun || P.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 [Proj]!</span>")
|
||||
Proj.on_hit(src)
|
||||
M.visible_message("<span class='boldwarning'>[M] is knocked off of [src] by the [P]!</span>")
|
||||
P.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,20 +1,22 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M)
|
||||
..()
|
||||
. = ..()
|
||||
if(.) //the attack was blocked
|
||||
return
|
||||
switch(M.a_intent)
|
||||
if("help")
|
||||
if(INTENT_HELP)
|
||||
if (health > 0)
|
||||
visible_message("<span class='notice'>[M] [response_help] [src].</span>")
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
if("grab")
|
||||
if(INTENT_GRAB)
|
||||
if(grab_state >= GRAB_AGGRESSIVE && isliving(pulling))
|
||||
vore_attack(M, pulling)
|
||||
else
|
||||
grabbedby(M)
|
||||
|
||||
if("harm", "disarm")
|
||||
if(INTENT_HARM, INTENT_DISARM)
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='notice'>You don't want to hurt [src]!</span>")
|
||||
return
|
||||
@@ -27,12 +29,11 @@
|
||||
updatehealth()
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
/mob/living/simple_animal/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 FALSE
|
||||
..(user, 1)
|
||||
. = ..(user, TRUE)
|
||||
if(.)
|
||||
return
|
||||
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)
|
||||
@@ -40,32 +41,32 @@
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(..()) //successful monkey bite.
|
||||
if(stat != DEAD)
|
||||
var/damage = rand(1, 3)
|
||||
attack_threshold_check(damage)
|
||||
return 1
|
||||
. = ..()
|
||||
if(.) //successful larva bite
|
||||
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(..()) //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
|
||||
. = ..()
|
||||
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")
|
||||
|
||||
/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
. = ..()
|
||||
@@ -82,7 +83,8 @@
|
||||
return attack_threshold_check(damage, M.melee_damage_type)
|
||||
|
||||
/mob/living/simple_animal/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
. = ..()
|
||||
if(.) //successful slime shock
|
||||
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("astral") && !H.mind)
|
||||
if(H.reagents.has_reagent(/datum/reagent/fermi/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)
|
||||
target_turf.PlaceOnTop(/turf/open/floor/plasteel, flags = CHANGETURF_INHERIT_AIR)
|
||||
else //Build a hull plating without a floor tile.
|
||||
target_turf.PlaceOnTop(/turf/open/floor/plating)
|
||||
target_turf.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
|
||||
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)
|
||||
F.PlaceOnTop(/turf/open/floor/plasteel, flags = CHANGETURF_INHERIT_AIR)
|
||||
|
||||
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))
|
||||
F.PlaceOnTop(initial(tiletype.turf_type), flags = CHANGETURF_INHERIT_AIR)
|
||||
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 == "harm")
|
||||
if(H.a_intent == 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 = "tricordrazine"
|
||||
var/treatment_brute = "bicaridine"
|
||||
var/treatment_brute_avoid = /datum/reagent/medicine/tricordrazine
|
||||
var/treatment_brute = /datum/reagent/medicine/bicaridine
|
||||
var/treatment_oxy_avoid = null
|
||||
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_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_virus_avoid = null
|
||||
var/treatment_virus = "spaceacillin"
|
||||
var/treatment_virus = /datum/reagent/medicine/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 = "tricordrazine"
|
||||
treatment_fire = "tricordrazine"
|
||||
treatment_tox = "tricordrazine"
|
||||
treatment_brute = /datum/reagent/medicine/tricordrazine
|
||||
treatment_fire = /datum/reagent/medicine/tricordrazine
|
||||
treatment_tox = /datum/reagent/medicine/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 = "pancuronium"
|
||||
treatment_oxy = /datum/reagent/toxin/pancuronium
|
||||
treatment_brute_avoid = null
|
||||
treatment_brute = "pancuronium"
|
||||
treatment_brute = /datum/reagent/toxin/pancuronium
|
||||
treatment_fire_avoid = null
|
||||
treatment_fire = "sodium_thiopental"
|
||||
treatment_fire = /datum/reagent/toxin/sodium_thiopental
|
||||
treatment_tox_avoid = null
|
||||
treatment_tox = "sodium_thiopental"
|
||||
treatment_tox = /datum/reagent/toxin/sodium_thiopental
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/update_icon()
|
||||
cut_overlays()
|
||||
@@ -369,8 +369,9 @@
|
||||
|
||||
//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/datum/reagent/R in reagent_glass.reagents.reagent_list)
|
||||
if(!C.reagents.has_reagent(R.id))
|
||||
for(var/A in reagent_glass.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(!C.reagents.has_reagent(R.type))
|
||||
return TRUE
|
||||
|
||||
//They're injured enough for it!
|
||||
@@ -477,8 +478,9 @@
|
||||
|
||||
//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/datum/reagent/R in reagent_glass.reagents.reagent_list)
|
||||
if(!C.reagents.has_reagent(R.id))
|
||||
for(var/A in reagent_glass.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(!C.reagents.has_reagent(R.type))
|
||||
reagent_id = "internal_beaker"
|
||||
break
|
||||
|
||||
|
||||
@@ -151,7 +151,8 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(. && !QDELETED(src)) //Got hit and not blown up yet.
|
||||
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("whiskey", 15)
|
||||
S.reagents.add_reagent(/datum/reagent/consumable/ethanol/whiskey, 15)
|
||||
S.on_reagent_change(ADD_REAGENT)
|
||||
..()
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
. = ..()
|
||||
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)
|
||||
@@ -229,24 +233,6 @@
|
||||
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."
|
||||
@@ -290,10 +276,12 @@
|
||||
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("nutriment", 0.4)
|
||||
L.reagents.add_reagent("vitamin", 0.4)
|
||||
L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4)
|
||||
L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4)
|
||||
|
||||
//Cat made
|
||||
/mob/living/simple_animal/pet/cat/custom_cat
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
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
|
||||
@@ -268,7 +273,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, "pet_corgi", /datum/mood_event/pet_corgi)
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, src, /datum/mood_event/pet_animal, src)
|
||||
return
|
||||
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(item_to_add))
|
||||
@@ -639,22 +644,3 @@
|
||||
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,6 +130,7 @@
|
||||
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)
|
||||
mob_try_pickup(user)
|
||||
if(user.a_intent != INTENT_HELP)
|
||||
return ..() // TODO: convert picking up mobs into an element or component.
|
||||
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("milk", 20)
|
||||
reagents.add_reagent(/datum/reagent/consumable/milk, 20)
|
||||
. = ..()
|
||||
|
||||
/obj/item/udder/proc/generateMilk()
|
||||
if(prob(5))
|
||||
reagents.add_reagent("milk", rand(5, 10))
|
||||
reagents.add_reagent(/datum/reagent/consumable/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("nutriment" = 3, "vitamin" = 2)
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2)
|
||||
foodtype = GROSS | MEAT | RAW
|
||||
grind_results = list("blood" = 20, "liquidgibs" = 5)
|
||||
grind_results = list(/datum/reagent/blood = 20, /datum/reagent/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 = "toxin"
|
||||
var/poison_type = /datum/reagent/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/dead/observer/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
|
||||
var/list/mob/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/dead/observer/C = pick(candidates)
|
||||
var/mob/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/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)
|
||||
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)
|
||||
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
var/mob/C = pick(candidates)
|
||||
spawn_guardian(user, C.key)
|
||||
else
|
||||
to_chat(user, "[failure_message]")
|
||||
|
||||
@@ -54,10 +54,8 @@
|
||||
var/blocked = FALSE
|
||||
if(hasmatchingsummoner(A)) //if the summoner matches don't hurt them
|
||||
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(L.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("nutriment" = 3, "vitamin" = 2)
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2)
|
||||
foodtype = GROSS | MEAT | RAW
|
||||
grind_results = list("blood" = 20, "liquidgibs" = 5)
|
||||
juice_results = list("banana" = 0)
|
||||
grind_results = list(/datum/reagent/blood = 20, /datum/reagent/liquidgibs = 5)
|
||||
juice_results = list(/datum/reagent/consumable/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.id, rand(1,5))
|
||||
L.reagents.add_reagent(beegent.type, 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[initial(R.id)])
|
||||
assign_reagent(GLOB.chemical_reagents_list[R])
|
||||
|
||||
/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.id, rand(1,5))
|
||||
L.reagents.add_reagent(beegent.type, 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.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent)
|
||||
if(B.beegent && beegent && B.beegent.type != beegent.type || B.beegent && !beegent || !B.beegent && beegent)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -253,9 +253,10 @@
|
||||
/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
|
||||
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/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)
|
||||
var/obj/item/queen_bee/qb = new(user.drop_location())
|
||||
qb.queen = new(qb)
|
||||
if(queen && queen.beegent)
|
||||
@@ -266,8 +267,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.id, 5))
|
||||
S.reagents.remove_reagent(R.id,5)
|
||||
if(R && S.reagents.has_reagent(R.type, 5))
|
||||
S.reagents.remove_reagent(R.type,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 = "toxin"
|
||||
var/poison_type = /datum/reagent/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 = "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 = /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?
|
||||
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 = "frostoil"
|
||||
poison_type = /datum/reagent/consumable/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 = "frostoil"
|
||||
poison_type = /datum/reagent/consumable/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 = "frostoil"
|
||||
poison_type = /datum/reagent/consumable/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("leaper_venom", 5)
|
||||
C.reagents.add_reagent(/datum/reagent/toxin/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("leaper_venom", 5)
|
||||
C.reagents.add_reagent(/datum/reagent/toxin/leaper_venom, 5)
|
||||
if(isanimal(L))
|
||||
var/mob/living/simple_animal/A = L
|
||||
A.adjustHealth(25)
|
||||
@@ -105,7 +105,6 @@
|
||||
|
||||
/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,10 +486,7 @@ Difficulty: Very Hard
|
||||
if(isturf(Stuff))
|
||||
var/turf/T = Stuff
|
||||
if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors)
|
||||
var/turf/open/O = T.ChangeTurf(NewTerrainFloors)
|
||||
if(O.air)
|
||||
var/datum/gas_mixture/G = O.air
|
||||
G.copy_from_turf(O)
|
||||
var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR)
|
||||
if(prob(florachance) && NewFlora.len && !is_blocked_turf(O, TRUE))
|
||||
var/atom/Picked = pick(NewFlora)
|
||||
new Picked(O)
|
||||
|
||||
@@ -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
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
|
||||
var/list/crusher_loot
|
||||
var/medal_type
|
||||
var/score_type = BOSS_SCORE
|
||||
|
||||
@@ -240,7 +240,8 @@ obj/structure/elite_tumor/proc/return_elite()
|
||||
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.
|
||||
addtimer(CALLBACK(src, .proc/arena_checks), 50)
|
||||
if(!QDELETED(src))
|
||||
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))
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
|
||||
/obj/item/udder/gutlunch/generateMilk()
|
||||
if(prob(60))
|
||||
reagents.add_reagent("cream", rand(2, 5))
|
||||
reagents.add_reagent(/datum/reagent/consumable/cream, rand(2, 5))
|
||||
if(prob(45))
|
||||
reagents.add_reagent("salglu_solution", rand(2,5))
|
||||
reagents.add_reagent(/datum/reagent/medicine/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 = 5
|
||||
var/crusher_drop_mod = 25
|
||||
|
||||
/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 20 creatures before getting the item
|
||||
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
|
||||
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)
|
||||
T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland, flags = CHANGETURF_INHERIT_AIR)
|
||||
qdel(src)
|
||||
|
||||
@@ -166,7 +166,9 @@
|
||||
..()
|
||||
|
||||
/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()
|
||||
|
||||
@@ -185,6 +187,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("mushroomhallucinogen", powerlevel)
|
||||
S.reagents.add_reagent("omnizine", powerlevel)
|
||||
S.reagents.add_reagent("synaptizine", powerlevel)
|
||||
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)
|
||||
|
||||
@@ -141,9 +141,9 @@
|
||||
. = ..()
|
||||
remove_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE)
|
||||
var/amount = 0
|
||||
if(reagents.has_reagent("morphine")) // morphine slows slimes down
|
||||
if(reagents.has_reagent(/datum/reagent/medicine/morphine)) // morphine slows slimes down
|
||||
amount = 2
|
||||
if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow
|
||||
if(reagents.has_reagent(/datum/reagent/consumable/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,33 +253,34 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/slime/attack_slime(mob/living/simple_animal/slime/M)
|
||||
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()
|
||||
. = ..()
|
||||
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()
|
||||
|
||||
/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)
|
||||
@@ -321,9 +322,11 @@
|
||||
attacked += 10
|
||||
|
||||
/mob/living/simple_animal/slime/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(..()) //if harm or disarm intent.
|
||||
attacked += 10
|
||||
discipline_slime(M)
|
||||
. = ..()
|
||||
if(!.) // the attack was blocked or was help/grab intent
|
||||
return
|
||||
attacked += 10
|
||||
discipline_slime(M)
|
||||
|
||||
|
||||
/mob/living/simple_animal/slime/attackby(obj/item/W, mob/living/user, params)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//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().
|
||||
+13
-11
@@ -567,9 +567,9 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
/mob/proc/is_muzzled()
|
||||
return 0
|
||||
|
||||
/mob/Stat(delayoverride)
|
||||
. = ..()
|
||||
var/statdelay = delayoverride || 10
|
||||
/mob/Stat()
|
||||
..()
|
||||
|
||||
if(statpanel("Status"))
|
||||
if (client)
|
||||
stat(null, "Ping: [round(client.lastping, 1)]ms (Average: [round(client.avgping, 1)]ms)")
|
||||
@@ -577,7 +577,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 || "NULL"]")
|
||||
stat(null, "Round ID: [GLOB.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,9 +587,8 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
if(ETA)
|
||||
stat(null, "[ETA] [SSshuttle.emergency.getTimerStr()]")
|
||||
|
||||
if(client?.holder)
|
||||
if(client && 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]")
|
||||
@@ -615,7 +614,6 @@ 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
|
||||
@@ -639,13 +637,14 @@ 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)
|
||||
@@ -802,11 +801,14 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
|
||||
//can the mob be buckled to something by default?
|
||||
/mob/proc/can_buckle()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//can the mob be unbuckled from something by default?
|
||||
/mob/proc/can_unbuckle()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/proc/can_buckle_others(mob/living/target, atom/buckle_to)
|
||||
return TRUE
|
||||
|
||||
//Can the mob interact() with an atom?
|
||||
/mob/proc/can_interact_with(atom/A)
|
||||
@@ -958,4 +960,4 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
|
||||
/mob/setMovetype(newval)
|
||||
. = ..()
|
||||
update_movespeed(FALSE)
|
||||
update_movespeed(FALSE)
|
||||
@@ -29,6 +29,7 @@
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user