mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 11:05:03 +01:00
Merge branch 'master' into hook-kill-v10-final-ultimate-final
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
name = "alien"
|
||||
voice_name = "alien"
|
||||
speak_emote = list("hisses")
|
||||
bubble_icon = "alien"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
gender = NEUTER
|
||||
dna = null
|
||||
|
||||
@@ -136,14 +136,11 @@ Doesn't work on other aliens/AI.*/
|
||||
set category = "Alien"
|
||||
|
||||
if(powerc())
|
||||
if(stomach_contents.len)
|
||||
if(LAZYLEN(stomach_contents))
|
||||
for(var/mob/M in src)
|
||||
if(M in stomach_contents)
|
||||
stomach_contents.Remove(M)
|
||||
M.forceMove(loc)
|
||||
//Paralyse(10)
|
||||
src.visible_message("<span class='alertalien'><B>[src] hurls out the contents of [p_their()] stomach!</span>")
|
||||
return
|
||||
LAZYREMOVE(stomach_contents, M)
|
||||
M.forceMove(drop_location())
|
||||
visible_message("<span class='alertalien'><B>[src] hurls out the contents of [p_their()] stomach!</span>")
|
||||
|
||||
/mob/living/carbon/proc/getPlasma()
|
||||
var/obj/item/organ/internal/xenos/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/xenos/plasmavessel)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
icon_state = "alienq_s"
|
||||
status_flags = CANPARALYSE
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
bubble_icon = "alienroyal"
|
||||
large = 1
|
||||
ventcrawler = 0
|
||||
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/handle_atom_del(atom/A)
|
||||
if(A in processing_patches)
|
||||
processing_patches -= A
|
||||
LAZYREMOVE(processing_patches, A)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/blob_act(obj/structure/blob/B)
|
||||
@@ -51,41 +50,40 @@
|
||||
|
||||
/mob/living/carbon/var/last_stomach_attack //defining this here because no one would look in carbon_defines for it
|
||||
|
||||
/mob/living/carbon/relaymove(var/mob/user, direction)
|
||||
if(user in src.stomach_contents)
|
||||
if(last_stomach_attack + STOMACH_ATTACK_DELAY > world.time) return
|
||||
/mob/living/carbon/relaymove(mob/user, direction)
|
||||
if(LAZYLEN(stomach_contents))
|
||||
if(user in stomach_contents)
|
||||
if(last_stomach_attack + STOMACH_ATTACK_DELAY > world.time)
|
||||
return
|
||||
|
||||
last_stomach_attack = world.time
|
||||
for(var/mob/M in hearers(4, src))
|
||||
if(M.client)
|
||||
M.show_message(text("<span class='warning'>You hear something rumbling inside [src]'s stomach...</span>"), 2)
|
||||
|
||||
var/obj/item/I = user.get_active_hand()
|
||||
if(I && I.force)
|
||||
var/d = rand(round(I.force / 4), I.force)
|
||||
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/obj/item/organ/external/organ = H.get_organ("chest")
|
||||
if(istype(organ))
|
||||
if(organ.receive_damage(d, 0))
|
||||
H.UpdateDamageIcon()
|
||||
|
||||
H.updatehealth("stomach attack")
|
||||
|
||||
else
|
||||
src.take_organ_damage(d)
|
||||
|
||||
for(var/mob/M in viewers(user, null))
|
||||
last_stomach_attack = world.time
|
||||
for(var/mob/M in hearers(4, src))
|
||||
if(M.client)
|
||||
M.show_message(text("<span class='warning'><B>[user] attacks [src]'s stomach wall with the [I.name]!</span>"), 2)
|
||||
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
M.show_message(text("<span class='warning'>You hear something rumbling inside [src]'s stomach...</span>"), 2)
|
||||
|
||||
if(prob(src.getBruteLoss() - 50))
|
||||
for(var/atom/movable/A in stomach_contents)
|
||||
A.forceMove(drop_location())
|
||||
stomach_contents.Remove(A)
|
||||
src.gib()
|
||||
var/obj/item/I = user.get_active_hand()
|
||||
if(I && I.force)
|
||||
var/d = rand(round(I.force / 4), I.force)
|
||||
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/obj/item/organ/external/organ = H.get_organ("chest")
|
||||
if(istype(organ))
|
||||
if(organ.receive_damage(d, 0))
|
||||
H.UpdateDamageIcon()
|
||||
|
||||
H.updatehealth("stomach attack")
|
||||
|
||||
else
|
||||
take_organ_damage(d)
|
||||
|
||||
for(var/mob/M in viewers(user, null))
|
||||
if(M.client)
|
||||
M.show_message(text("<span class='warning'><B>[user] attacks [src]'s stomach wall with the [I.name]!</span>"), 2)
|
||||
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
|
||||
if(prob(getBruteLoss() - 50))
|
||||
gib()
|
||||
|
||||
#undef STOMACH_ATTACK_DELAY
|
||||
|
||||
@@ -140,9 +138,8 @@
|
||||
I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
|
||||
|
||||
for(var/mob/M in src)
|
||||
if(M in src.stomach_contents)
|
||||
src.stomach_contents.Remove(M)
|
||||
M.forceMove(get_turf(src))
|
||||
LAZYREMOVE(stomach_contents, M)
|
||||
M.forceMove(drop_location())
|
||||
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
|
||||
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
|
||||
@@ -1069,10 +1066,6 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
|
||||
|
||||
/mob/living/carbon/proc/forceFedAttackLog(var/obj/item/reagent_containers/food/toEat, mob/user)
|
||||
add_attack_logs(user, src, "Fed [toEat]. Reagents: [toEat.reagents.log_list(toEat)]", toEat.reagents.harmless_helper() ? ATKLOG_ALMOSTALL : null)
|
||||
if(!iscarbon(user))
|
||||
LAssailant = null
|
||||
else
|
||||
LAssailant = user
|
||||
|
||||
|
||||
/*TO DO - If/when stomach organs are introduced, override this at the human level sending the item to the stomach
|
||||
@@ -1205,3 +1198,18 @@ so that different stomachs can handle things in different ways VB*/
|
||||
I.acid_level = 0 //washes off the acid on our clothes
|
||||
I.extinguish() //extinguishes our clothes
|
||||
..()
|
||||
|
||||
/mob/living/carbon/clean_blood(clean_hands = TRUE, clean_mask = TRUE, clean_feet = TRUE)
|
||||
if(head)
|
||||
if(head.clean_blood())
|
||||
update_inv_head()
|
||||
if(head.flags_inv & HIDEMASK)
|
||||
clean_mask = FALSE
|
||||
if(wear_suit)
|
||||
if(wear_suit.clean_blood())
|
||||
update_inv_wear_suit()
|
||||
if(wear_suit.flags_inv & HIDESHOES)
|
||||
clean_feet = FALSE
|
||||
if(wear_suit.flags_inv & HIDEGLOVES)
|
||||
clean_hands = FALSE
|
||||
..(clean_hands, clean_mask, clean_feet)
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/mob/living/carbon
|
||||
gender = MALE
|
||||
pressure_resistance = 15
|
||||
var/list/stomach_contents = list()
|
||||
var/list/processing_patches = list()
|
||||
var/list/stomach_contents
|
||||
var/list/processing_patches
|
||||
var/list/internal_organs = list()
|
||||
var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
|
||||
var/antibodies = 0
|
||||
|
||||
var/life_tick = 0 // The amount of life ticks that have processed on this mob.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
if(!isSynthetic())
|
||||
if(!ismachineperson(src))
|
||||
animation = new(loc)
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
@@ -32,12 +32,11 @@
|
||||
E.droplimb(DROPLIMB_SHARP)
|
||||
|
||||
for(var/mob/M in src)
|
||||
if(M in stomach_contents)
|
||||
stomach_contents.Remove(M)
|
||||
M.forceMove(get_turf(src))
|
||||
LAZYREMOVE(stomach_contents, M)
|
||||
M.forceMove(drop_location())
|
||||
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
|
||||
|
||||
if(!isSynthetic())
|
||||
if(!ismachineperson(src))
|
||||
flick("gibbed-h", animation)
|
||||
hgibs(loc, dna)
|
||||
else
|
||||
@@ -106,11 +105,6 @@
|
||||
//Handle species-specific deaths.
|
||||
dna.species.handle_death(gibbed, src)
|
||||
|
||||
if(ishuman(LAssailant))
|
||||
var/mob/living/carbon/human/H=LAssailant
|
||||
if(H.mind)
|
||||
H.mind.kills += "[key_name(src)]"
|
||||
|
||||
if(SSticker && SSticker.mode)
|
||||
// log_world("k")
|
||||
sql_report_death(src)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
//Cooldown-inducing emotes
|
||||
if("ping", "pings", "buzz", "buzzes", "beep", "beeps", "yes", "no", "buzz2")
|
||||
var/found_machine_head = FALSE
|
||||
if(ismachine(src)) //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise.
|
||||
if(ismachineperson(src)) //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise.
|
||||
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
|
||||
found_machine_head = TRUE
|
||||
else
|
||||
@@ -947,7 +947,7 @@
|
||||
if("Skrell")
|
||||
emotelist += "\nSkrell specific emotes :- warble(s)"
|
||||
|
||||
if(ismachine(src))
|
||||
if(ismachineperson(src))
|
||||
emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob"
|
||||
else
|
||||
var/obj/item/organ/external/head/H = get_organ("head") // If you have a robotic head, you can make beep-boop noises
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
if(!E)
|
||||
wound_flavor_text["[organ_tag]"] = "<B>[p_they(TRUE)] [p_are()] missing [p_their()] [organ_descriptor].</B>\n"
|
||||
else
|
||||
if(!isSynthetic())
|
||||
if(!ismachineperson(src))
|
||||
if(E.is_robotic())
|
||||
wound_flavor_text["[E.limb_name]"] = "[p_they(TRUE)] [p_have()] a robotic [E.name]!\n"
|
||||
|
||||
@@ -252,7 +252,7 @@
|
||||
var/temp = getBruteLoss() //no need to calculate each of these twice
|
||||
|
||||
if(temp)
|
||||
var/brute_message = !isSynthetic() ? "bruising" : "denting"
|
||||
var/brute_message = !ismachineperson(src) ? "bruising" : "denting"
|
||||
if(temp < 30)
|
||||
msg += "[p_they(TRUE)] [p_have()] minor [brute_message ].\n"
|
||||
else
|
||||
@@ -301,13 +301,13 @@
|
||||
else if(nutrition >= NUTRITION_LEVEL_FAT)
|
||||
msg += "[p_they(TRUE)] [p_are()] quite chubby.\n"
|
||||
|
||||
if(!isSynthetic() && blood_volume < BLOOD_VOLUME_SAFE)
|
||||
if(!ismachineperson(src) && blood_volume < BLOOD_VOLUME_SAFE)
|
||||
msg += "[p_they(TRUE)] [p_have()] pale skin.\n"
|
||||
|
||||
if(bleedsuppress)
|
||||
msg += "[p_they(TRUE)] [p_are()] bandaged with something.\n"
|
||||
else if(bleed_rate)
|
||||
var/bleed_message = !isSynthetic() ? "bleeding" : "leaking"
|
||||
var/bleed_message = !ismachineperson(src) ? "bleeding" : "leaking"
|
||||
msg += "<B>[p_they(TRUE)] [p_are()] [bleed_message]!</B>\n"
|
||||
|
||||
if(reagents.has_reagent("teslium"))
|
||||
|
||||
@@ -1162,18 +1162,6 @@
|
||||
custom_pain("You feel a stabbing pain in your chest!")
|
||||
L.damage = L.min_bruised_damage
|
||||
|
||||
//returns 1 if made bloody, returns 0 otherwise
|
||||
|
||||
/mob/living/carbon/human/clean_blood(var/clean_feet)
|
||||
.=..()
|
||||
if(clean_feet && !shoes && istype(feet_blood_DNA, /list) && feet_blood_DNA.len)
|
||||
feet_blood_color = null
|
||||
qdel(feet_blood_DNA)
|
||||
bloody_feet = list(BLOOD_STATE_HUMAN = 0, BLOOD_STATE_XENO = 0, BLOOD_STATE_NOT_BLOODY = 0)
|
||||
blood_state = BLOOD_STATE_NOT_BLOODY
|
||||
update_inv_shoes()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/cuff_resist(obj/item/I)
|
||||
if(HULK in mutations)
|
||||
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
|
||||
@@ -1701,14 +1689,14 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
|
||||
|
||||
/mob/living/carbon/human/forceFed(var/obj/item/reagent_containers/food/toEat, mob/user, fullness)
|
||||
if(!check_has_mouth())
|
||||
if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (ismachine(src)))))
|
||||
if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (ismachineperson(src)))))
|
||||
to_chat(user, "Where do you intend to put \the [toEat]? \The [src] doesn't have a mouth!")
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/selfDrink(var/obj/item/reagent_containers/food/drinks/toDrink)
|
||||
if(!check_has_mouth())
|
||||
if(!ismachine(src))
|
||||
if(!ismachineperson(src))
|
||||
to_chat(src, "Where do you intend to put \the [src]? You don't have a mouth!")
|
||||
return 0
|
||||
else
|
||||
|
||||
@@ -84,7 +84,7 @@ emp_act
|
||||
E.heal_damage(rembrute,0,0,1)
|
||||
rembrute = nrembrute
|
||||
user.visible_message("<span class='alert'>[user] patches some dents on [src]'s [E.name] with [I].</span>")
|
||||
if(bleed_rate && isSynthetic())
|
||||
if(bleed_rate && ismachineperson(src))
|
||||
bleed_rate = 0
|
||||
user.visible_message("<span class='alert'>[user] patches some leaks on [src] with [I].</span>")
|
||||
if(IgniteMob())
|
||||
@@ -387,11 +387,6 @@ emp_act
|
||||
to_chat(user, "<span class='warning'>You hack off a chunk of meat from [name]</span>")
|
||||
if(!meatleft)
|
||||
add_attack_logs(user, src, "Chopped up into meat")
|
||||
if(!iscarbon(user))
|
||||
LAssailant = null
|
||||
else
|
||||
LAssailant = user
|
||||
|
||||
qdel(src)
|
||||
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(user.zone_selected))
|
||||
|
||||
@@ -37,7 +37,6 @@ GLOBAL_DATUM_INIT(default_martial_art, /datum/martial_art, new())
|
||||
var/obj/item/s_store = null
|
||||
|
||||
var/icon/stand_icon = null
|
||||
var/icon/lying_icon = null
|
||||
|
||||
var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life()
|
||||
|
||||
|
||||
@@ -635,7 +635,7 @@
|
||||
else
|
||||
overeatduration -= 2
|
||||
|
||||
if(!ismachine(src) && nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA) //Gosh damn snowflakey IPCs
|
||||
if(!ismachineperson(src) && nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA) //Gosh damn snowflakey IPCs
|
||||
var/datum/disease/D = new /datum/disease/critical/hypoglycemia
|
||||
ForceContractDisease(D)
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
alcohol_strength /= sober_str
|
||||
|
||||
var/obj/item/organ/internal/liver/L
|
||||
if(!isSynthetic())
|
||||
if(!ismachineperson(src))
|
||||
L = get_int_organ(/obj/item/organ/internal/liver)
|
||||
if(L)
|
||||
alcohol_strength *= L.alcohol_intensity
|
||||
@@ -719,7 +719,7 @@
|
||||
AdjustConfused(3 / sober_str)
|
||||
if(alcohol_strength >= blur_start) //blurry eyes
|
||||
EyeBlurry(10 / sober_str)
|
||||
if(!isSynthetic()) //stuff only for non-synthetics
|
||||
if(!ismachineperson(src)) //stuff only for non-synthetics
|
||||
if(alcohol_strength >= vomit_start) //vomiting
|
||||
if(prob(8))
|
||||
fakevomit()
|
||||
|
||||
@@ -352,21 +352,6 @@
|
||||
if(organ.receive_damage(damage, 0, sharp, used_weapon))
|
||||
H.UpdateDamageIcon()
|
||||
|
||||
if(H.LAssailant && ishuman(H.LAssailant)) //superheros still get the comical hit markers
|
||||
var/mob/living/carbon/human/A = H.LAssailant
|
||||
if(A.mind && (A.mind in (SSticker.mode.superheroes) || SSticker.mode.supervillains || SSticker.mode.greyshirts))
|
||||
var/list/attack_bubble_recipients = list()
|
||||
var/mob/living/user
|
||||
for(var/mob/O in viewers(user, src))
|
||||
if(O.client && O.has_vision(information_only=TRUE))
|
||||
attack_bubble_recipients.Add(O.client)
|
||||
spawn(0)
|
||||
var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1)
|
||||
dmgIcon.pixel_x = (!H.lying) ? rand(-3,3) : rand(-11,12)
|
||||
dmgIcon.pixel_y = (!H.lying) ? rand(-11,9) : rand(-10,1)
|
||||
flick_overlay(dmgIcon, attack_bubble_recipients, 9)
|
||||
|
||||
|
||||
if(BURN)
|
||||
H.damageoverlaytemp = 20
|
||||
damage = damage * burn_mod
|
||||
@@ -443,6 +428,9 @@
|
||||
else
|
||||
target.LAssailant = user
|
||||
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
|
||||
var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh)
|
||||
damage += attack.damage
|
||||
if(!damage)
|
||||
|
||||
@@ -376,7 +376,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
|
||||
|
||||
//base icons
|
||||
var/icon/hair_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
|
||||
if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic())))
|
||||
if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(ismachineperson(src))))
|
||||
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style]
|
||||
if(hair_style && hair_style.species_allowed)
|
||||
if((head_organ.dna.species.name in hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics...
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
if(stat != DEAD)
|
||||
handle_organs()
|
||||
|
||||
//stuff in the stomach
|
||||
if(LAZYLEN(stomach_contents))
|
||||
handle_stomach(times_fired)
|
||||
|
||||
. = ..()
|
||||
|
||||
if(QDELETED(src))
|
||||
@@ -254,14 +258,15 @@
|
||||
if(times_fired % 20==2) //dry off a bit once every 20 ticks or so
|
||||
wetlevel = max(wetlevel - 1,0)
|
||||
|
||||
/mob/living/carbon/handle_stomach(times_fired)
|
||||
for(var/mob/living/M in stomach_contents)
|
||||
/mob/living/carbon/proc/handle_stomach(times_fired)
|
||||
for(var/thing in stomach_contents)
|
||||
var/mob/living/M = thing
|
||||
if(M.loc != src)
|
||||
stomach_contents.Remove(M)
|
||||
LAZYREMOVE(stomach_contents, M)
|
||||
continue
|
||||
if(stat != DEAD)
|
||||
if(M.stat == DEAD)
|
||||
stomach_contents.Remove(M)
|
||||
LAZYREMOVE(stomach_contents, M)
|
||||
qdel(M)
|
||||
continue
|
||||
if(times_fired % 3 == 1)
|
||||
@@ -476,7 +481,7 @@
|
||||
P.reagents.remove_any(applied_amount * 0.5)
|
||||
else
|
||||
if(!P.reagents || P.reagents.total_volume <= 0)
|
||||
processing_patches -= P
|
||||
LAZYREMOVE(processing_patches, P)
|
||||
qdel(P)
|
||||
|
||||
/mob/living/carbon/proc/handle_germs()
|
||||
|
||||
@@ -58,9 +58,6 @@
|
||||
|
||||
handle_fire()
|
||||
|
||||
//stuff in the stomach
|
||||
handle_stomach(times_fired)
|
||||
|
||||
update_gravity(mob_has_gravity())
|
||||
|
||||
if(pulling)
|
||||
@@ -117,9 +114,6 @@
|
||||
/mob/living/proc/handle_environment(datum/gas_mixture/environment)
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_stomach(times_fired)
|
||||
return
|
||||
|
||||
/mob/living/proc/update_pulling()
|
||||
if(incapacitated())
|
||||
stop_pulling()
|
||||
|
||||
@@ -682,9 +682,6 @@
|
||||
*/////////////////////
|
||||
/mob/living/proc/resist_grab()
|
||||
var/resisting = 0
|
||||
for(var/obj/O in requests)
|
||||
qdel(O)
|
||||
resisting++
|
||||
for(var/X in grabbed_by)
|
||||
var/obj/item/grab/G = X
|
||||
resisting++
|
||||
|
||||
@@ -61,7 +61,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return default_language
|
||||
|
||||
/mob/living/proc/handle_speech_problems(list/message_pieces, var/verb)
|
||||
var/robot = isSynthetic()
|
||||
var/robot = ismachineperson(src)
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
if(S.speaking && S.speaking.flags & NO_STUTTER)
|
||||
continue
|
||||
@@ -269,12 +269,12 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
M.hear_say(message_pieces, verb, italics, src, speech_sound, sound_vol, sound_frequency)
|
||||
if(M.client)
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
spawn(0)
|
||||
if(loc && !isturf(loc))
|
||||
var/atom/A = loc //Non-turf, let it handle the speech bubble
|
||||
A.speech_bubble("hR[speech_bubble_test]", A, speech_bubble_recipients)
|
||||
else //Turf, leave speech bubbles to the mob
|
||||
speech_bubble("h[speech_bubble_test]", src, speech_bubble_recipients)
|
||||
|
||||
if(loc && !isturf(loc))
|
||||
var/atom/A = loc //Non-turf, let it handle the speech bubble
|
||||
A.speech_bubble("[A.bubble_icon][speech_bubble_test]", A, speech_bubble_recipients)
|
||||
else //Turf, leave speech bubbles to the mob
|
||||
speech_bubble("[bubble_icon][speech_bubble_test]", src, speech_bubble_recipients)
|
||||
|
||||
for(var/obj/O in listening_obj)
|
||||
spawn(0)
|
||||
@@ -462,10 +462,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(M.client)
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
|
||||
spawn(0)
|
||||
var/image/I = image('icons/mob/talk.dmi', src, "h[speech_bubble_test]", MOB_LAYER + 1)
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
flick_overlay(I, speech_bubble_recipients, 30)
|
||||
speech_bubble("[bubble_icon][speech_bubble_test]", src, speech_bubble_recipients)
|
||||
|
||||
if(watching.len)
|
||||
var/rendered = "<span class='game say'><span class='name'>[name]</span> [not_heard].</span>"
|
||||
@@ -474,7 +471,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list())
|
||||
var/image/I = image('icons/mob/talk.dmi', bubble_loc, bubble_state, MOB_LAYER + 1)
|
||||
/mob/living/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list())
|
||||
var/image/I = image('icons/mob/talk.dmi', bubble_loc, bubble_state, FLY_LAYER)
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
flick_overlay(I, bubble_recipients, 30)
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, bubble_recipients, 30)
|
||||
|
||||
@@ -253,7 +253,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
|
||||
to_chat(user, "<span class='warning'>You can't analyze non-robotic things!</span>")
|
||||
return
|
||||
|
||||
|
||||
|
||||
switch(scan_type)
|
||||
if("robot")
|
||||
var/BU = M.getFireLoss() > 50 ? "<b>[M.getFireLoss()]</b>" : M.getFireLoss()
|
||||
@@ -269,7 +269,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
|
||||
to_chat(user, "<span class='notice'>Localized Damage:</span>")
|
||||
if(!LAZYLEN(damaged) && !LAZYLEN(missing))
|
||||
to_chat(user, "<span class='notice'>\t Components are OK.</span>")
|
||||
else
|
||||
else
|
||||
if(LAZYLEN(damaged))
|
||||
for(var/datum/robot_component/org in damaged)
|
||||
user.show_message(text("<span class='notice'>\t []: [][] - [] - [] - []</span>", \
|
||||
@@ -282,7 +282,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
|
||||
if(LAZYLEN(missing))
|
||||
for(var/datum/robot_component/org in missing)
|
||||
user.show_message("<span class='warning'>\t [capitalize(org.name)]: MISSING</span>")
|
||||
|
||||
|
||||
if(H.emagged && prob(5))
|
||||
to_chat(user, "<span class='warning'>\t ERROR: INTERNAL SYSTEMS COMPROMISED</span>")
|
||||
|
||||
@@ -313,7 +313,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
|
||||
if(!organ_found)
|
||||
to_chat(user, "<span class='warning'>No prosthetics located.</span>")
|
||||
|
||||
if(H.isSynthetic())
|
||||
if(ismachineperson(H))
|
||||
to_chat(user, "<span class='notice'>Internal Fluid Level:[H.blood_volume]/[H.max_blood]</span>")
|
||||
if(H.bleed_rate)
|
||||
to_chat(user, "<span class='warning'>Warning:External component leak detected!</span>")
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
icon_state = "repairbot"
|
||||
maxHealth = 35
|
||||
health = 35
|
||||
bubble_icon = "machine"
|
||||
universal_speak = 0
|
||||
universal_understand = 1
|
||||
gender = NEUTER
|
||||
|
||||
@@ -9,6 +9,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
icon_state = "robot"
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
bubble_icon = "robot"
|
||||
universal_understand = 1
|
||||
deathgasp_on_death = TRUE
|
||||
|
||||
@@ -16,8 +17,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
var/custom_name = ""
|
||||
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
|
||||
|
||||
//Hud stuff
|
||||
|
||||
//Hud stuff
|
||||
var/obj/screen/inv1 = null
|
||||
var/obj/screen/inv2 = null
|
||||
var/obj/screen/inv3 = null
|
||||
@@ -27,7 +27,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
|
||||
var/obj/screen/robot_modules_background
|
||||
|
||||
//3 Modules can be activated at any one time.
|
||||
//3 Modules can be activated at any one time.
|
||||
var/obj/item/robot_module/module = null
|
||||
var/module_active = null
|
||||
var/module_state_1 = null
|
||||
@@ -57,6 +57,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
var/is_emaggable = TRUE
|
||||
var/eye_protection = 0
|
||||
var/ear_protection = 0
|
||||
var/damage_protection = 0
|
||||
var/emp_protection = FALSE
|
||||
var/xeno_disarm_chance = 85
|
||||
|
||||
var/list/force_modules = list()
|
||||
var/allow_rename = TRUE
|
||||
@@ -86,7 +89,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
var/tracking_entities = 0 //The number of known entities currently accessing the internal camera
|
||||
var/braintype = "Cyborg"
|
||||
var/base_icon = ""
|
||||
var/crisis = 0
|
||||
var/modules_break = TRUE
|
||||
|
||||
var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting.
|
||||
@@ -97,6 +99,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
|
||||
hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD)
|
||||
|
||||
var/default_cell_type = /obj/item/stock_parts/cell/high
|
||||
var/magpulse = 0
|
||||
var/ionpulse = 0 // Jetpack-like effect.
|
||||
var/ionpulse_on = 0 // Jetpack-like effect.
|
||||
@@ -132,7 +135,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
|
||||
init()
|
||||
|
||||
if(!scrambledcodes && !camera)
|
||||
if(!camera && (!scrambledcodes || designation == "ERT"))
|
||||
camera = new /obj/machinery/camera(src)
|
||||
camera.c_tag = real_name
|
||||
camera.network = list("SS13","Robots")
|
||||
@@ -144,7 +147,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
mmi.icon_state = "boris"
|
||||
|
||||
if(!cell) // Make sure a new cell gets created *before* executing initialize_components(). The cell component needs an existing cell for it to get set up properly
|
||||
cell = new /obj/item/stock_parts/cell/high(src)
|
||||
cell = new default_cell_type(src)
|
||||
|
||||
initialize_components()
|
||||
//if(!unfinished)
|
||||
@@ -288,12 +291,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
/mob/living/silicon/robot/proc/pick_module()
|
||||
if(module)
|
||||
return
|
||||
var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
|
||||
var/list/modules = list("Generalist", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
|
||||
if(islist(force_modules) && force_modules.len)
|
||||
modules = force_modules.Copy()
|
||||
if(GLOB.security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis)
|
||||
to_chat(src, "<span class='warning'>Crisis mode active. The combat module is now available.</span>")
|
||||
modules += "Combat"
|
||||
if(mmi != null && mmi.alien)
|
||||
modules = list("Hunter")
|
||||
modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules
|
||||
@@ -306,9 +306,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
return
|
||||
|
||||
switch(modtype)
|
||||
if("Standard")
|
||||
if("Generalist")
|
||||
module = new /obj/item/robot_module/standard(src)
|
||||
module.channels = list("Service" = 1)
|
||||
module.channels = list("Engineering" = 1, "Medical" = 1, "Security" = 1, "Service" = 1)
|
||||
module_sprites["Basic"] = "robot_old"
|
||||
module_sprites["Android"] = "droid"
|
||||
module_sprites["Default"] = "Standard"
|
||||
@@ -337,6 +337,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
module_sprites["Standard"] = "Standard-Mine"
|
||||
module_sprites["Noble-DIG"] = "Noble-DIG"
|
||||
module_sprites["Cricket"] = "Cricket-MINE"
|
||||
module_sprites["Lavaland"] = "lavaland"
|
||||
|
||||
if("Medical")
|
||||
module = new /obj/item/robot_module/medical(src)
|
||||
@@ -353,6 +354,17 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
status_flags &= ~CANPUSH
|
||||
|
||||
if("Security")
|
||||
if(!weapons_unlock)
|
||||
var/count_secborgs = 0
|
||||
for(var/mob/living/silicon/robot/R in GLOB.alive_mob_list)
|
||||
if(R && R.stat != DEAD && R.module && istype(R.module, /obj/item/robot_module/security))
|
||||
count_secborgs++
|
||||
var/max_secborgs = 2
|
||||
if(GLOB.security_level == SEC_LEVEL_GREEN)
|
||||
max_secborgs = 1
|
||||
if(count_secborgs >= max_secborgs)
|
||||
to_chat(src, "<span class='warning'>There are too many Security cyborgs active. Please choose another module.</span>")
|
||||
return
|
||||
module = new /obj/item/robot_module/security(src)
|
||||
module.channels = list("Security" = 1)
|
||||
module_sprites["Basic"] = "secborg"
|
||||
@@ -387,10 +399,16 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
module_sprites["Noble-CLN"] = "Noble-CLN"
|
||||
module_sprites["Cricket"] = "Cricket-JANI"
|
||||
|
||||
if("Combat")
|
||||
module = new /obj/item/robot_module/combat(src)
|
||||
if("Destroyer") // Rolling Borg
|
||||
module = new /obj/item/robot_module/destroyer(src)
|
||||
module.channels = list("Security" = 1)
|
||||
icon_state = "droidcombat"
|
||||
status_flags &= ~CANPUSH
|
||||
|
||||
if("Combat") // Gamma ERT
|
||||
module = new /obj/item/robot_module/combat(src)
|
||||
icon_state = "ertgamma"
|
||||
status_flags &= ~CANPUSH
|
||||
|
||||
if("Hunter")
|
||||
module = new /obj/item/robot_module/alien/hunter(src)
|
||||
@@ -442,6 +460,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
ionpulse = FALSE
|
||||
magpulse = FALSE
|
||||
add_language("Robot Talk", 1)
|
||||
if("lava" in weather_immunities) // Remove the lava-immunity effect given by a printable upgrade
|
||||
weather_immunities -= "lava"
|
||||
|
||||
status_flags |= CANPUSH
|
||||
|
||||
@@ -916,7 +936,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/update_icons()
|
||||
|
||||
overlays.Cut()
|
||||
if(stat != DEAD && !(paralysis || stunned || IsWeakened() || low_power_mode)) //Not dead, not stunned.
|
||||
if(custom_panel in custom_eye_names)
|
||||
@@ -925,36 +944,24 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
overlays += "eyes-[icon_state]"
|
||||
else
|
||||
overlays -= "eyes"
|
||||
|
||||
if(opened)
|
||||
var/panelprefix = "ov"
|
||||
if(custom_sprite) //Custom borgs also have custom panels, heh
|
||||
panelprefix = "[ckey]"
|
||||
|
||||
if(custom_panel in custom_panel_names) //For default borgs with different panels
|
||||
panelprefix = custom_panel
|
||||
|
||||
if(wiresexposed)
|
||||
overlays += "[panelprefix]-openpanel +w"
|
||||
else if(cell)
|
||||
overlays += "[panelprefix]-openpanel +c"
|
||||
else
|
||||
overlays += "[panelprefix]-openpanel -c"
|
||||
|
||||
var/combat = list("Combat")
|
||||
if(modtype in combat)
|
||||
if(base_icon == "")
|
||||
base_icon = icon_state
|
||||
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
|
||||
icon_state = "[base_icon]-roll"
|
||||
else
|
||||
icon_state = base_icon
|
||||
if(module)
|
||||
for(var/obj/item/borg/combat/shield/S in module.modules)
|
||||
if(activated(S))
|
||||
overlays += "[base_icon]-shield"
|
||||
borg_icons()
|
||||
update_fire()
|
||||
|
||||
/mob/living/silicon/robot/proc/borg_icons() // Exists so that robot/destroyer can override it
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/proc/installed_modules()
|
||||
if(weapon_lock)
|
||||
to_chat(src, "<span class='warning'>Weapon lock active, unable to use modules! Count:[weaponlock_time]</span>")
|
||||
@@ -1309,6 +1316,16 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
..()
|
||||
update_module_icon()
|
||||
|
||||
/mob/living/silicon/robot/emp_act(severity)
|
||||
if(emp_protection)
|
||||
return
|
||||
..()
|
||||
switch(severity)
|
||||
if(1)
|
||||
disable_component("comms", 160)
|
||||
if(2)
|
||||
disable_component("comms", 60)
|
||||
|
||||
/mob/living/silicon/robot/deathsquad
|
||||
base_icon = "nano_bloodhound"
|
||||
icon_state = "nano_bloodhound"
|
||||
@@ -1321,44 +1338,29 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
pdahide = 1
|
||||
eye_protection = 2 // Immunity to flashes and the visual part of flashbangs
|
||||
ear_protection = 1 // Immunity to the audio part of flashbangs
|
||||
damage_protection = 10 // Reduce all incoming damage by this number
|
||||
xeno_disarm_chance = 20
|
||||
allow_rename = FALSE
|
||||
modtype = "Commando"
|
||||
faction = list("nanotrasen")
|
||||
is_emaggable = FALSE
|
||||
|
||||
/mob/living/silicon/robot/deathsquad/New(loc)
|
||||
..()
|
||||
cell = new /obj/item/stock_parts/cell/hyper(src)
|
||||
default_cell_type = /obj/item/stock_parts/cell/bluespace
|
||||
|
||||
/mob/living/silicon/robot/deathsquad/init()
|
||||
laws = new /datum/ai_laws/deathsquad
|
||||
module = new /obj/item/robot_module/deathsquad(src)
|
||||
|
||||
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
|
||||
radio = new /obj/item/radio/borg/deathsquad(src)
|
||||
radio.recalculateChannels()
|
||||
|
||||
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
|
||||
|
||||
/mob/living/silicon/robot/combat
|
||||
base_icon = "droidcombat"
|
||||
icon_state = "droidcombat"
|
||||
modtype = "Combat"
|
||||
designation = "Combat"
|
||||
/mob/living/silicon/robot/deathsquad/bullet_act(var/obj/item/projectile/P)
|
||||
if(istype(P) && P.is_reflectable && P.starting)
|
||||
visible_message("<span class='danger'>The [P.name] gets reflected by [src]!</span>", "<span class='userdanger'>The [P.name] gets reflected by [src]!</span>")
|
||||
P.reflect_back(src)
|
||||
return -1
|
||||
return ..(P)
|
||||
|
||||
/mob/living/silicon/robot/combat/init()
|
||||
..()
|
||||
module = new /obj/item/robot_module/combat(src)
|
||||
module.channels = list("Security" = 1)
|
||||
//languages
|
||||
module.add_languages(src)
|
||||
//subsystems
|
||||
module.add_subsystems_and_actions(src)
|
||||
|
||||
status_flags &= ~CANPUSH
|
||||
|
||||
radio.config(module.channels)
|
||||
notify_ai(2)
|
||||
|
||||
/mob/living/silicon/robot/ert
|
||||
designation = "ERT"
|
||||
@@ -1366,11 +1368,12 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
scrambledcodes = 1
|
||||
req_one_access = list(ACCESS_CENT_SPECOPS)
|
||||
ionpulse = 1
|
||||
|
||||
force_modules = list("Engineering", "Medical", "Security")
|
||||
static_radio_channels = 1
|
||||
allow_rename = FALSE
|
||||
weapons_unlock = TRUE
|
||||
default_cell_type = /obj/item/stock_parts/cell/super
|
||||
var/eprefix = "Amber"
|
||||
|
||||
|
||||
/mob/living/silicon/robot/ert/init()
|
||||
@@ -1379,11 +1382,10 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
radio.recalculateChannels()
|
||||
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
|
||||
|
||||
/mob/living/silicon/robot/ert/New(loc, cyborg_unlock)
|
||||
/mob/living/silicon/robot/ert/New(loc)
|
||||
..(loc)
|
||||
cell = new /obj/item/stock_parts/cell/hyper(src)
|
||||
var/rnum = rand(1,1000)
|
||||
var/borgname = "ERT [rnum]"
|
||||
var/borgname = "[eprefix] ERT [rnum]"
|
||||
name = borgname
|
||||
custom_name = borgname
|
||||
real_name = name
|
||||
@@ -1392,22 +1394,63 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
mind.original = src
|
||||
mind.assigned_role = SPECIAL_ROLE_ERT
|
||||
mind.special_role = SPECIAL_ROLE_ERT
|
||||
if(cyborg_unlock)
|
||||
crisis = 1
|
||||
if(!(mind in SSticker.minds))
|
||||
SSticker.minds += mind
|
||||
SSticker.mode.ert += mind
|
||||
|
||||
/mob/living/silicon/robot/ert/gamma
|
||||
crisis = 1
|
||||
|
||||
/mob/living/silicon/robot/emp_act(severity)
|
||||
/mob/living/silicon/robot/ert/red
|
||||
eprefix = "Red"
|
||||
default_cell_type = /obj/item/stock_parts/cell/hyper
|
||||
|
||||
/mob/living/silicon/robot/ert/gamma
|
||||
default_cell_type = /obj/item/stock_parts/cell/bluespace
|
||||
force_modules = list("Combat", "Engineering", "Medical")
|
||||
damage_protection = 5 // Reduce all incoming damage by this number
|
||||
eprefix = "Gamma"
|
||||
magpulse = 1
|
||||
xeno_disarm_chance = 40
|
||||
|
||||
|
||||
/mob/living/silicon/robot/destroyer
|
||||
// admin-only borg, the seraph / special ops officer of borgs
|
||||
base_icon = "droidcombat"
|
||||
icon_state = "droidcombat"
|
||||
modtype = "Destroyer"
|
||||
designation = "Destroyer"
|
||||
lawupdate = 0
|
||||
scrambledcodes = 1
|
||||
req_one_access = list(ACCESS_CENT_SPECOPS)
|
||||
ionpulse = 1
|
||||
magpulse = 1
|
||||
pdahide = 1
|
||||
eye_protection = 2 // Immunity to flashes and the visual part of flashbangs
|
||||
ear_protection = 1 // Immunity to the audio part of flashbangs
|
||||
emp_protection = TRUE // Immunity to EMP, due to heavy shielding
|
||||
damage_protection = 20 // Reduce all incoming damage by this number. Very high in the case of /destroyer borgs, since it is an admin-only borg.
|
||||
xeno_disarm_chance = 10
|
||||
default_cell_type = /obj/item/stock_parts/cell/bluespace
|
||||
|
||||
/mob/living/silicon/robot/destroyer/init()
|
||||
..()
|
||||
switch(severity)
|
||||
if(1)
|
||||
disable_component("comms", 160)
|
||||
if(2)
|
||||
disable_component("comms", 60)
|
||||
module = new /obj/item/robot_module/destroyer(src)
|
||||
module.add_languages(src)
|
||||
module.add_subsystems_and_actions(src)
|
||||
status_flags &= ~CANPUSH
|
||||
if(radio)
|
||||
qdel(radio)
|
||||
radio = new /obj/item/radio/borg/ert/specops(src)
|
||||
radio.recalculateChannels()
|
||||
|
||||
/mob/living/silicon/robot/destroyer/borg_icons()
|
||||
if(base_icon == "")
|
||||
base_icon = icon_state
|
||||
if(module_active && istype(module_active,/obj/item/borg/destroyer/mobility))
|
||||
icon_state = "[base_icon]-roll"
|
||||
else
|
||||
icon_state = base_icon
|
||||
overlays += "[base_icon]-shield"
|
||||
|
||||
|
||||
/mob/living/silicon/robot/extinguish_light()
|
||||
update_headlamp(1, 150)
|
||||
|
||||
@@ -76,29 +76,6 @@
|
||||
if(!LAZYLEN(components))
|
||||
return
|
||||
|
||||
//Combat shielding absorbs a percentage of damage directly into the cell.
|
||||
var/obj/item/borg/combat/shield/shield
|
||||
if(module_state_1 && istype(module_state_1, /obj/item/borg/combat/shield))
|
||||
shield = module_state_1
|
||||
else if(module_state_2 && istype(module_state_2, /obj/item/borg/combat/shield))
|
||||
shield = module_state_2
|
||||
else if(module_state_3 && istype(module_state_3, /obj/item/borg/combat/shield))
|
||||
shield = module_state_3
|
||||
if(shield)
|
||||
//Shields absorb a certain percentage of damage based on their power setting.
|
||||
var/absorb_brute = brute * shield.shield_level
|
||||
var/absorb_burn = burn * shield.shield_level
|
||||
var/cost = (absorb_brute+absorb_burn) * 100
|
||||
|
||||
cell.charge -= cost
|
||||
if(cell.charge <= 0)
|
||||
cell.charge = 0
|
||||
to_chat(src, "<span class='warning'>Your shield has overloaded!</span>")
|
||||
else
|
||||
brute -= absorb_brute
|
||||
burn -= absorb_burn
|
||||
to_chat(src, "<span class='warning'>Your shield absorbs some of the impact!</span>")
|
||||
|
||||
var/datum/robot_component/armour/A = get_armour()
|
||||
if(A)
|
||||
A.take_damage(brute, burn, sharp, updating_health)
|
||||
@@ -127,32 +104,15 @@
|
||||
updatehealth("heal overall damage")
|
||||
|
||||
/mob/living/silicon/robot/take_overall_damage(brute = 0, burn = 0, updating_health = TRUE, used_weapon = null, sharp = 0)
|
||||
if(status_flags & GODMODE) return //godmode
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
|
||||
if(damage_protection)
|
||||
brute = clamp(brute - damage_protection, 0, brute)
|
||||
burn = clamp(burn - damage_protection, 0, burn)
|
||||
|
||||
var/list/datum/robot_component/parts = get_damageable_components()
|
||||
|
||||
//Combat shielding absorbs a percentage of damage directly into the cell.
|
||||
var/obj/item/borg/combat/shield/shield
|
||||
if(module_state_1 && istype(module_state_1, /obj/item/borg/combat/shield))
|
||||
shield = module_state_1
|
||||
else if(module_state_2 && istype(module_state_2, /obj/item/borg/combat/shield))
|
||||
shield = module_state_2
|
||||
else if(module_state_3 && istype(module_state_3, /obj/item/borg/combat/shield))
|
||||
shield = module_state_3
|
||||
if(shield)
|
||||
//Shields absorb a certain percentage of damage based on their power setting.
|
||||
var/absorb_brute = brute * shield.shield_level
|
||||
var/absorb_burn = burn * shield.shield_level
|
||||
var/cost = (absorb_brute+absorb_burn) * 100
|
||||
|
||||
cell.charge -= cost
|
||||
if(cell.charge <= 0)
|
||||
cell.charge = 0
|
||||
to_chat(src, "<span class='warning'>Your shield has overloaded!</span>")
|
||||
else
|
||||
brute -= absorb_brute
|
||||
burn -= absorb_burn
|
||||
to_chat(src, "<span class='warning'>Your shield absorbs some of the impact!</span>")
|
||||
|
||||
var/datum/robot_component/armour/A = get_armour()
|
||||
if(A)
|
||||
A.take_damage(brute, burn, sharp)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
if(M.a_intent == INTENT_DISARM)
|
||||
if(!lying)
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
if(prob(85))
|
||||
if(prob(xeno_disarm_chance))
|
||||
Stun(7)
|
||||
step(src, get_dir(M,src))
|
||||
spawn(5)
|
||||
|
||||
@@ -73,24 +73,7 @@
|
||||
/obj/item/borg
|
||||
var/powerneeded // Percentage of power remaining required to run item
|
||||
|
||||
/obj/item/borg/combat/shield
|
||||
name = "personal shielding"
|
||||
desc = "A powerful experimental module that turns aside or absorbs incoming attacks at the cost of charge."
|
||||
icon = 'icons/obj/decals.dmi'
|
||||
icon_state = "shock"
|
||||
powerneeded = 25
|
||||
var/shield_level = 0.5 //Percentage of damage absorbed by the shield.
|
||||
|
||||
/obj/item/borg/combat/shield/verb/set_shield_level()
|
||||
set name = "Set shield level"
|
||||
set category = "Object"
|
||||
set src in range(0)
|
||||
|
||||
var/N = input("How much damage should the shield absorb?") in list("5","10","25","50","75","100")
|
||||
if(N)
|
||||
shield_level = text2num(N)/100
|
||||
|
||||
/obj/item/borg/combat/mobility
|
||||
/obj/item/borg/destroyer/mobility
|
||||
name = "mobility module"
|
||||
desc = "By retracting limbs and tucking in its head, a combat android can roll at high speeds."
|
||||
icon = 'icons/obj/decals.dmi'
|
||||
|
||||
@@ -118,20 +118,48 @@
|
||||
return
|
||||
|
||||
/obj/item/robot_module/standard
|
||||
name = "standard robot module"
|
||||
// if station is fine, assist with constructing station goal room, cleaning, and repairing cables chewed by rats
|
||||
// if medical crisis, assist by providing basic healthcare, retrieving corpses, and monitoring crew lifesigns
|
||||
// if eng crisis, assist by helping repair hull breaches
|
||||
// if sec crisis, assist by opening doors for sec and providing backup zipties on patrols
|
||||
name = "generalist robot module"
|
||||
module_type = "Standard"
|
||||
subsystems = list(/mob/living/silicon/proc/subsystem_power_monitor, /mob/living/silicon/proc/subsystem_crew_monitor)
|
||||
stacktypes = list(
|
||||
/obj/item/stack/sheet/metal/cyborg = 50,
|
||||
/obj/item/stack/cable_coil/cyborg = 50,
|
||||
/obj/item/stack/rods/cyborg = 60,
|
||||
/obj/item/stack/tile/plasteel = 20
|
||||
)
|
||||
|
||||
/obj/item/robot_module/standard/New()
|
||||
..()
|
||||
modules += new /obj/item/melee/baton/loaded(src)
|
||||
modules += new /obj/item/extinguisher(src)
|
||||
modules += new /obj/item/wrench/cyborg(src)
|
||||
// sec
|
||||
modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
|
||||
// janitorial
|
||||
modules += new /obj/item/soap/nanotrasen(src)
|
||||
modules += new /obj/item/lightreplacer/cyborg(src)
|
||||
// eng
|
||||
modules += new /obj/item/crowbar/cyborg(src)
|
||||
modules += new /obj/item/wrench/cyborg(src)
|
||||
modules += new /obj/item/extinguisher(src) // for firefighting, and propulsion in space
|
||||
modules += new /obj/item/weldingtool/largetank/cyborg(src)
|
||||
// mining
|
||||
modules += new /obj/item/pickaxe(src)
|
||||
modules += new /obj/item/t_scanner/adv_mining_scanner(src)
|
||||
modules += new /obj/item/storage/bag/ore/cyborg(src)
|
||||
// med
|
||||
modules += new /obj/item/healthanalyzer(src)
|
||||
modules += new /obj/item/reagent_containers/borghypo/basic(src)
|
||||
modules += new /obj/item/roller_holder(src) // for taking the injured to medbay without worsening their injuries or leaving a blood trail the whole way
|
||||
emag = new /obj/item/melee/energy/sword/cyborg(src)
|
||||
|
||||
for(var/G in stacktypes)
|
||||
var/obj/item/stack/sheet/M = new G(src)
|
||||
M.amount = stacktypes[G]
|
||||
modules += M
|
||||
fix_modules()
|
||||
|
||||
|
||||
/obj/item/robot_module/medical
|
||||
name = "medical robot module"
|
||||
module_type = "Medical"
|
||||
@@ -259,6 +287,7 @@
|
||||
modules += new /obj/item/mop/advanced/cyborg(src)
|
||||
modules += new /obj/item/lightreplacer/cyborg(src)
|
||||
modules += new /obj/item/holosign_creator(src)
|
||||
modules += new /obj/item/extinguisher/mini(src)
|
||||
emag = new /obj/item/reagent_containers/spray(src)
|
||||
|
||||
emag.reagents.add_reagent("lube", 250)
|
||||
@@ -483,25 +512,44 @@
|
||||
|
||||
fix_modules()
|
||||
|
||||
/obj/item/robot_module/combat
|
||||
name = "combat robot module"
|
||||
/obj/item/robot_module/destroyer
|
||||
name = "destroyer robot module"
|
||||
module_type = "Malf"
|
||||
module_actions = list(
|
||||
/datum/action/innate/robot_sight/thermal,
|
||||
)
|
||||
|
||||
/obj/item/robot_module/destroyer/New()
|
||||
..()
|
||||
|
||||
modules += new /obj/item/gun/energy/immolator/multi/cyborg(src) // See comments on /robot_module/combat below
|
||||
modules += new /obj/item/melee/baton/loaded(src) // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats
|
||||
modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
|
||||
modules += new /obj/item/pickaxe/drill/jackhammer(src) // for breaking walls to execute flanking moves
|
||||
modules += new /obj/item/borg/destroyer/mobility(src)
|
||||
emag = null
|
||||
fix_modules()
|
||||
|
||||
|
||||
/obj/item/robot_module/combat
|
||||
name = "combat robot module"
|
||||
module_type = "Malf"
|
||||
module_actions = list()
|
||||
|
||||
/obj/item/robot_module/combat/New()
|
||||
..()
|
||||
modules += new /obj/item/gun/energy/immolator/multi/cyborg(src) // primary weapon, strong at close range (ie: against blob/terror/xeno), but consumes a lot of energy per shot.
|
||||
// Borg gets 40 shots of this weapon. Gamma Sec ERT gets 10.
|
||||
// So, borg has way more burst damage, but also takes way longer to recharge / get back in the fight once depleted. Has to find a borg recharger and sit in it for ages.
|
||||
// Organic gamma sec ERT carries alternate weapons, including a box of flashbangs, and can load up on a huge number of guns from science. Borg cannot do either.
|
||||
// Overall, gamma borg has higher skill floor but lower skill ceiling.
|
||||
modules += new /obj/item/melee/baton/loaded(src) // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats
|
||||
modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
|
||||
modules += new /obj/item/gun/energy/gun/cyborg(src)
|
||||
modules += new /obj/item/pickaxe/drill/jackhammer(src)
|
||||
modules += new /obj/item/borg/combat/shield(src)
|
||||
modules += new /obj/item/borg/combat/mobility(src)
|
||||
modules += new /obj/item/wrench/cyborg(src)
|
||||
emag = new /obj/item/gun/energy/lasercannon/cyborg(src)
|
||||
|
||||
modules += new /obj/item/pickaxe/drill/jackhammer(src) // for breaking walls to execute flanking moves
|
||||
emag = null
|
||||
fix_modules()
|
||||
|
||||
|
||||
/obj/item/robot_module/alien/hunter
|
||||
name = "alien hunter module"
|
||||
module_type = "Standard"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/mob/living/silicon/robot/movement_delay()
|
||||
. = ..()
|
||||
. += speed
|
||||
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
|
||||
if(module_active && istype(module_active,/obj/item/borg/destroyer/mobility))
|
||||
. -= 3
|
||||
. += config.robot_delay
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
scrambledcodes = 1
|
||||
pdahide = 1
|
||||
faction = list("syndicate")
|
||||
bubble_icon = "syndibot"
|
||||
designation = "Syndicate Assault"
|
||||
modtype = "Syndicate"
|
||||
req_access = list(ACCESS_SYNDICATE)
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
gender = NEUTER
|
||||
robot_talk_understand = 1
|
||||
voice_name = "synthesized voice"
|
||||
bubble_icon = "machine"
|
||||
has_unlimited_silicon_privilege = 1
|
||||
weather_immunities = list("ash")
|
||||
var/syndicate = 0
|
||||
var/const/MAIN_CHANNEL = "Main Frequency"
|
||||
var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
var/register_alarms = 1
|
||||
var/datum/nano_module/alarm_monitor/all/alarm_monitor
|
||||
var/datum/nano_module/atmos_control/atmos_control
|
||||
var/datum/nano_module/crew_monitor/crew_monitor
|
||||
var/datum/tgui_module/crew_monitor/crew_monitor
|
||||
var/datum/nano_module/law_manager/law_manager
|
||||
var/datum/nano_module/power_monitor/silicon/power_monitor
|
||||
|
||||
@@ -71,8 +71,7 @@
|
||||
/mob/living/silicon/proc/subsystem_crew_monitor()
|
||||
set category = "Subsystems"
|
||||
set name = "Crew Monitor"
|
||||
|
||||
crew_monitor.ui_interact(usr, state = GLOB.self_state)
|
||||
crew_monitor.tgui_interact(usr, state = GLOB.tgui_self_state)
|
||||
|
||||
/****************
|
||||
* Law Manager *
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
speak_emote = list("states")
|
||||
friendly = "boops"
|
||||
|
||||
bubble_icon = "machine"
|
||||
faction = list("neutral", "silicon")
|
||||
|
||||
var/obj/machinery/bot_core/bot_core = null
|
||||
@@ -63,6 +63,7 @@
|
||||
var/new_destination // pending new destination (waiting for beacon response)
|
||||
var/destination // destination description tag
|
||||
var/next_destination // the next destination in the patrol route
|
||||
var/ignorelistcleanuptimer = 1 // This ticks up every automated action, at 300 we clean the ignore list
|
||||
var/robot_arm = /obj/item/robot_parts/r_arm
|
||||
|
||||
var/blockcount = 0 //number of times retried a blocked path
|
||||
@@ -254,6 +255,15 @@
|
||||
/mob/living/simple_animal/bot/handle_automated_action()
|
||||
diag_hud_set_botmode()
|
||||
|
||||
if(ignorelistcleanuptimer % 300 == 0) // Every 300 actions, clean up the ignore list from old junk
|
||||
for(var/uid in ignore_list)
|
||||
var/atom/referredatom = locateUID(uid)
|
||||
if(!referredatom || QDELETED(referredatom))
|
||||
ignore_list -= uid
|
||||
ignorelistcleanuptimer = 1
|
||||
else
|
||||
ignorelistcleanuptimer++
|
||||
|
||||
if(!on)
|
||||
return
|
||||
|
||||
@@ -439,14 +449,15 @@ Example usage: patient = scan(/mob/living/carbon/human, oldpatient, 1)
|
||||
The proc would return a human next to the bot to be set to the patient var.
|
||||
Pass the desired type path itself, declaring a temporary var beforehand is not required.
|
||||
*/
|
||||
/mob/living/simple_animal/bot/proc/scan(scan_type, old_target, scan_range = DEFAULT_SCAN_RANGE)
|
||||
/mob/living/simple_animal/bot/proc/scan(atom/scan_type, atom/old_target, scan_range = DEFAULT_SCAN_RANGE)
|
||||
var/final_result
|
||||
for(var/scan in shuffle(view(scan_range, src))) //Search for something in range!
|
||||
if(!istype(scan, scan_type)) //Check that the thing we found is the type we want!
|
||||
var/atom/A = scan
|
||||
if(!istype(A, scan_type)) //Check that the thing we found is the type we want!
|
||||
continue //If not, keep searching!
|
||||
if( (scan in ignore_list) || (scan == old_target) ) //Filter for blacklisted elements, usually unreachable or previously processed oness
|
||||
if((A.UID() in ignore_list) || (A == old_target) ) //Filter for blacklisted elements, usually unreachable or previously processed oness
|
||||
continue
|
||||
var/scan_result = process_scan(scan) //Some bots may require additional processing when a result is selected.
|
||||
var/scan_result = process_scan(A) //Some bots may require additional processing when a result is selected.
|
||||
if(scan_result)
|
||||
final_result = scan_result
|
||||
else
|
||||
@@ -454,17 +465,16 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r
|
||||
return final_result
|
||||
|
||||
//When the scan finds a target, run bot specific processing to select it for the next step. Empty by default.
|
||||
/mob/living/simple_animal/bot/proc/process_scan(scan_target)
|
||||
/mob/living/simple_animal/bot/proc/process_scan(atom/scan_target)
|
||||
return scan_target
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/proc/add_to_ignore(subject)
|
||||
/mob/living/simple_animal/bot/proc/add_to_ignore(atom/A)
|
||||
if(ignore_list.len < 50) //This will help keep track of them, so the bot is always trying to reach a blocked spot.
|
||||
ignore_list |= subject
|
||||
else if(ignore_list.len >= subject) //If the list is full, insert newest, delete oldest.
|
||||
ignore_list -= ignore_list[1]
|
||||
ignore_list |= subject
|
||||
|
||||
ignore_list |= A.UID()
|
||||
else //If the list is full, insert newest, delete oldest.
|
||||
ignore_list.Cut(1, 2)
|
||||
ignore_list |= A.UID()
|
||||
/*
|
||||
Movement proc for stepping a bot through a path generated through A-star.
|
||||
Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/bot_reset()
|
||||
..()
|
||||
ignore_list = list() //Allows the bot to clean targets it previously ignored due to being unreachable.
|
||||
ignore_list.Cut() //Allows the bot to clean targets it previously ignored due to being unreachable.
|
||||
target = null
|
||||
oldloc = null
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
audible_message("[src] makes an excited beeping booping sound!")
|
||||
|
||||
if(!target) //Search for cleanables it can see.
|
||||
target = scan(/obj/effect/decal/cleanable/)
|
||||
target = scan(/obj/effect/decal/cleanable)
|
||||
|
||||
if(!target && auto_patrol) //Search for cleanables it can see.
|
||||
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
..()
|
||||
target = null
|
||||
oldloc = null
|
||||
ignore_list = list()
|
||||
ignore_list.Cut()
|
||||
nagged = 0
|
||||
anchored = FALSE
|
||||
update_icon()
|
||||
@@ -270,7 +270,7 @@
|
||||
return 1
|
||||
|
||||
//Floorbots, having several functions, need sort out special conditions here.
|
||||
/mob/living/simple_animal/bot/floorbot/process_scan(scan_target)
|
||||
/mob/living/simple_animal/bot/floorbot/process_scan(atom/scan_target)
|
||||
var/result
|
||||
var/turf/simulated/floor/F
|
||||
switch(process_type)
|
||||
|
||||
@@ -323,13 +323,13 @@
|
||||
/mob/living/simple_animal/bot/mulebot/proc/buzz(type)
|
||||
switch(type)
|
||||
if(SIGH)
|
||||
audible_message("[src] makes a sighing buzz.", "<span class='emote'>You hear an electronic buzzing sound.</span>")
|
||||
audible_message("[src] makes a sighing buzz.")
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
if(ANNOYED)
|
||||
audible_message("[src] makes an annoyed buzzing sound.", "<span class='emote'>You hear an electronic buzzing sound.</span>")
|
||||
audible_message("[src] makes an annoyed buzzing sound.")
|
||||
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
if(DELIGHT)
|
||||
audible_message("[src] makes a delighted ping!", "<span class='emote'>You hear a ping.</span>")
|
||||
audible_message("[src] makes a delighted ping!")
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
|
||||
|
||||
@@ -601,7 +601,7 @@
|
||||
/mob/living/simple_animal/bot/mulebot/proc/at_target()
|
||||
if(!reached_target)
|
||||
radio_channel = "Supply" //Supply channel
|
||||
audible_message("[src] makes a chiming sound!", "<span class='emote'>You hear a chime.</span>")
|
||||
audible_message("[src] makes a chiming sound!")
|
||||
playsound(loc, 'sound/machines/chime.ogg', 50, 0)
|
||||
reached_target = 1
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
melee_damage_upper = 25
|
||||
attacktext = "slashes"
|
||||
speak_emote = list("hisses")
|
||||
bubble_icon = "alien"
|
||||
a_intent = INTENT_HARM
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
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)
|
||||
@@ -127,6 +128,7 @@
|
||||
icon_state = "queen_s"
|
||||
icon_living = "queen_s"
|
||||
icon_dead = "queen_dead"
|
||||
bubble_icon = "alienroyal"
|
||||
move_to_delay = 4
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
var/list/human_overlays = list()
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab/Life(seconds, times_fired)
|
||||
if(..())
|
||||
if(..() && !stat)
|
||||
if(!is_zombie && isturf(src.loc))
|
||||
for(var/mob/living/carbon/human/H in oview(src, 1)) //Only for corpse right next to/on same tile
|
||||
if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD))
|
||||
@@ -35,7 +35,7 @@
|
||||
if(cycles >= 4)
|
||||
for(var/mob/living/simple_animal/K in oview(src, 1)) //Only for corpse right next to/on same tile
|
||||
if(K.stat == DEAD || (!K.check_death_method() && K.health <= HEALTH_THRESHOLD_DEAD))
|
||||
visible_message("<span class='danger'>[src] consumes [target] whole!</span>")
|
||||
visible_message("<span class='danger'>[src] consumes [K] whole!</span>")
|
||||
if(health < maxHealth)
|
||||
health += 10
|
||||
qdel(K)
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop()
|
||||
var/mob/living/carbon/human/monkey/M = new(owner)
|
||||
owner.stomach_contents += M
|
||||
LAZYADD(owner.stomach_contents, M)
|
||||
|
||||
for(var/obj/item/organ/internal/I in src)
|
||||
I.insert(M, 1)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
loot = list(/obj/effect/decal/cleanable/blood/gibs/robot)
|
||||
deathmessage = "blows apart!"
|
||||
bubble_icon = "machine"
|
||||
del_on_death = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/range
|
||||
|
||||
@@ -363,6 +363,7 @@
|
||||
minbodytemp = 0
|
||||
mob_size = MOB_SIZE_TINY
|
||||
flying = 1
|
||||
bubble_icon = "syndibot"
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
del_on_death = 1
|
||||
deathmessage = "is smashed into pieces!"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
response_harm = "stomps on"
|
||||
emote_see = list("jiggles", "bounces in place")
|
||||
speak_emote = list("blorbles")
|
||||
bubble_icon = "slime"
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/mob/Logout()
|
||||
SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs
|
||||
SStgui.on_logout(src) // Cleanup any TGUIs the user has open
|
||||
unset_machine()
|
||||
GLOB.player_list -= src
|
||||
log_access_out(src)
|
||||
|
||||
+31
-7
@@ -20,8 +20,8 @@
|
||||
AA.viewers -= src
|
||||
viewing_alternate_appearances = null
|
||||
logs.Cut()
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL
|
||||
LAssailant = null
|
||||
return ..()
|
||||
|
||||
/mob/Initialize()
|
||||
GLOB.mob_list += src
|
||||
@@ -127,14 +127,12 @@
|
||||
// self_message (optional) is what the src mob hears.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
/mob/audible_message(var/message, var/deaf_message, var/hearing_distance, var/self_message)
|
||||
/mob/audible_message(message, deaf_message, hearing_distance)
|
||||
var/range = 7
|
||||
if(hearing_distance)
|
||||
range = hearing_distance
|
||||
var/msg = message
|
||||
for(var/mob/M in get_mobs_in_view(range, src))
|
||||
if(self_message && M == src)
|
||||
msg = self_message
|
||||
M.show_message(msg, 2, deaf_message, 1)
|
||||
|
||||
// based on say code
|
||||
@@ -156,12 +154,12 @@
|
||||
// message is the message output to anyone who can hear.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance)
|
||||
/atom/proc/audible_message(message, deaf_message, hearing_distance)
|
||||
var/range = 7
|
||||
if(hearing_distance)
|
||||
range = hearing_distance
|
||||
for(var/mob/M in get_mobs_in_view(range, src))
|
||||
M.show_message( message, 2, deaf_message, 1)
|
||||
M.show_message(message, 2, deaf_message, 1)
|
||||
|
||||
/mob/proc/findname(msg)
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
@@ -1390,3 +1388,29 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
///Force set the mob nutrition
|
||||
/mob/proc/set_nutrition(change)
|
||||
nutrition = max(0, change)
|
||||
|
||||
/mob/clean_blood(clean_hands = TRUE, clean_mask = TRUE, clean_feet = TRUE)
|
||||
. = ..()
|
||||
if(bloody_hands && clean_hands)
|
||||
bloody_hands = 0
|
||||
update_inv_gloves()
|
||||
if(l_hand)
|
||||
if(l_hand.clean_blood())
|
||||
update_inv_l_hand()
|
||||
if(r_hand)
|
||||
if(r_hand.clean_blood())
|
||||
update_inv_r_hand()
|
||||
if(back)
|
||||
if(back.clean_blood())
|
||||
update_inv_back()
|
||||
if(wear_mask && clean_mask)
|
||||
if(wear_mask.clean_blood())
|
||||
update_inv_wear_mask()
|
||||
if(clean_feet)
|
||||
feet_blood_color = null
|
||||
qdel(feet_blood_DNA)
|
||||
bloody_feet = list(BLOOD_STATE_HUMAN = 0, BLOOD_STATE_XENO = 0, BLOOD_STATE_NOT_BLOODY = 0)
|
||||
blood_state = BLOOD_STATE_NOT_BLOODY
|
||||
update_inv_shoes()
|
||||
update_icons() //apply the now updated overlays to the mob
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
var/use_me = 1 //Allows all mobs to use the me verb by default, will have to manually specify they cannot
|
||||
var/damageoverlaytemp = 0
|
||||
var/computer_id = null
|
||||
var/lastattacker = null
|
||||
var/lastattacked = null
|
||||
var/lastattacker = null // real name of the person doing the attacking
|
||||
var/lastattackerckey = null // their ckey
|
||||
var/list/attack_log_old = list( )
|
||||
var/list/debug_log = null
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
var/med_record = ""
|
||||
var/sec_record = ""
|
||||
var/gen_record = ""
|
||||
var/bhunger = 0 //Carbon
|
||||
var/lying = 0
|
||||
var/lying_prev = 0
|
||||
var/lastpuke = 0
|
||||
@@ -61,8 +60,7 @@
|
||||
var/emote_type = 1 // Define emote default type, 1 for seen emotes, 2 for heard emotes
|
||||
var/name_archive //For admin things like possession
|
||||
|
||||
var/timeofdeath = 0.0//Living
|
||||
|
||||
var/timeofdeath = 0 //Living
|
||||
|
||||
var/bodytemperature = 310.055 //98.7 F
|
||||
var/flying = 0
|
||||
@@ -71,22 +69,22 @@
|
||||
var/hunger_drain = HUNGER_FACTOR // how quickly the mob gets hungry; largely utilized by species.
|
||||
|
||||
var/overeatduration = 0 // How long this guy is overeating //Carbon
|
||||
var/intent = null//Living
|
||||
var/intent = null //Living
|
||||
var/shakecamera = 0
|
||||
var/a_intent = INTENT_HELP//Living
|
||||
var/m_intent = MOVE_INTENT_RUN//Living
|
||||
var/a_intent = INTENT_HELP //Living
|
||||
var/m_intent = MOVE_INTENT_RUN //Living
|
||||
var/lastKnownIP = null
|
||||
/// movable atoms buckled to this mob
|
||||
var/atom/movable/buckled = null//Living
|
||||
var/atom/movable/buckled = null //Living
|
||||
/// movable atom we are buckled to
|
||||
var/atom/movable/buckling
|
||||
|
||||
var/obj/item/l_hand = null//Living
|
||||
var/obj/item/r_hand = null//Living
|
||||
var/obj/item/back = null//Human/Monkey
|
||||
var/obj/item/tank/internal = null//Human/Monkey
|
||||
var/obj/item/storage/s_active = null//Carbon
|
||||
var/obj/item/clothing/mask/wear_mask = null//Carbon
|
||||
var/obj/item/l_hand = null //Living
|
||||
var/obj/item/r_hand = null //Living
|
||||
var/obj/item/back = null //Human
|
||||
var/obj/item/tank/internal = null //Human
|
||||
var/obj/item/storage/s_active = null //Carbon
|
||||
var/obj/item/clothing/mask/wear_mask = null //Carbon
|
||||
|
||||
var/datum/hud/hud_used = null
|
||||
|
||||
@@ -95,7 +93,6 @@
|
||||
var/research_scanner = 0 //For research scanner equipped mobs. Enable to show research data when examining.
|
||||
|
||||
var/list/grabbed_by = list()
|
||||
var/list/requests = list()
|
||||
var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
|
||||
var/list/mapobjs = list()
|
||||
|
||||
@@ -103,9 +100,9 @@
|
||||
|
||||
var/emote_cd = 0 // Used to supress emote spamming. 1 if on CD, 2 if disabled by admin (manually set), else 0
|
||||
|
||||
var/job = null//Living
|
||||
var/job = null //Living
|
||||
|
||||
var/datum/dna/dna = null//Carbon
|
||||
var/datum/dna/dna = null //Carbon
|
||||
var/radiation = 0 //Carbon
|
||||
|
||||
var/list/mutations = list() //Carbon -- Doohl
|
||||
@@ -179,8 +176,6 @@
|
||||
var/turf/listed_turf = null //the current turf being examined in the stat panel
|
||||
var/list/shouldnt_see = list() //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
|
||||
|
||||
var/kills = 0
|
||||
|
||||
var/stance_damage = 0 //Whether this mob's ability to stand has been affected
|
||||
|
||||
var/list/active_genes = list()
|
||||
|
||||
@@ -408,7 +408,7 @@
|
||||
add_attack_logs(attacker, affecting, "Devoured")
|
||||
|
||||
affecting.forceMove(user)
|
||||
attacker.stomach_contents.Add(affecting)
|
||||
LAZYADD(attacker.stomach_contents, affecting)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grab/proc/checkvalid(var/mob/attacker, var/mob/prey) //does all the checking for the attack proc to see if a mob can eat another with the grab
|
||||
|
||||
@@ -12,14 +12,6 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/proc/isSynthetic()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/isSynthetic()
|
||||
if(ismachine(src))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/proc/get_screen_colour()
|
||||
|
||||
/mob/proc/update_client_colour(var/time = 10) //Update the mob's client.color with an animation the specified time in length.
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
|
||||
return get_turf(src)
|
||||
|
||||
/mob/proc/say_test(var/text)
|
||||
/proc/say_test(text)
|
||||
var/ending = copytext(text, length(text))
|
||||
if(ending == "?")
|
||||
return "1"
|
||||
|
||||
@@ -5,31 +5,32 @@ mob/var/typing
|
||||
mob/var/last_typed
|
||||
mob/var/last_typed_time
|
||||
|
||||
GLOBAL_DATUM(typing_indicator, /image)
|
||||
GLOBAL_LIST_EMPTY(typing_indicator)
|
||||
|
||||
/mob/proc/set_typing_indicator(var/state)
|
||||
/mob/proc/set_typing_indicator(state)
|
||||
|
||||
if(!GLOB.typing_indicator)
|
||||
GLOB.typing_indicator = image('icons/mob/talk.dmi', null, "typing", MOB_LAYER + 1)
|
||||
GLOB.typing_indicator.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
if(!GLOB.typing_indicator[bubble_icon])
|
||||
GLOB.typing_indicator[bubble_icon] = image('icons/mob/talk.dmi', null, "[bubble_icon]typing", FLY_LAYER)
|
||||
var/image/I = GLOB.typing_indicator[bubble_icon]
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if((MUTE in H.mutations) || H.silent)
|
||||
overlays -= GLOB.typing_indicator
|
||||
overlays -= GLOB.typing_indicator[bubble_icon]
|
||||
return
|
||||
|
||||
if(client)
|
||||
if((client.prefs.toggles & SHOW_TYPING) || stat != CONSCIOUS || is_muzzled())
|
||||
overlays -= GLOB.typing_indicator
|
||||
overlays -= GLOB.typing_indicator[bubble_icon]
|
||||
else
|
||||
if(state)
|
||||
if(!typing)
|
||||
overlays += GLOB.typing_indicator
|
||||
overlays += GLOB.typing_indicator[bubble_icon]
|
||||
typing = 1
|
||||
else
|
||||
if(typing)
|
||||
overlays -= GLOB.typing_indicator
|
||||
overlays -= GLOB.typing_indicator[bubble_icon]
|
||||
typing = 0
|
||||
return state
|
||||
|
||||
|
||||
Reference in New Issue
Block a user