Merge branch 'master' into upstream-merge-29953
This commit is contained in:
@@ -30,8 +30,8 @@
|
||||
// literally only an option for carbons though
|
||||
to_chat(C, "<span class='warning'>You may not hold items while blood crawling!</span>")
|
||||
return 0
|
||||
var/obj/item/weapon/bloodcrawl/B1 = new(C)
|
||||
var/obj/item/weapon/bloodcrawl/B2 = new(C)
|
||||
var/obj/item/bloodcrawl/B1 = new(C)
|
||||
var/obj/item/bloodcrawl/B2 = new(C)
|
||||
B1.icon_state = "bloodhand_left"
|
||||
B2.icon_state = "bloodhand_right"
|
||||
C.put_in_hands(B1)
|
||||
@@ -134,11 +134,11 @@
|
||||
/mob/living/proc/bloodcrawl_swallow(var/mob/living/victim)
|
||||
qdel(victim)
|
||||
|
||||
/obj/item/weapon/bloodcrawl
|
||||
/obj/item/bloodcrawl
|
||||
name = "blood crawl"
|
||||
desc = "You are unable to hold anything while in this form."
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
flags = NODROP|ABSTRACT
|
||||
flags_1 = NODROP_1|ABSTRACT_1
|
||||
|
||||
/mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B)
|
||||
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
|
||||
@@ -166,8 +166,8 @@
|
||||
exit_blood_effect(B)
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
for(var/obj/item/weapon/bloodcrawl/BC in C)
|
||||
BC.flags = null
|
||||
for(var/obj/item/bloodcrawl/BC in C)
|
||||
BC.flags_1 = null
|
||||
qdel(BC)
|
||||
qdel(src.holder)
|
||||
src.holder = null
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
if(user.zone_selected != "head")
|
||||
return ..()
|
||||
|
||||
if((C.head && (C.head.flags_cover & HEADCOVERSEYES)) || (C.wear_mask && (C.wear_mask.flags_cover & MASKCOVERSEYES)) || (C.glasses && (C.glasses.flags & GLASSESCOVERSEYES)))
|
||||
if((C.head && (C.head.flags_cover & HEADCOVERSEYES)) || (C.wear_mask && (C.wear_mask.flags_cover & MASKCOVERSEYES)) || (C.glasses && (C.glasses.flags_1 & GLASSESCOVERSEYES)))
|
||||
to_chat(user, "<span class='warning'>You're going to need to remove their head cover first!</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ GLOBAL_VAR(posibrain_notify_cooldown)
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/ping_ghosts(msg, newlymade)
|
||||
if(newlymade || GLOB.posibrain_notify_cooldown <= world.time)
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/effects/ghost2.ogg':null, enter_link = "<a href=?src=\ref[src];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE)
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/misc/server-ready.ogg':null, enter_link = "<a href=?src=\ref[src];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE)
|
||||
if(!newlymade)
|
||||
GLOB.posibrain_notify_cooldown = world.time + askDelay
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
verb_say = "hisses"
|
||||
initial_language_holder = /datum/language_holder/alien
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
|
||||
var/nightvision = 1
|
||||
|
||||
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/has_fine_manipulation = 0
|
||||
var/move_delay_add = 0 // movement delay to add
|
||||
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
/datum/emote/living/alien/roar
|
||||
key = "roar"
|
||||
key_third_person = "roars"
|
||||
message_alien = "roars"
|
||||
message_larva = "softly roars"
|
||||
message_alien = "roars."
|
||||
message_larva = "softly roars."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/living/alien/roar/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
if(. && isalienadult(user))
|
||||
playsound(user.loc, 'sound/voice/hiss5.ogg', 40, 1, 1)
|
||||
playsound(user.loc, 'sound/voice/hiss5.ogg', 40, 1, 1)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "alien"
|
||||
icon_state = "alien"
|
||||
pass_flags = PASSTABLE
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
limb_destroyer = 1
|
||||
var/obj/item/r_store = null
|
||||
@@ -42,7 +42,7 @@
|
||||
<HR>"}
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a>"
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags_1 & ABSTRACT_1)) ? I : "<font color=grey>Empty</font>"]</a>"
|
||||
dat += "<BR><A href='?src=\ref[src];pouches=1'>Empty Pouches</A>"
|
||||
|
||||
if(handcuffed)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
layer = LARGE_MOB_LAYER //above most mobs, but below speechbubbles
|
||||
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 20, /obj/item/stack/sheet/animalhide/xeno = 3)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 20, /obj/item/stack/sheet/animalhide/xeno = 3)
|
||||
|
||||
var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
name = "\improper royal parasite"
|
||||
desc = "Inject this into one of your grown children to promote her to a Praetorian!"
|
||||
icon_state = "alien_medal"
|
||||
flags = ABSTRACT|NODROP|DROPDEL
|
||||
flags_1 = ABSTRACT_1|NODROP_1|DROPDEL_1
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
|
||||
/obj/item/queenpromote/attack(mob/living/M, mob/living/carbon/alien/humanoid/user)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
icon_state = "facehugger"
|
||||
item_state = "facehugger"
|
||||
w_class = WEIGHT_CLASS_TINY //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
flags = MASKINTERNALS
|
||||
flags_1 = MASKINTERNALS_1
|
||||
throw_range = 5
|
||||
tint = 3
|
||||
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
var/obj/item/item_in_hand = src.get_active_held_item()
|
||||
if(item_in_hand) //this segment checks if the item in your hand is twohanded.
|
||||
var/obj/item/weapon/twohanded/TH = item_in_hand
|
||||
var/obj/item/twohanded/TH = item_in_hand
|
||||
if(istype(TH))
|
||||
if(TH.wielded == 1)
|
||||
to_chat(usr, "<span class='warning'>Your other hand is too busy holding [TH]</span>")
|
||||
@@ -165,7 +165,7 @@
|
||||
var/end_T_descriptor = "<font color='#6b4400'>tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]</font>"
|
||||
add_logs(src, throwable_mob, "thrown", addition="from [start_T_descriptor] with the target [end_T_descriptor]")
|
||||
|
||||
else if(!(I.flags & (NODROP|ABSTRACT)))
|
||||
else if(!(I.flags_1 & (NODROP_1|ABSTRACT_1)))
|
||||
thrown_thing = I
|
||||
dropItemToGround(I)
|
||||
|
||||
@@ -188,17 +188,17 @@
|
||||
<HR>
|
||||
<B><FONT size=3>[name]</FONT></B>
|
||||
<HR>
|
||||
<BR><B>Head:</B> <A href='?src=\ref[src];item=[slot_head]'> [(head && !(head.flags&ABSTRACT)) ? head : "Nothing"]</A>
|
||||
<BR><B>Mask:</B> <A href='?src=\ref[src];item=[slot_wear_mask]'> [(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "Nothing"]</A>
|
||||
<BR><B>Neck:</B> <A href='?src=\ref[src];item=[slot_neck]'> [(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "Nothing"]</A>"}
|
||||
<BR><B>Head:</B> <A href='?src=\ref[src];item=[slot_head]'> [(head && !(head.flags_1&ABSTRACT_1)) ? head : "Nothing"]</A>
|
||||
<BR><B>Mask:</B> <A href='?src=\ref[src];item=[slot_wear_mask]'> [(wear_mask && !(wear_mask.flags_1&ABSTRACT_1)) ? wear_mask : "Nothing"]</A>
|
||||
<BR><B>Neck:</B> <A href='?src=\ref[src];item=[slot_neck]'> [(wear_neck && !(wear_neck.flags_1&ABSTRACT_1)) ? wear_neck : "Nothing"]</A>"}
|
||||
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "Nothing"]</a>"
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags_1 & ABSTRACT_1)) ? I : "Nothing"]</a>"
|
||||
|
||||
dat += "<BR><B>Back:</B> <A href='?src=\ref[src];item=[slot_back]'>[back ? back : "Nothing"]</A>"
|
||||
|
||||
if(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank))
|
||||
if(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/tank))
|
||||
dat += "<BR><A href='?src=\ref[src];internal=1'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
|
||||
if(handcuffed)
|
||||
@@ -220,15 +220,15 @@
|
||||
if(href_list["internal"])
|
||||
var/slot = text2num(href_list["internal"])
|
||||
var/obj/item/ITEM = get_item_by_slot(slot)
|
||||
if(ITEM && istype(ITEM, /obj/item/weapon/tank) && wear_mask && (wear_mask.flags & MASKINTERNALS))
|
||||
if(ITEM && istype(ITEM, /obj/item/tank) && wear_mask && (wear_mask.flags_1 & MASKINTERNALS_1))
|
||||
visible_message("<span class='danger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].</span>", \
|
||||
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].</span>")
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY))
|
||||
if(internal)
|
||||
internal = null
|
||||
update_internals_hud_icon(0)
|
||||
else if(ITEM && istype(ITEM, /obj/item/weapon/tank))
|
||||
if((wear_mask && (wear_mask.flags & MASKINTERNALS)) || getorganslot("breathing_tube"))
|
||||
else if(ITEM && istype(ITEM, /obj/item/tank))
|
||||
if((wear_mask && (wear_mask.flags_1 & MASKINTERNALS_1)) || getorganslot("breathing_tube"))
|
||||
internal = ITEM
|
||||
update_internals_hud_icon(1)
|
||||
|
||||
@@ -321,7 +321,7 @@
|
||||
|
||||
/mob/living/carbon/proc/uncuff()
|
||||
if (handcuffed)
|
||||
var/obj/item/weapon/W = handcuffed
|
||||
var/obj/item/W = handcuffed
|
||||
handcuffed = null
|
||||
if (buckled && buckled.buckle_requires_restraints)
|
||||
buckled.unbuckle_mob(src)
|
||||
@@ -336,7 +336,7 @@
|
||||
W.plane = initial(W.plane)
|
||||
changeNext_move(0)
|
||||
if (legcuffed)
|
||||
var/obj/item/weapon/W = legcuffed
|
||||
var/obj/item/W = legcuffed
|
||||
legcuffed = null
|
||||
update_inv_legcuffed()
|
||||
if (client)
|
||||
@@ -394,7 +394,7 @@
|
||||
return initial(pixel_y)
|
||||
|
||||
/mob/living/carbon/proc/accident(obj/item/I)
|
||||
if(!I || (I.flags & (NODROP|ABSTRACT)))
|
||||
if(!I || (I.flags_1 & (NODROP_1|ABSTRACT_1)))
|
||||
return
|
||||
|
||||
dropItemToGround(I)
|
||||
@@ -732,7 +732,7 @@
|
||||
regenerate_limbs()
|
||||
regenerate_organs()
|
||||
handcuffed = initial(handcuffed)
|
||||
for(var/obj/item/weapon/restraints/R in contents) //actually remove cuffs from inventory
|
||||
for(var/obj/item/restraints/R in contents) //actually remove cuffs from inventory
|
||||
qdel(R)
|
||||
update_handcuffed()
|
||||
if(reagents)
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
/mob/living/carbon/get_ear_protection()
|
||||
var/number = ..()
|
||||
if(ears && HAS_SECONDARY_FLAG(ears, BANG_PROTECT))
|
||||
if(ears && (ears.flags_2 & BANG_PROTECT_2))
|
||||
number += 1
|
||||
if(head && HAS_SECONDARY_FLAG(head, BANG_PROTECT))
|
||||
if(head && (head.flags_2 & BANG_PROTECT_2))
|
||||
number += 1
|
||||
var/obj/item/organ/ears/E = getorganslot("ears")
|
||||
if(!E)
|
||||
@@ -210,7 +210,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
if(tesla_shock && HAS_SECONDARY_FLAG(src, TESLA_IGNORE))
|
||||
if(tesla_shock && (flags_2 & TESLA_IGNORE_2))
|
||||
return FALSE
|
||||
shock_damage *= siemens_coeff
|
||||
if(dna && dna.species)
|
||||
@@ -255,6 +255,8 @@
|
||||
else if(check_zone(M.zone_selected) == "head")
|
||||
M.visible_message("<span class='notice'>[M] gives [src] a pat on the head to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You give [src] a pat on the head to make [p_them()] feel better!</span>")
|
||||
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || (dna.features["tail_human"] != "None") || ("mam_tail" in dna.species.mutant_bodyparts)))
|
||||
emote("wag") //lewd
|
||||
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>")
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
var/obj/item/handcuffed = null //Whether or not the mob is handcuffed
|
||||
var/obj/item/legcuffed = null //Same as handcuffs but for legs. Bear traps use this.
|
||||
|
||||
var/disgust = 0
|
||||
|
||||
//inventory slots
|
||||
var/obj/item/back = null
|
||||
var/obj/item/clothing/mask/wear_mask = null
|
||||
var/obj/item/clothing/neck/wear_neck = null
|
||||
var/obj/item/weapon/tank/internal = null
|
||||
var/obj/item/tank/internal = null
|
||||
var/obj/item/head = null
|
||||
|
||||
var/obj/item/gloves = null //only used by humans
|
||||
@@ -31,7 +33,7 @@
|
||||
var/co2overloadtime = null
|
||||
var/temperature_resistance = T0C+75
|
||||
has_limbs = 1
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab
|
||||
var/obj/item/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab
|
||||
|
||||
var/list/obj/effect/proc_holder/alien/abilities = list()
|
||||
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
@@ -47,4 +49,4 @@
|
||||
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
|
||||
|
||||
var/icon_render_key = ""
|
||||
var/static/list/limb_icon_cache = list()
|
||||
var/static/list/limb_icon_cache = list()
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
if(istype(T) && movement_dir && T.allow_thrust(0.01))
|
||||
return 1
|
||||
|
||||
var/obj/item/weapon/tank/jetpack/J = get_jetpack()
|
||||
var/obj/item/tank/jetpack/J = get_jetpack()
|
||||
if(istype(J) && (movement_dir || J.stabilizers) && J.allow_thrust(0.01, src))
|
||||
return 1
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
msg += "[t_He] [t_is] wearing [icon2html(wear_neck, user)] \a [src.wear_neck] around [t_his] neck.\n"
|
||||
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & ABSTRACT))
|
||||
if(!(I.flags_1 & ABSTRACT_1))
|
||||
if(I.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
|
||||
else
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
//Hands
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & ABSTRACT))
|
||||
if(!(I.flags_1 & ABSTRACT_1))
|
||||
if(I.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
|
||||
else
|
||||
@@ -77,7 +77,7 @@
|
||||
|
||||
//handcuffed?
|
||||
if(handcuffed)
|
||||
if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable))
|
||||
if(istype(handcuffed, /obj/item/restraints/handcuffs/cable))
|
||||
msg += "<span class='warning'>[t_He] [t_is] [icon2html(handcuffed, user)] restrained with cable!</span>\n"
|
||||
else
|
||||
msg += "<span class='warning'>[t_He] [t_is] [icon2html(handcuffed, user)] handcuffed!</span>\n"
|
||||
@@ -225,6 +225,14 @@
|
||||
else
|
||||
msg += "[t_He] [t_is] quite chubby.\n"
|
||||
|
||||
switch(disgust)
|
||||
if(DISGUST_LEVEL_GROSS to DISGUST_LEVEL_VERYGROSS)
|
||||
msg += "[t_He] looks a bit grossed out.\n"
|
||||
if(DISGUST_LEVEL_VERYGROSS to DISGUST_LEVEL_DISGUSTED)
|
||||
msg += "[t_He] looks really grossed out.\n"
|
||||
if(DISGUST_LEVEL_DISGUSTED to INFINITY)
|
||||
msg += "[t_He] looks disgusted.\n"
|
||||
|
||||
if(blood_volume < BLOOD_VOLUME_SAFE)
|
||||
msg += "[t_He] [t_has] pale skin.\n"
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
|
||||
INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
|
||||
/mob/living/carbon/human/dummy/Destroy()
|
||||
..()
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
/mob/living/carbon/human/dummy/Life()
|
||||
return
|
||||
|
||||
@@ -145,43 +141,43 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
dat += "<table>"
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<tr><td><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
dat += "<tr><td><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags_1 & ABSTRACT_1)) ? I : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
dat += "<tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Back:</B></td><td><A href='?src=\ref[src];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(back, /obj/item/weapon/tank))
|
||||
dat += "<tr><td><B>Back:</B></td><td><A href='?src=\ref[src];item=[slot_back]'>[(back && !(back.flags_1&ABSTRACT_1)) ? back : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(back, /obj/item/tank))
|
||||
dat += " <A href='?src=\ref[src];internal=[slot_back]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
|
||||
dat += "</td></tr><tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Head:</B></td><td><A href='?src=\ref[src];item=[slot_head]'>[(head && !(head.flags&ABSTRACT)) ? head : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Head:</B></td><td><A href='?src=\ref[src];item=[slot_head]'>[(head && !(head.flags_1&ABSTRACT_1)) ? head : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_wear_mask in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Mask:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=\ref[src];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=\ref[src];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags_1&ABSTRACT_1)) ? wear_mask : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_neck in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Neck:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Neck:</B></td><td><A href='?src=\ref[src];item=[slot_neck]'>[(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Neck:</B></td><td><A href='?src=\ref[src];item=[slot_neck]'>[(wear_neck && !(wear_neck.flags_1&ABSTRACT_1)) ? wear_neck : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_glasses in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Eyes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Eyes:</B></td><td><A href='?src=\ref[src];item=[slot_glasses]'>[(glasses && !(glasses.flags&ABSTRACT)) ? glasses : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Eyes:</B></td><td><A href='?src=\ref[src];item=[slot_glasses]'>[(glasses && !(glasses.flags_1&ABSTRACT_1)) ? glasses : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_ears in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Ears:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Ears:</B></td><td><A href='?src=\ref[src];item=[slot_ears]'>[(ears && !(ears.flags&ABSTRACT)) ? ears : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Ears:</B></td><td><A href='?src=\ref[src];item=[slot_ears]'>[(ears && !(ears.flags_1&ABSTRACT_1)) ? ears : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
dat += "<tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=\ref[src];item=[slot_wear_suit]'>[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? wear_suit : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=\ref[src];item=[slot_wear_suit]'>[(wear_suit && !(wear_suit.flags_1&ABSTRACT_1)) ? wear_suit : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
if(wear_suit)
|
||||
dat += "<tr><td> ↳<B>Suit Storage:</B></td><td><A href='?src=\ref[src];item=[slot_s_store]'>[(s_store && !(s_store.flags&ABSTRACT)) ? s_store : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(s_store, /obj/item/weapon/tank))
|
||||
dat += "<tr><td> ↳<B>Suit Storage:</B></td><td><A href='?src=\ref[src];item=[slot_s_store]'>[(s_store && !(s_store.flags_1&ABSTRACT_1)) ? s_store : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(s_store, /obj/item/tank))
|
||||
dat += " <A href='?src=\ref[src];internal=[slot_s_store]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
dat += "</td></tr>"
|
||||
else
|
||||
@@ -190,30 +186,30 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
if(slot_shoes in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Shoes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Shoes:</B></td><td><A href='?src=\ref[src];item=[slot_shoes]'>[(shoes && !(shoes.flags&ABSTRACT)) ? shoes : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Shoes:</B></td><td><A href='?src=\ref[src];item=[slot_shoes]'>[(shoes && !(shoes.flags_1&ABSTRACT_1)) ? shoes : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_gloves in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Gloves:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Gloves:</B></td><td><A href='?src=\ref[src];item=[slot_gloves]'>[(gloves && !(gloves.flags&ABSTRACT)) ? gloves : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Gloves:</B></td><td><A href='?src=\ref[src];item=[slot_gloves]'>[(gloves && !(gloves.flags_1&ABSTRACT_1)) ? gloves : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_w_uniform in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Uniform:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Uniform:</B></td><td><A href='?src=\ref[src];item=[slot_w_uniform]'>[(w_uniform && !(w_uniform.flags&ABSTRACT)) ? w_uniform : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Uniform:</B></td><td><A href='?src=\ref[src];item=[slot_w_uniform]'>[(w_uniform && !(w_uniform.flags_1&ABSTRACT_1)) ? w_uniform : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if((w_uniform == null && !(dna && dna.species.nojumpsuit)) || (slot_w_uniform in obscured))
|
||||
dat += "<tr><td><font color=grey> ↳<B>Pockets:</B></font></td></tr>"
|
||||
dat += "<tr><td><font color=grey> ↳<B>ID:</B></font></td></tr>"
|
||||
dat += "<tr><td><font color=grey> ↳<B>Belt:</B></font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td> ↳<B>Belt:</B></td><td><A href='?src=\ref[src];item=[slot_belt]'>[(belt && !(belt.flags&ABSTRACT)) ? belt : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(belt, /obj/item/weapon/tank))
|
||||
dat += "<tr><td> ↳<B>Belt:</B></td><td><A href='?src=\ref[src];item=[slot_belt]'>[(belt && !(belt.flags_1&ABSTRACT_1)) ? belt : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(belt, /obj/item/tank))
|
||||
dat += " <A href='?src=\ref[src];internal=[slot_belt]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
dat += "</td></tr>"
|
||||
dat += "<tr><td> ↳<B>Pockets:</B></td><td><A href='?src=\ref[src];pockets=left'>[(l_store && !(l_store.flags&ABSTRACT)) ? "Left (Full)" : "<font color=grey>Left (Empty)</font>"]</A>"
|
||||
dat += " <A href='?src=\ref[src];pockets=right'>[(r_store && !(r_store.flags&ABSTRACT)) ? "Right (Full)" : "<font color=grey>Right (Empty)</font>"]</A></td></tr>"
|
||||
dat += "<tr><td> ↳<B>ID:</B></td><td><A href='?src=\ref[src];item=[slot_wear_id]'>[(wear_id && !(wear_id.flags&ABSTRACT)) ? wear_id : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td> ↳<B>Pockets:</B></td><td><A href='?src=\ref[src];pockets=left'>[(l_store && !(l_store.flags_1&ABSTRACT_1)) ? "Left (Full)" : "<font color=grey>Left (Empty)</font>"]</A>"
|
||||
dat += " <A href='?src=\ref[src];pockets=right'>[(r_store && !(r_store.flags_1&ABSTRACT_1)) ? "Right (Full)" : "<font color=grey>Right (Empty)</font>"]</A></td></tr>"
|
||||
dat += "<tr><td> ↳<B>ID:</B></td><td><A href='?src=\ref[src];item=[slot_wear_id]'>[(wear_id && !(wear_id.flags_1&ABSTRACT_1)) ? wear_id : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<tr><td><B>Handcuffed:</B> <A href='?src=\ref[src];item=[slot_handcuffed]'>Remove</A></td></tr>"
|
||||
@@ -275,11 +271,11 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
var/obj/item/place_item = usr.get_active_held_item() // Item to place in the pocket, if it's empty
|
||||
|
||||
var/delay_denominator = 1
|
||||
if(pocket_item && !(pocket_item.flags&ABSTRACT))
|
||||
if(pocket_item.flags & NODROP)
|
||||
if(pocket_item && !(pocket_item.flags_1&ABSTRACT_1))
|
||||
if(pocket_item.flags_1 & NODROP_1)
|
||||
to_chat(usr, "<span class='warning'>You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!</span>")
|
||||
to_chat(usr, "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>")
|
||||
else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.flags&ABSTRACT))
|
||||
else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.flags_1&ABSTRACT_1))
|
||||
to_chat(usr, "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>")
|
||||
delay_denominator = 4
|
||||
else
|
||||
@@ -319,7 +315,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical))
|
||||
return
|
||||
var/obj/item/weapon/photo/P = null
|
||||
var/obj/item/photo/P = null
|
||||
if(href_list["photo_front"])
|
||||
P = R.fields["photo_front"]
|
||||
else if(href_list["photo_side"])
|
||||
@@ -525,10 +521,10 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
// If targeting the head, see if the head item is thin enough.
|
||||
// If targeting anything else, see if the wear suit is thin enough.
|
||||
if(above_neck(target_zone))
|
||||
if(head && head.flags & THICKMATERIAL && !penetrate_thick)
|
||||
if(head && head.flags_1 & THICKMATERIAL_1 && !penetrate_thick)
|
||||
. = 0
|
||||
else
|
||||
if(wear_suit && wear_suit.flags & THICKMATERIAL && !penetrate_thick)
|
||||
if(wear_suit && wear_suit.flags_1 & THICKMATERIAL_1 && !penetrate_thick)
|
||||
. = 0
|
||||
if(!. && error_msg && user)
|
||||
// Might need re-wording.
|
||||
@@ -573,23 +569,23 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/redtag))
|
||||
threatcount += 4
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag))
|
||||
if(is_holding_item_of_type(/obj/item/gun/energy/laser/redtag))
|
||||
threatcount += 4
|
||||
if(istype(belt, /obj/item/weapon/gun/energy/laser/redtag))
|
||||
if(istype(belt, /obj/item/gun/energy/laser/redtag))
|
||||
threatcount += 2
|
||||
|
||||
if(lasercolor == "r")
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/bluetag))
|
||||
threatcount += 4
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag))
|
||||
if(is_holding_item_of_type(/obj/item/gun/energy/laser/bluetag))
|
||||
threatcount += 4
|
||||
if(istype(belt, /obj/item/weapon/gun/energy/laser/bluetag))
|
||||
if(istype(belt, /obj/item/gun/energy/laser/bluetag))
|
||||
threatcount += 2
|
||||
|
||||
return threatcount
|
||||
|
||||
//Check for ID
|
||||
var/obj/item/weapon/card/id/idcard = get_idcard()
|
||||
var/obj/item/card/id/idcard = get_idcard()
|
||||
if( (judgement_criteria & JUDGE_IDCHECK) && !idcard && name=="Unknown")
|
||||
threatcount += 4
|
||||
|
||||
@@ -617,10 +613,10 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
|
||||
//Check for dresscode violations
|
||||
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/syndi) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi))
|
||||
threatcount += 5
|
||||
threatcount += 6
|
||||
|
||||
//Check for nonhuman scum
|
||||
if(dna && dna.species.id && dna.species.id != "human" || "lizard" || "mammal" || "avian" || "aquatic" || "insect")
|
||||
if(dna && dna.species.id && !(dna.species.id in list("human" , "lizard", "mammal", "avian", "aquatic", "insect")))
|
||||
threatcount += 1
|
||||
|
||||
//mindshield implants imply trustworthyness
|
||||
@@ -628,7 +624,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
threatcount -= 1
|
||||
|
||||
//Agent cards lower threatlevel.
|
||||
if(istype(idcard, /obj/item/weapon/card/id/syndicate))
|
||||
if(istype(idcard, /obj/item/card/id/syndicate))
|
||||
threatcount -= 2
|
||||
|
||||
return threatcount
|
||||
|
||||
@@ -442,7 +442,7 @@
|
||||
else if(S.siemens_coefficient == (-1))
|
||||
total_coeff -= 1
|
||||
siemens_coeff = total_coeff
|
||||
if(HAS_SECONDARY_FLAG(src, TESLA_IGNORE))
|
||||
if(flags_2 & TESLA_IGNORE_2)
|
||||
siemens_coeff = 0
|
||||
else if(!safety)
|
||||
var/gloves_siemens_coeff = 1
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
//gets assignment from ID or ID inside PDA or PDA itself
|
||||
//Useful when player do something with computers
|
||||
/mob/living/carbon/human/proc/get_assignment(if_no_id = "No id", if_no_job = "No job")
|
||||
var/obj/item/weapon/card/id/id = get_idcard()
|
||||
var/obj/item/card/id/id = get_idcard()
|
||||
if(id)
|
||||
. = id.assignment
|
||||
else
|
||||
@@ -27,7 +27,7 @@
|
||||
//gets name from ID or ID inside PDA or PDA itself
|
||||
//Useful when player do something with computers
|
||||
/mob/living/carbon/human/proc/get_authentification_name(if_no_id = "Unknown")
|
||||
var/obj/item/weapon/card/id/id = get_idcard()
|
||||
var/obj/item/card/id/id = get_idcard()
|
||||
if(id)
|
||||
return id.registered_name
|
||||
var/obj/item/device/pda/pda = wear_id
|
||||
@@ -63,9 +63,9 @@
|
||||
//gets name from ID or PDA itself, ID inside PDA doesn't matter
|
||||
//Useful when player is being seen by other mobs
|
||||
/mob/living/carbon/human/proc/get_id_name(if_no_id = "Unknown")
|
||||
var/obj/item/weapon/storage/wallet/wallet = wear_id
|
||||
var/obj/item/storage/wallet/wallet = wear_id
|
||||
var/obj/item/device/pda/pda = wear_id
|
||||
var/obj/item/weapon/card/id/id = wear_id
|
||||
var/obj/item/card/id/id = wear_id
|
||||
var/obj/item/device/modular_computer/tablet/tablet = wear_id
|
||||
if(istype(wallet))
|
||||
id = wallet.front_id
|
||||
@@ -74,7 +74,7 @@
|
||||
else if(istype(pda))
|
||||
. = pda.owner
|
||||
else if(istype(tablet))
|
||||
var/obj/item/weapon/computer_hardware/card_slot/card_slot = tablet.all_components[MC_CARD]
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = tablet.all_components[MC_CARD]
|
||||
if(card_slot && (card_slot.stored_card2 || card_slot.stored_card))
|
||||
if(card_slot.stored_card2) //The second card is the one used for authorization in the ID changing program, so we prioritize it here for consistency
|
||||
. = card_slot.stored_card2.registered_name
|
||||
@@ -94,10 +94,10 @@
|
||||
/mob/living/carbon/human/abiotic(full_body = 0)
|
||||
var/abiotic_hands = FALSE
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & NODROP))
|
||||
if(!(I.flags_1 & NODROP_1))
|
||||
abiotic_hands = TRUE
|
||||
break
|
||||
if(full_body && abiotic_hands && ((back && !(back.flags&NODROP)) || (wear_mask && !(wear_mask.flags&NODROP)) || (head && !(head.flags&NODROP)) || (shoes && !(shoes.flags&NODROP)) || (w_uniform && !(w_uniform.flags&NODROP)) || (wear_suit && !(wear_suit.flags&NODROP)) || (glasses && !(glasses.flags&NODROP)) || (ears && !(ears.flags&NODROP)) || (gloves && !(gloves.flags&NODROP)) ) )
|
||||
if(full_body && abiotic_hands && ((back && !(back.flags_1&NODROP_1)) || (wear_mask && !(wear_mask.flags_1&NODROP_1)) || (head && !(head.flags_1&NODROP_1)) || (shoes && !(shoes.flags_1&NODROP_1)) || (w_uniform && !(w_uniform.flags_1&NODROP_1)) || (wear_suit && !(wear_suit.flags_1&NODROP_1)) || (glasses && !(glasses.flags_1&NODROP_1)) || (ears && !(ears.flags_1&NODROP_1)) || (gloves && !(gloves.flags_1&NODROP_1)) ) )
|
||||
return TRUE
|
||||
return abiotic_hands
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/can_track(mob/living/user)
|
||||
if(wear_id && istype(wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
|
||||
if(wear_id && istype(wear_id.GetID(), /obj/item/card/id/syndicate))
|
||||
return 0
|
||||
if(istype(head, /obj/item/clothing/head))
|
||||
var/obj/item/clothing/head/hat = head
|
||||
@@ -143,19 +143,19 @@
|
||||
var/protection = (prot["head"] + prot["arms"] + prot["feet"] + prot["legs"] + prot["groin"] + prot["chest"] + prot["hands"])/7
|
||||
return protection
|
||||
|
||||
/mob/living/carbon/human/can_use_guns(var/obj/item/weapon/G)
|
||||
/mob/living/carbon/human/can_use_guns(obj/item/G)
|
||||
. = ..()
|
||||
|
||||
if(G.trigger_guard == TRIGGER_GUARD_NORMAL)
|
||||
if(src.dna.check_mutation(HULK))
|
||||
to_chat(src, "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(NOGUNS in src.dna.species.species_traits)
|
||||
to_chat(src, "<span class='warning'>Your fingers don't fit in the trigger guard!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(mind)
|
||||
if(mind.martial_art && mind.martial_art.no_guns) //great dishonor to famiry
|
||||
to_chat(src, "<span class='warning'>Use of ranged weaponry would bring dishonor to the clan.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
return .
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
. += dna.species.movement_delay(src)
|
||||
|
||||
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
|
||||
if(isobj(shoes) && (shoes.flags&NOSLIP) && !(lube&GALOSHES_DONT_HELP))
|
||||
if(isobj(shoes) && (shoes.flags_1&NOSLIP_1) && !(lube&GALOSHES_DONT_HELP))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/experience_pressure_difference()
|
||||
playsound(src, 'sound/effects/space_wind.ogg', 50, 1)
|
||||
if(shoes && shoes.flags&NOSLIP)
|
||||
if(shoes && shoes.flags_1&NOSLIP_1)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -45,13 +45,13 @@
|
||||
var/list/blacklistItems = list() // items we should be ignoring
|
||||
var/maxStepsTick = 6 // step as many times as we can per frame
|
||||
//Job and mind data
|
||||
var/obj/item/weapon/card/id/MYID
|
||||
var/obj/item/weapon/card/id/RPID // the "real" idea they use
|
||||
var/obj/item/card/id/MYID
|
||||
var/obj/item/card/id/RPID // the "real" idea they use
|
||||
var/obj/item/device/pda/MYPDA
|
||||
var/obj/item/main_hand
|
||||
var/obj/item/other_hand
|
||||
var/TRAITS = 0
|
||||
var/obj/item/weapon/card/id/Path_ID
|
||||
var/obj/item/card/id/Path_ID
|
||||
var/datum/job/myjob
|
||||
var/list/myPath = list()
|
||||
faction = list("synth")
|
||||
@@ -87,17 +87,28 @@
|
||||
/// SNPC voice handling
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/loadVoice()
|
||||
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
|
||||
S["knownStrings"] >> knownStrings
|
||||
|
||||
if(fexists("data/npc_saves/snpc.sav"))
|
||||
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
|
||||
S["knownStrings"] >> knownStrings
|
||||
fdel(S)
|
||||
else
|
||||
var/json_file = file("data/npc_saves/snpc.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
knownStrings = json["knownStrings"]
|
||||
if(isnull(knownStrings))
|
||||
knownStrings = list()
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/saveVoice()
|
||||
if(voice_saved)
|
||||
return
|
||||
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
|
||||
WRITE_FILE(S["knownStrings"], knownStrings)
|
||||
var/json_file = file("data/npc_saves/snpc.json")
|
||||
var/list/file_data = list()
|
||||
file_data["knownStrings"] = knownStrings
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
//botPool funcs
|
||||
/mob/living/carbon/human/interactive/proc/takeDelegate(mob/living/carbon/human/interactive/from,doReset=TRUE)
|
||||
@@ -249,7 +260,7 @@
|
||||
T.loc = pick(get_area_turfs(T.job2area(T.myjob)))
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/doSetup()
|
||||
Path_ID = new /obj/item/weapon/card/id(src)
|
||||
Path_ID = new /obj/item/card/id(src)
|
||||
|
||||
var/datum/job/captain/C = new/datum/job/captain
|
||||
Path_ID.access = C.get_access()
|
||||
@@ -286,34 +297,34 @@
|
||||
if("Assistant")
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/weapon)
|
||||
if("Captain","Head of Personnel")
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/weapon/stamp/captain, /obj/item/weapon/disk/nuclear)
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/stamp/captain, /obj/item/disk/nuclear)
|
||||
if("Cook")
|
||||
favoured_types = list(/obj/item/weapon/reagent_containers/food, /obj/item/weapon/kitchen)
|
||||
favoured_types = list(/obj/item/reagent_containers/food, /obj/item/kitchen)
|
||||
functions += "souschef"
|
||||
restrictedJob = 1
|
||||
if("Bartender")
|
||||
favoured_types = list(/obj/item/weapon/reagent_containers/food, /obj/item/weapon/kitchen)
|
||||
favoured_types = list(/obj/item/reagent_containers/food, /obj/item/kitchen)
|
||||
functions += "bartend"
|
||||
restrictedJob = 1
|
||||
if("Station Engineer","Chief Engineer","Atmospheric Technician")
|
||||
favoured_types = list(/obj/item/stack, /obj/item/weapon, /obj/item/clothing)
|
||||
if("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist")
|
||||
favoured_types = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/storage/firstaid, /obj/item/stack/medical, /obj/item/weapon/reagent_containers/syringe)
|
||||
favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/storage/firstaid, /obj/item/stack/medical, /obj/item/reagent_containers/syringe)
|
||||
functions += "healpeople"
|
||||
if("Research Director","Scientist","Roboticist")
|
||||
favoured_types = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/stack, /obj/item/weapon/reagent_containers)
|
||||
favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/stack, /obj/item/reagent_containers)
|
||||
if("Head of Security","Warden","Security Officer","Detective")
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/weapon, /obj/item/weapon/restraints)
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/weapon, /obj/item/restraints)
|
||||
if("Janitor")
|
||||
favoured_types = list(/obj/item/weapon/mop, /obj/item/weapon/reagent_containers/glass/bucket, /obj/item/weapon/reagent_containers/spray/cleaner, /obj/effect/decal/cleanable)
|
||||
favoured_types = list(/obj/item/mop, /obj/item/reagent_containers/glass/bucket, /obj/item/reagent_containers/spray/cleaner, /obj/effect/decal/cleanable)
|
||||
functions += "dojanitor"
|
||||
if("Clown")
|
||||
favoured_types = list(/obj/item/weapon/soap, /obj/item/weapon/reagent_containers/food/snacks/grown/banana, /obj/item/weapon/grown/bananapeel)
|
||||
favoured_types = list(/obj/item/soap, /obj/item/reagent_containers/food/snacks/grown/banana, /obj/item/grown/bananapeel)
|
||||
functions += "clowning"
|
||||
if("Mime")
|
||||
functions -= "chatter"
|
||||
if("Botanist")
|
||||
favoured_types = list(/obj/machinery/hydroponics, /obj/item/weapon/reagent_containers, /obj/item/weapon)
|
||||
favoured_types = list(/obj/machinery/hydroponics, /obj/item/reagent_containers, /obj/item/weapon)
|
||||
functions += "botany"
|
||||
restrictedJob = 1
|
||||
else
|
||||
@@ -505,7 +516,7 @@
|
||||
/mob/living/carbon/human/interactive/proc/insert_into_backpack()
|
||||
var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_hands,"right hand" = slot_hands)
|
||||
var/obj/item/I = get_item_by_slot(pick(slots))
|
||||
var/obj/item/weapon/storage/BP = get_item_by_slot(slot_back)
|
||||
var/obj/item/storage/BP = get_item_by_slot(slot_back)
|
||||
if(back && BP && I)
|
||||
if(BP.can_be_inserted(I,0))
|
||||
BP.handle_item_insertion(I,0)
|
||||
@@ -634,7 +645,7 @@
|
||||
//---------ITEMS
|
||||
if(isitem(TARGET))
|
||||
if(istype(TARGET, /obj/item/weapon))
|
||||
var/obj/item/weapon/W = TARGET
|
||||
var/obj/item/W = TARGET
|
||||
if(W.force >= best_force || prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2))
|
||||
if(!get_item_for_held_index(1) || !get_item_for_held_index(2))
|
||||
put_in_hands(W)
|
||||
@@ -660,7 +671,7 @@
|
||||
if(istype(TARGET, /obj/structure))
|
||||
var/obj/structure/STR = TARGET
|
||||
if(main_hand)
|
||||
var/obj/item/weapon/W = main_hand
|
||||
var/obj/item/W = main_hand
|
||||
STR.attackby(W, src)
|
||||
else
|
||||
STR.attack_hand(src)
|
||||
@@ -960,7 +971,7 @@
|
||||
inactivity_period = 0
|
||||
customEmote("[src]'s chest closes, hiding their insides.")
|
||||
if(SNPC_PSYCHO)
|
||||
var/choice = pick(typesof(/obj/item/weapon/grenade/chem_grenade) - /obj/item/weapon/grenade/chem_grenade)
|
||||
var/choice = pick(typesof(/obj/item/grenade/chem_grenade) - /obj/item/grenade/chem_grenade)
|
||||
|
||||
new choice(src)
|
||||
|
||||
@@ -976,13 +987,13 @@
|
||||
|
||||
var/list/allContents = getAllContents()
|
||||
|
||||
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/internalBeaker = locate(/obj/item/weapon/reagent_containers/glass/beaker/bluespace) in allContents
|
||||
var/obj/item/weapon/storage/bag/plants/internalBag = locate(/obj/item/weapon/storage/bag/plants) in allContents
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/internalBeaker = locate(/obj/item/reagent_containers/glass/beaker/bluespace) in allContents
|
||||
var/obj/item/storage/bag/plants/internalBag = locate(/obj/item/storage/bag/plants) in allContents
|
||||
|
||||
if(!internalBag)
|
||||
internalBag = new/obj/item/weapon/storage/bag/plants(src)
|
||||
internalBag = new/obj/item/storage/bag/plants(src)
|
||||
if(!internalBeaker)
|
||||
internalBeaker = new/obj/item/weapon/reagent_containers/glass/beaker/bluespace(src)
|
||||
internalBeaker = new/obj/item/reagent_containers/glass/beaker/bluespace(src)
|
||||
internalBeaker.name = "Grow-U-All Super Spray"
|
||||
|
||||
if(internalBeaker && internalBag)
|
||||
@@ -1049,7 +1060,7 @@
|
||||
if(change)
|
||||
HP.attackby(internalBeaker,src)
|
||||
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/grown/GF = locate(/obj/item/weapon/reagent_containers/food/snacks/grown) in view(12,src)
|
||||
var/obj/item/reagent_containers/food/snacks/grown/GF = locate(/obj/item/reagent_containers/food/snacks/grown) in view(12,src)
|
||||
if(GF)
|
||||
if(!Adjacent(GF))
|
||||
tryWalk(get_turf(GF))
|
||||
@@ -1084,7 +1095,7 @@
|
||||
var/mob/living/carbon/human/serveTarget
|
||||
|
||||
for(var/mob/living/carbon/human/H in rangeCheck)
|
||||
if(!locate(/obj/item/weapon/reagent_containers/food/drinks) in orange(1,H))
|
||||
if(!locate(/obj/item/reagent_containers/food/drinks) in orange(1,H))
|
||||
serveTarget = H
|
||||
|
||||
|
||||
@@ -1095,9 +1106,9 @@
|
||||
if(!Adjacent(RT))
|
||||
tryWalk(get_turf(RT))
|
||||
else
|
||||
var/drinkChoice = pick(typesof(/obj/item/weapon/reagent_containers/food/drinks) - /obj/item/weapon/reagent_containers/food/drinks)
|
||||
var/drinkChoice = pick(typesof(/obj/item/reagent_containers/food/drinks) - /obj/item/reagent_containers/food/drinks)
|
||||
if(drinkChoice)
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/D = new drinkChoice(get_turf(src))
|
||||
var/obj/item/reagent_containers/food/drinks/D = new drinkChoice(get_turf(src))
|
||||
RT.attackby(D,src)
|
||||
src.say("[pick("Something to wet your whistle!","Down the hatch, a tasty beverage!","One drink, coming right up!","Tasty liquid for your oral intake!","Enjoy!")]")
|
||||
customEmote("[src] [pick("gibbers","drools","slobbers","claps wildly","spits")], serving up a [D]!")
|
||||
@@ -1115,7 +1126,7 @@
|
||||
|
||||
if(retal && TARGET)
|
||||
for(var/obj/item/I in allContents)
|
||||
if(istype(I, /obj/item/weapon/restraints))
|
||||
if(istype(I, /obj/item/restraints))
|
||||
I.attack(TARGET,src) // go go bluespace restraint launcher!
|
||||
inactivity_period = 25
|
||||
break
|
||||
@@ -1129,17 +1140,17 @@
|
||||
var/mob/living/carbon/human/clownTarget
|
||||
var/list/clownPriority = list()
|
||||
|
||||
var/obj/item/weapon/reagent_containers/spray/S = locate(/obj/item/weapon/reagent_containers/spray) in allContents
|
||||
var/obj/item/reagent_containers/spray/S = locate(/obj/item/reagent_containers/spray) in allContents
|
||||
|
||||
if(!S)
|
||||
S = new/obj/item/weapon/reagent_containers/spray(src)
|
||||
S = new/obj/item/reagent_containers/spray(src)
|
||||
S.amount_per_transfer_from_this = 10
|
||||
|
||||
for(var/mob/living/carbon/human/C in rangeCheck)
|
||||
var/pranksNearby = 100
|
||||
for(var/turf/open/T in orange(1,C))
|
||||
for(var/obj/item/A in T)
|
||||
if(istype(A, /obj/item/weapon/soap) || istype(A, /obj/item/weapon/reagent_containers/food/snacks/grown/banana) || istype(A, /obj/item/weapon/grown/bananapeel))
|
||||
if(istype(A, /obj/item/soap) || istype(A, /obj/item/reagent_containers/food/snacks/grown/banana) || istype(A, /obj/item/grown/bananapeel))
|
||||
pranksNearby--
|
||||
if(T.wet)
|
||||
pranksNearby -= 10
|
||||
@@ -1159,13 +1170,13 @@
|
||||
var/hasPranked = 0
|
||||
for(var/A in allContents)
|
||||
if(prob(smartness/2) && !hasPranked)
|
||||
if(istype(A, /obj/item/weapon/soap))
|
||||
if(istype(A, /obj/item/soap))
|
||||
npcDrop(A)
|
||||
hasPranked = 1
|
||||
if(istype(A, /obj/item/weapon/reagent_containers/food/snacks/grown/banana))
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/B = A
|
||||
if(istype(A, /obj/item/reagent_containers/food/snacks/grown/banana))
|
||||
var/obj/item/reagent_containers/food/snacks/B = A
|
||||
B.attack(src, src)
|
||||
if(istype(A, /obj/item/weapon/grown/bananapeel))
|
||||
if(istype(A, /obj/item/grown/bananapeel))
|
||||
npcDrop(A)
|
||||
hasPranked = 1
|
||||
if(!hasPranked)
|
||||
@@ -1185,12 +1196,12 @@
|
||||
shouldTryHeal = 1
|
||||
M = A
|
||||
|
||||
var/obj/item/weapon/reagent_containers/hypospray/HPS
|
||||
var/obj/item/reagent_containers/hypospray/HPS
|
||||
|
||||
if(!locate(/obj/item/weapon/reagent_containers/hypospray) in allContents)
|
||||
new/obj/item/weapon/reagent_containers/hypospray(src)
|
||||
if(!locate(/obj/item/reagent_containers/hypospray) in allContents)
|
||||
new/obj/item/reagent_containers/hypospray(src)
|
||||
else
|
||||
HPS = locate(/obj/item/weapon/reagent_containers/hypospray) in allContents
|
||||
HPS = locate(/obj/item/reagent_containers/hypospray) in allContents
|
||||
if(!shouldTryHeal)
|
||||
shouldTryHeal = 2 // we have no stackables to use, lets use our internal hypospray instead
|
||||
|
||||
@@ -1222,11 +1233,11 @@
|
||||
return
|
||||
var/list/allContents = getAllContents()
|
||||
//now with bluespace magic!
|
||||
var/obj/item/weapon/reagent_containers/spray/S
|
||||
if(!locate(/obj/item/weapon/reagent_containers/spray) in allContents)
|
||||
new/obj/item/weapon/reagent_containers/spray(src)
|
||||
var/obj/item/reagent_containers/spray/S
|
||||
if(!locate(/obj/item/reagent_containers/spray) in allContents)
|
||||
new/obj/item/reagent_containers/spray(src)
|
||||
else
|
||||
S = locate(/obj/item/weapon/reagent_containers/spray) in allContents
|
||||
S = locate(/obj/item/reagent_containers/spray) in allContents
|
||||
|
||||
if(S)
|
||||
if(S.reagents.total_volume <= 5)
|
||||
@@ -1246,10 +1257,10 @@
|
||||
visible_message("<span class='notice'>[text]</span>")
|
||||
|
||||
// START COOKING MODULE
|
||||
/mob/living/carbon/human/interactive/proc/cookingwithmagic(var/obj/item/weapon/reagent_containers/food/snacks/target)
|
||||
/mob/living/carbon/human/interactive/proc/cookingwithmagic(var/obj/item/reagent_containers/food/snacks/target)
|
||||
if(Adjacent(target))
|
||||
customEmote("[src] [pick("gibbers","drools","slobbers","claps wildly","spits")] towards [target], and with a bang, it's instantly cooked!")
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/S = new target.cooked_type (get_turf(src))
|
||||
var/obj/item/reagent_containers/food/snacks/S = new target.cooked_type (get_turf(src))
|
||||
target.initialize_cooked_food(S, 100)
|
||||
if(target) // cleaning up old food seems inconsistent, so this will clean up stragglers
|
||||
qdel(target)
|
||||
@@ -1266,13 +1277,13 @@
|
||||
var/list/allContents = getAllContents()
|
||||
|
||||
//Bluespace in some inbuilt tools
|
||||
var/obj/item/weapon/kitchen/rollingpin/RP = locate(/obj/item/weapon/kitchen/rollingpin) in allContents
|
||||
var/obj/item/kitchen/rollingpin/RP = locate(/obj/item/kitchen/rollingpin) in allContents
|
||||
if(!RP)
|
||||
new/obj/item/weapon/kitchen/rollingpin(src)
|
||||
new/obj/item/kitchen/rollingpin(src)
|
||||
|
||||
var/obj/item/weapon/kitchen/knife/KK = locate(/obj/item/weapon/kitchen/knife) in allContents
|
||||
var/obj/item/kitchen/knife/KK = locate(/obj/item/kitchen/knife) in allContents
|
||||
if(!KK)
|
||||
new/obj/item/weapon/kitchen/knife(src)
|
||||
new/obj/item/kitchen/knife(src)
|
||||
|
||||
var/foundCookable = 0
|
||||
|
||||
@@ -1281,11 +1292,11 @@
|
||||
var/list/rangeCheck = view(6,src)
|
||||
|
||||
//Make some basic custom food
|
||||
var/list/customableTypes = list(/obj/item/weapon/reagent_containers/food/snacks/customizable, /obj/item/weapon/reagent_containers/food/snacks/store/bread/plain, /obj/item/weapon/reagent_containers/food/snacks/pizzabread, /obj/item/weapon/reagent_containers/food/snacks/bun, /obj/item/weapon/reagent_containers/food/snacks/store/cake/plain, /obj/item/weapon/reagent_containers/food/snacks/pie/plain, /obj/item/weapon/reagent_containers/food/snacks/pastrybase)
|
||||
var/list/customableTypes = list(/obj/item/reagent_containers/food/snacks/customizable, /obj/item/reagent_containers/food/snacks/store/bread/plain, /obj/item/reagent_containers/food/snacks/pizzabread, /obj/item/reagent_containers/food/snacks/bun, /obj/item/reagent_containers/food/snacks/store/cake/plain, /obj/item/reagent_containers/food/snacks/pie/plain, /obj/item/reagent_containers/food/snacks/pastrybase)
|
||||
|
||||
var/foundCustom
|
||||
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/DP in rangeCheck) // donkpockets are hitler to chef SNPCs
|
||||
for(var/obj/item/reagent_containers/food/snacks/donkpocket/DP in rangeCheck) // donkpockets are hitler to chef SNPCs
|
||||
if(prob(50))
|
||||
customEmote("[src] points at the [DP], emitting a loud [pick("bellow","screech","yell","scream")], and it bursts into flame.")
|
||||
qdel(DP)
|
||||
@@ -1309,8 +1320,8 @@
|
||||
|
||||
|
||||
if(foundCustom)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/FC = foundCustom
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/toMake in allContents)
|
||||
var/obj/item/reagent_containers/food/snacks/FC = foundCustom
|
||||
for(var/obj/item/reagent_containers/food/snacks/toMake in allContents)
|
||||
if(prob(smartness))
|
||||
if(FC.reagents)
|
||||
FC.attackby(toMake,src)
|
||||
@@ -1319,10 +1330,10 @@
|
||||
|
||||
|
||||
//Process dough into various states
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/dough/D = locate(/obj/item/weapon/reagent_containers/food/snacks/dough) in rangeCheck
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/flatdough/FD = locate(/obj/item/weapon/reagent_containers/food/snacks/flatdough) in rangeCheck
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/cakebatter/CB = locate(/obj/item/weapon/reagent_containers/food/snacks/cakebatter) in rangeCheck
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/piedough/PD = locate(/obj/item/weapon/reagent_containers/food/snacks/piedough) in rangeCheck
|
||||
var/obj/item/reagent_containers/food/snacks/dough/D = locate(/obj/item/reagent_containers/food/snacks/dough) in rangeCheck
|
||||
var/obj/item/reagent_containers/food/snacks/flatdough/FD = locate(/obj/item/reagent_containers/food/snacks/flatdough) in rangeCheck
|
||||
var/obj/item/reagent_containers/food/snacks/cakebatter/CB = locate(/obj/item/reagent_containers/food/snacks/cakebatter) in rangeCheck
|
||||
var/obj/item/reagent_containers/food/snacks/piedough/PD = locate(/obj/item/reagent_containers/food/snacks/piedough) in rangeCheck
|
||||
|
||||
if(D)
|
||||
TARGET = D
|
||||
@@ -1367,7 +1378,7 @@
|
||||
|
||||
|
||||
//Cook various regular foods into processed versions
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/toCook = locate(/obj/item/weapon/reagent_containers/food/snacks) in rangeCheck
|
||||
var/obj/item/reagent_containers/food/snacks/toCook = locate(/obj/item/reagent_containers/food/snacks) in rangeCheck
|
||||
if(toCook)
|
||||
if(toCook.cooked_type)
|
||||
TARGET = toCook
|
||||
@@ -1378,11 +1389,11 @@
|
||||
tryWalk(get_turf(toCook))
|
||||
|
||||
var/list/finishedList = list()
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/toDisplay in allContents)
|
||||
if(!toDisplay.cooked_type && !istype(toDisplay, /obj/item/weapon/reagent_containers/food/snacks/grown)) // dont display our ingredients
|
||||
for(var/obj/item/reagent_containers/food/snacks/toDisplay in allContents)
|
||||
if(!toDisplay.cooked_type && !istype(toDisplay, /obj/item/reagent_containers/food/snacks/grown)) // dont display our ingredients
|
||||
finishedList += toDisplay
|
||||
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/toGrab in rangeCheck)
|
||||
for(var/obj/item/reagent_containers/food/snacks/toGrab in rangeCheck)
|
||||
if(!(locate(/obj/structure/table/reinforced) in get_turf(toGrab))) //it's not being displayed
|
||||
foundCookable = 1
|
||||
if(!Adjacent(toGrab))
|
||||
@@ -1395,7 +1406,7 @@
|
||||
|
||||
for(var/obj/structure/table/reinforced/toCheck in rangeCheck)
|
||||
var/counted = 0
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/S in get_turf(toCheck))
|
||||
for(var/obj/item/reagent_containers/food/snacks/S in get_turf(toCheck))
|
||||
++counted
|
||||
if(counted < 12) // make sure theres not too much food here
|
||||
RT = toCheck
|
||||
@@ -1406,20 +1417,20 @@
|
||||
if(!Adjacent(RT))
|
||||
tryWalk(get_turf(RT))
|
||||
else
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/toPlop in allContents)
|
||||
for(var/obj/item/reagent_containers/food/snacks/toPlop in allContents)
|
||||
RT.attackby(toPlop,src)
|
||||
|
||||
if(!foundCookable)
|
||||
var/list/allTypes = list(/obj/item/weapon/reagent_containers/food/snacks/piedough, /obj/item/weapon/reagent_containers/food/snacks/cakebatter, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/flatdough)
|
||||
var/list/allTypes = list(/obj/item/reagent_containers/food/snacks/piedough, /obj/item/reagent_containers/food/snacks/cakebatter, /obj/item/reagent_containers/food/snacks/dough, /obj/item/reagent_containers/food/snacks/flatdough)
|
||||
|
||||
for(var/A in typesof(/obj/item/weapon/reagent_containers/food/snacks))
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/O = A
|
||||
for(var/A in typesof(/obj/item/reagent_containers/food/snacks))
|
||||
var/obj/item/reagent_containers/food/snacks/O = A
|
||||
if(initial(O.cooked_type))
|
||||
allTypes += A
|
||||
|
||||
var/chosenType = pick(allTypes)
|
||||
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/newSnack = new chosenType(get_turf(src))
|
||||
var/obj/item/reagent_containers/food/snacks/newSnack = new chosenType(get_turf(src))
|
||||
TARGET = newSnack
|
||||
newSnack.reagents.remove_any((newSnack.reagents.total_volume/2)-1)
|
||||
newSnack.name = "Synthetic [newSnack.name]"
|
||||
@@ -1463,7 +1474,7 @@
|
||||
|
||||
//ensure we're using the best object possible
|
||||
|
||||
var/obj/item/weapon/best
|
||||
var/obj/item/best
|
||||
var/foundFav = 0
|
||||
var/list/allContents = getAllContents()
|
||||
for(var/test in allContents)
|
||||
@@ -1474,15 +1485,15 @@
|
||||
return
|
||||
if(!foundFav)
|
||||
if(istype(test, /obj/item/weapon))
|
||||
var/obj/item/weapon/R = test
|
||||
var/obj/item/R = test
|
||||
if(R.force > 2) // make sure we don't equip any non-weaponlike items, ie bags and stuff
|
||||
if(!best)
|
||||
best = R
|
||||
else
|
||||
if(best.force < R.force)
|
||||
best = R
|
||||
if(istype(R, /obj/item/weapon/gun))
|
||||
var/obj/item/weapon/gun/G = R
|
||||
if(istype(R, /obj/item/gun))
|
||||
var/obj/item/gun/G = R
|
||||
if(G.can_shoot())
|
||||
best = R
|
||||
break // gun with ammo? screw the rest
|
||||
@@ -1495,16 +1506,16 @@
|
||||
if(M.health > 1)
|
||||
//THROWING OBJECTS
|
||||
for(var/A in allContents)
|
||||
if(istype(A, /obj/item/weapon/gun)) // guns are for shooting, not throwing.
|
||||
if(istype(A, /obj/item/gun)) // guns are for shooting, not throwing.
|
||||
continue
|
||||
if(prob(robustness))
|
||||
if(istype(A, /obj/item/weapon))
|
||||
var/obj/item/weapon/W = A
|
||||
var/obj/item/W = A
|
||||
if(W.throwforce > 19) // Only throw worthwile stuff, no more lobbing wrenches at wenches
|
||||
npcDrop(W,1)
|
||||
throw_item(TARGET)
|
||||
if(istype(A, /obj/item/weapon/grenade)) // Allahu ackbar! ALLAHU ACKBARR!!
|
||||
var/obj/item/weapon/grenade/G = A
|
||||
if(istype(A, /obj/item/grenade)) // Allahu ackbar! ALLAHU ACKBARR!!
|
||||
var/obj/item/grenade/G = A
|
||||
G.attack_self(src)
|
||||
if(prob(smartness))
|
||||
npcDrop(G,1)
|
||||
@@ -1516,11 +1527,11 @@
|
||||
swap_hands()
|
||||
if(main_hand)
|
||||
if(main_hand.force != 0)
|
||||
if(istype(main_hand, /obj/item/weapon/gun))
|
||||
var/obj/item/weapon/gun/G = main_hand
|
||||
if(istype(main_hand, /obj/item/gun))
|
||||
var/obj/item/gun/G = main_hand
|
||||
if(G.can_trigger_gun(src))
|
||||
if(istype(main_hand, /obj/item/weapon/gun/ballistic))
|
||||
var/obj/item/weapon/gun/ballistic/P = main_hand
|
||||
if(istype(main_hand, /obj/item/gun/ballistic))
|
||||
var/obj/item/gun/ballistic/P = main_hand
|
||||
if(!P.chambered)
|
||||
P.chamber_round()
|
||||
P.update_icon()
|
||||
@@ -1529,8 +1540,8 @@
|
||||
npcDrop(P,1)
|
||||
else
|
||||
P.afterattack(TARGET, src)
|
||||
else if(istype(main_hand, /obj/item/weapon/gun/energy))
|
||||
var/obj/item/weapon/gun/energy/P = main_hand
|
||||
else if(istype(main_hand, /obj/item/gun/energy))
|
||||
var/obj/item/gun/energy/P = main_hand
|
||||
var/stunning = 0
|
||||
for(var/A in P.ammo_type)
|
||||
if(ispath(A, /obj/item/ammo_casing/energy/electrode))
|
||||
@@ -1550,7 +1561,7 @@
|
||||
if(!walk2derpless(TARGET))
|
||||
timeout++
|
||||
else
|
||||
var/obj/item/weapon/W = main_hand
|
||||
var/obj/item/W = main_hand
|
||||
W.attack(TARGET,src)
|
||||
else
|
||||
G.loc = get_turf(src) // drop item works inconsistently
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
|
||||
if(!. || !I)
|
||||
return
|
||||
if(index && dna.species.mutanthands)
|
||||
if(index && !QDELETED(src) && dna.species.mutanthands) //hand freed, fill with claws, skip if we're getting deleted.
|
||||
put_in_hand(new dna.species.mutanthands(), index)
|
||||
if(I == wear_suit)
|
||||
if(s_store && invdrop)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
//citadel code
|
||||
if(stat != DEAD)
|
||||
handle_arousal()
|
||||
|
||||
|
||||
if(..()) //not dead
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_life(src)
|
||||
@@ -55,7 +55,9 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
if((wear_suit && (wear_suit.flags & STOPSPRESSUREDMAGE)) && (head && (head.flags & STOPSPRESSUREDMAGE)))
|
||||
if((wear_suit && (wear_suit.flags_1 & STOPSPRESSUREDMAGE_1)) && (head && (head.flags_1 & STOPSPRESSUREDMAGE_1)))
|
||||
return ONE_ATMOSPHERE
|
||||
if(ismob(loc))
|
||||
return ONE_ATMOSPHERE
|
||||
else
|
||||
return pressure
|
||||
@@ -153,7 +155,7 @@
|
||||
//END FIRE CODE
|
||||
|
||||
|
||||
//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list)
|
||||
//This proc returns a number made up of the flags_1 for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list)
|
||||
/mob/living/carbon/human/proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
|
||||
var/thermal_protection_flags = 0
|
||||
//Handle normal clothing
|
||||
@@ -242,6 +244,9 @@
|
||||
|
||||
if(dna && (RESISTCOLD in dna.species.species_traits))
|
||||
return 1
|
||||
|
||||
if(ismob(loc))
|
||||
return 1 //because lazy and being inside somemone insulates you from space
|
||||
|
||||
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
|
||||
var/thermal_protection_flags = get_cold_protection_flags(temperature)
|
||||
@@ -285,13 +290,13 @@
|
||||
|
||||
/mob/living/carbon/human/has_smoke_protection()
|
||||
if(wear_mask)
|
||||
if(wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
if(wear_mask.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
|
||||
. = 1
|
||||
if(glasses)
|
||||
if(glasses.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
if(glasses.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
|
||||
. = 1
|
||||
if(head)
|
||||
if(head.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
if(head.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
|
||||
. = 1
|
||||
if(NOBREATH in dna.species.species_traits)
|
||||
. = 1
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
|
||||
var/obj/item/clothing/mask/chameleon/V = wear_mask
|
||||
if(V.vchange && wear_id)
|
||||
var/obj/item/weapon/card/id/idcard = wear_id.GetID()
|
||||
var/obj/item/card/id/idcard = wear_id.GetID()
|
||||
if(istype(idcard))
|
||||
return idcard.registered_name
|
||||
else
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
|
||||
/datum/species
|
||||
var/id = null // if the game needs to manually check your race to do something not included in a proc here, it will use this
|
||||
var/limbs_id = null //this is used if you want to use a different species limb sprites. Mainly used for angels as they look like humans.
|
||||
var/name = null // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
|
||||
var/id // if the game needs to manually check your race to do something not included in a proc here, it will use this
|
||||
var/limbs_id //this is used if you want to use a different species limb sprites. Mainly used for angels as they look like humans.
|
||||
var/name // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
|
||||
var/roundstart = 0 // can this mob be chosen at roundstart? (assuming the config option is checked?)
|
||||
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
|
||||
|
||||
@@ -21,17 +21,21 @@
|
||||
var/face_y_offset = 0
|
||||
var/hair_y_offset = 0
|
||||
|
||||
var/hair_color = null // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
|
||||
var/hair_color // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
|
||||
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
|
||||
|
||||
var/use_skintones = 0 // does it use skintones or not? (spoiler alert this is only used by humans)
|
||||
var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id.
|
||||
var/exotic_bloodtype = "" //If your race uses a non standard bloodtype (A+, O-, AB-, etc)
|
||||
var/meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing
|
||||
var/skinned_type = null
|
||||
var/meat = /obj/item/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing
|
||||
var/skinned_type
|
||||
var/liked_food = NONE
|
||||
var/disliked_food = NONE
|
||||
var/toxic_food = NONE
|
||||
var/list/no_equip = list() // slots the race can't equip stuff to
|
||||
var/nojumpsuit = 0 // this is sorta... weird. it basically lets you equip stuff that usually needs jumpsuits without one, like belts and pockets and ids
|
||||
var/blacklisted = 0 //Flag to exclude from green slime core species.
|
||||
var/dangerous_existence = null //A flag for transformation spells that tells them "hey if you turn a person into one of these without preperation, they'll probably die!"
|
||||
var/dangerous_existence //A flag for transformation spells that tells them "hey if you turn a person into one of these without preperation, they'll probably die!"
|
||||
var/say_mod = "says" // affects the speech message
|
||||
var/list/default_features = list() // Default mutant bodyparts for this species. Don't forget to set one for every mutant bodypart you allow this species to have.
|
||||
var/list/mutant_bodyparts = list() // Parts of the body that are diferent enough from the standard human model that they cause clipping with some equipment
|
||||
@@ -50,7 +54,7 @@
|
||||
var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded?
|
||||
var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"]
|
||||
|
||||
// species flags. these can be found in flags.dm
|
||||
// species flags_1. these can be found in flags_1.dm
|
||||
var/list/species_traits = list()
|
||||
|
||||
var/attack_verb = "punch" // punch-specific attack verb
|
||||
@@ -67,23 +71,21 @@
|
||||
|
||||
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
|
||||
var/obj/item/organ/ears/mutantears = /obj/item/organ/ears
|
||||
var/obj/item/mutanthands
|
||||
var/obj/item/organ/tongue/mutanttongue = /obj/item/organ/tongue
|
||||
|
||||
|
||||
var/obj/item/organ/liver/mutantliver
|
||||
var/obj/item/organ/stomach/mutantstomach
|
||||
|
||||
//Hands
|
||||
var/obj/item/mutanthands = null
|
||||
|
||||
//Citadel snowflake
|
||||
var/fixed_mut_color2 = ""
|
||||
var/fixed_mut_color3 = ""
|
||||
var/whitelisted = 0 //Is this species restricted to certain players?
|
||||
var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both.
|
||||
|
||||
///////////
|
||||
// PROCS //
|
||||
///////////
|
||||
///////////
|
||||
// PROCS //
|
||||
///////////
|
||||
|
||||
|
||||
/datum/species/New()
|
||||
@@ -216,7 +218,7 @@
|
||||
|
||||
if(mutanthands)
|
||||
// Drop items in hands
|
||||
// If you're lucky enough to have a NODROP item, then it stays.
|
||||
// If you're lucky enough to have a NODROP_1 item, then it stays.
|
||||
for(var/V in C.held_items)
|
||||
var/obj/item/I = V
|
||||
if(istype(I))
|
||||
@@ -411,6 +413,7 @@
|
||||
standing += wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER)
|
||||
else
|
||||
standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER)
|
||||
|
||||
if(H.socks && H.get_num_legs() >= 2 && !(DIGITIGRADE in species_traits))
|
||||
var/datum/sprite_accessory/socks/socks = GLOB.socks_list[H.socks]
|
||||
if(socks)
|
||||
@@ -910,7 +913,7 @@
|
||||
return 0
|
||||
return equip_delay_self_check(I, H, bypass_equip_delay_self)
|
||||
if(slot_l_store)
|
||||
if(I.flags & NODROP) //Pockets aren't visible, so you can't move NODROP items into them.
|
||||
if(I.flags_1 & NODROP_1) //Pockets aren't visible, so you can't move NODROP_1 items into them.
|
||||
return 0
|
||||
if(H.l_store)
|
||||
return 0
|
||||
@@ -926,7 +929,7 @@
|
||||
if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & SLOT_POCKET) )
|
||||
return 1
|
||||
if(slot_r_store)
|
||||
if(I.flags & NODROP)
|
||||
if(I.flags_1 & NODROP_1)
|
||||
return 0
|
||||
if(H.r_store)
|
||||
return 0
|
||||
@@ -943,7 +946,7 @@
|
||||
return 1
|
||||
return 0
|
||||
if(slot_s_store)
|
||||
if(I.flags & NODROP)
|
||||
if(I.flags_1 & NODROP_1)
|
||||
return 0
|
||||
if(H.s_store)
|
||||
return 0
|
||||
@@ -959,13 +962,13 @@
|
||||
if(!disable_warning)
|
||||
to_chat(H, "The [I.name] is too big to attach.") //should be src?
|
||||
return 0
|
||||
if( istype(I, /obj/item/device/pda) || istype(I, /obj/item/weapon/pen) || is_type_in_list(I, H.wear_suit.allowed) )
|
||||
if( istype(I, /obj/item/device/pda) || istype(I, /obj/item/pen) || is_type_in_list(I, H.wear_suit.allowed) )
|
||||
return 1
|
||||
return 0
|
||||
if(slot_handcuffed)
|
||||
if(H.handcuffed)
|
||||
return 0
|
||||
if(!istype(I, /obj/item/weapon/restraints/handcuffs))
|
||||
if(!istype(I, /obj/item/restraints/handcuffs))
|
||||
return 0
|
||||
if(num_arms < 2)
|
||||
return 0
|
||||
@@ -973,14 +976,14 @@
|
||||
if(slot_legcuffed)
|
||||
if(H.legcuffed)
|
||||
return 0
|
||||
if(!istype(I, /obj/item/weapon/restraints/legcuffs))
|
||||
if(!istype(I, /obj/item/restraints/legcuffs))
|
||||
return 0
|
||||
if(num_legs < 2)
|
||||
return 0
|
||||
return 1
|
||||
if(slot_in_backpack)
|
||||
if(H.back && istype(H.back, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/B = H.back
|
||||
if(H.back && istype(H.back, /obj/item/storage))
|
||||
var/obj/item/storage/B = H.back
|
||||
if(B.can_be_inserted(I, 1, H))
|
||||
return 1
|
||||
return 0
|
||||
@@ -1155,7 +1158,7 @@
|
||||
gravity = 1
|
||||
|
||||
if(!gravity)
|
||||
var/obj/item/weapon/tank/jetpack/J = H.back
|
||||
var/obj/item/tank/jetpack/J = H.back
|
||||
var/obj/item/clothing/suit/space/hardsuit/C = H.wear_suit
|
||||
var/obj/item/organ/cyberimp/chest/thrusters/T = H.getorganslot("thrusters")
|
||||
if(!istype(J) && istype(C))
|
||||
@@ -1180,7 +1183,7 @@
|
||||
if(H.back)
|
||||
. += H.back.slowdown
|
||||
for(var/obj/item/I in H.held_items)
|
||||
if(HAS_SECONDARY_FLAG(I, SLOWS_WHILE_IN_HAND))
|
||||
if(I.flags_2 & SLOWS_WHILE_IN_HAND_2)
|
||||
. += I.slowdown
|
||||
var/health_deficiency = (100 - H.health + H.staminaloss)
|
||||
var/hungry = (500 - H.nutrition) / 5 // So overeat would be 100 and default level would be 80
|
||||
@@ -1321,7 +1324,6 @@
|
||||
target.apply_effect(40, KNOCKDOWN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!"))
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
add_logs(user, target, "disarmed", " pushing them to the ground")
|
||||
|
||||
return
|
||||
|
||||
if(randn <= 60)
|
||||
@@ -1329,7 +1331,6 @@
|
||||
if(target.pulling)
|
||||
to_chat(target, "<span class='warning'>[user] has broken [target]'s grip on [target.pulling]!</span>")
|
||||
target.stop_pulling()
|
||||
|
||||
else
|
||||
I = target.get_active_held_item()
|
||||
if(target.drop_item())
|
||||
@@ -1587,6 +1588,7 @@
|
||||
else
|
||||
H.throw_alert("temp", /obj/screen/alert/cold, 3)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod, BURN)
|
||||
|
||||
else
|
||||
H.clear_alert("temp")
|
||||
|
||||
@@ -1695,9 +1697,9 @@
|
||||
return
|
||||
|
||||
|
||||
////////
|
||||
////////////
|
||||
//Stun//
|
||||
////////
|
||||
////////////
|
||||
|
||||
/datum/species/proc/spec_stun(mob/living/carbon/human/H,amount)
|
||||
. = stunmod * amount
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
mutanttongue = /obj/item/organ/tongue/fly
|
||||
mutantliver = /obj/item/organ/liver/fly
|
||||
mutantstomach = /obj/item/organ/stomach/fly
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/fly
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/fly
|
||||
disliked_food = null
|
||||
liked_food = NONE
|
||||
|
||||
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
|
||||
if(chem.id == "pestkiller")
|
||||
@@ -26,6 +28,6 @@
|
||||
..()
|
||||
|
||||
/datum/species/fly/check_weakness(obj/item/weapon, mob/living/attacker)
|
||||
if(istype(weapon, /obj/item/weapon/melee/flyswatter))
|
||||
if(istype(weapon, /obj/item/melee/flyswatter))
|
||||
return 29 //Flyswatters deal 30x damage to flypeople.
|
||||
return 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
datum/species/mammal
|
||||
/datum/species/mammal
|
||||
name = "Mammal"
|
||||
id = "mammal"
|
||||
default_color = "4B4B4B"
|
||||
@@ -9,6 +9,8 @@ datum/species/mammal
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT | FRIED
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/mammal/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -24,12 +26,14 @@ datum/species/mammal
|
||||
say_mod = "chirps"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("snout", "wings", "taur", "mam_tail", "mam_body_markings")
|
||||
mutant_bodyparts = list("snout", "wings", "taur", "mam_tail", "mam_body_markings", "taur")
|
||||
default_features = list("snout" = "Sharp", "wings" = "None", "taur" = "None", "mam_body_markings" = "Hawk")
|
||||
attack_verb = "peck"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT | FRUIT
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/avian/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -44,12 +48,14 @@ datum/species/mammal
|
||||
id = "aquatic"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_tail", "mam_body_markings", "mam_ears")
|
||||
mutant_bodyparts = list("mam_tail", "mam_body_markings", "mam_ears", "taur")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF","mam_tail" = "shark", "mam_body_markings" = "None", "mam_ears" = "None")
|
||||
attack_verb = "bite"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/aquatic/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -64,12 +70,14 @@ datum/species/mammal
|
||||
id = "insect"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_body_markings", "mam_ears", "mam_tail")
|
||||
mutant_bodyparts = list("mam_body_markings", "mam_ears", "mam_tail", "taur")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_body_markings" = "moth", "mam_tail" = "None", "mam_ears" = "None")
|
||||
attack_verb = "flutter" //wat?
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT | FRUIT
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/insect/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -93,11 +101,12 @@ datum/species/mammal
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/xeno
|
||||
exotic_bloodtype = "L"
|
||||
damage_overlay_type = "xeno"
|
||||
roundstart = 1
|
||||
liked_food = MEAT
|
||||
|
||||
//Praise the Omnissiah, A challange worthy of my skills - HS
|
||||
|
||||
@@ -126,7 +135,7 @@ datum/species/mammal
|
||||
exotic_blood = "xblood"
|
||||
damage_overlay_type = "xeno"
|
||||
no_equip = list(slot_glasses) //MY EYES, THEY'RE GONE
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/xeno
|
||||
// safe_toxins_max = 32 //Too much of anything is bad.
|
||||
roundstart = 0
|
||||
@@ -229,7 +238,7 @@ datum/species/mammal
|
||||
whitelist = list("rubyflamewing")
|
||||
blacklisted = 0
|
||||
|
||||
datum/species/guilmon
|
||||
/datum/species/guilmon
|
||||
name = "Guilmon"
|
||||
id = "guilmon"
|
||||
default_color = "4B4B4B"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
nojumpsuit = 1
|
||||
sexes = 1
|
||||
damage_overlay_type = ""
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/golem
|
||||
// To prevent golem subtypes from overwhelming the odds when random species
|
||||
// changes, only the Random Golem type can be chosen
|
||||
blacklisted = TRUE
|
||||
@@ -56,7 +56,7 @@
|
||||
/datum/species/golem/adamantine
|
||||
name = "Adamantine Golem"
|
||||
id = "adamantine golem"
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine
|
||||
mutant_organs = list(/obj/item/organ/adamantine_resonator, /obj/item/organ/vocal_cords/adamantine)
|
||||
fixed_mut_color = "4ed"
|
||||
info_text = "As an <span class='danger'>Adamantine Golem</span>, you possess special vocal cords allowing you to \"resonate\" messages to all golems."
|
||||
@@ -67,7 +67,7 @@
|
||||
name = "Plasma Golem"
|
||||
id = "plasma golem"
|
||||
fixed_mut_color = "a3d"
|
||||
meat = /obj/item/weapon/ore/plasma
|
||||
meat = /obj/item/ore/plasma
|
||||
//Can burn and takes damage from heat
|
||||
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR)
|
||||
info_text = "As a <span class='danger'>Plasma Golem</span>, you burn easily. Be careful, if you get hot enough while burning, you'll blow up!"
|
||||
@@ -127,7 +127,7 @@
|
||||
id = "diamond golem"
|
||||
fixed_mut_color = "0ff"
|
||||
armor = 70 //up from 55
|
||||
meat = /obj/item/weapon/ore/diamond
|
||||
meat = /obj/item/ore/diamond
|
||||
info_text = "As a <span class='danger'>Diamond Golem</span>, you are more resistant than the average golem."
|
||||
prefix = "Diamond"
|
||||
special_names = list("Back")
|
||||
@@ -139,7 +139,7 @@
|
||||
fixed_mut_color = "cc0"
|
||||
speedmod = 1
|
||||
armor = 25 //down from 55
|
||||
meat = /obj/item/weapon/ore/gold
|
||||
meat = /obj/item/ore/gold
|
||||
info_text = "As a <span class='danger'>Gold Golem</span>, you are faster but less resistant than the average golem."
|
||||
prefix = "Golden"
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
id = "silver golem"
|
||||
fixed_mut_color = "ddd"
|
||||
punchstunthreshold = 9 //60% chance, from 40%
|
||||
meat = /obj/item/weapon/ore/silver
|
||||
meat = /obj/item/ore/silver
|
||||
info_text = "As a <span class='danger'>Silver Golem</span>, your attacks are heavier and have a higher chance of stunning."
|
||||
prefix = "Silver"
|
||||
special_names = list("Surfer", "Chariot", "Lining")
|
||||
@@ -164,7 +164,7 @@
|
||||
punchdamagehigh = 21
|
||||
punchstunthreshold = 18 //still 40% stun chance
|
||||
speedmod = 4 //pretty fucking slow
|
||||
meat = /obj/item/weapon/ore/iron
|
||||
meat = /obj/item/ore/iron
|
||||
info_text = "As a <span class='danger'>Plasteel Golem</span>, you are slower, but harder to stun, and hit very hard when punching."
|
||||
attack_verb = "smash"
|
||||
attack_sound = 'sound/effects/meteorimpact.ogg' //hits pretty hard
|
||||
@@ -175,7 +175,7 @@
|
||||
name = "Titanium Golem"
|
||||
id = "titanium golem"
|
||||
fixed_mut_color = "fff"
|
||||
meat = /obj/item/weapon/ore/titanium
|
||||
meat = /obj/item/ore/titanium
|
||||
info_text = "As a <span class='danger'>Titanium Golem</span>, you are immune to ash storms, and slightly more resistant to burn damage."
|
||||
burnmod = 0.9
|
||||
prefix = "Titanium"
|
||||
@@ -193,7 +193,7 @@
|
||||
name = "Plastitanium Golem"
|
||||
id = "plastitanium golem"
|
||||
fixed_mut_color = "888"
|
||||
meat = /obj/item/weapon/ore/titanium
|
||||
meat = /obj/item/ore/titanium
|
||||
info_text = "As a <span class='danger'>Plastitanium Golem</span>, you are immune to both ash storms and lava, and slightly more resistant to burn damage."
|
||||
burnmod = 0.8
|
||||
prefix = "Plastitanium"
|
||||
@@ -284,7 +284,7 @@
|
||||
name = "Uranium Golem"
|
||||
id = "uranium golem"
|
||||
fixed_mut_color = "7f0"
|
||||
meat = /obj/item/weapon/ore/uranium
|
||||
meat = /obj/item/ore/uranium
|
||||
info_text = "As an <span class='danger'>Uranium Golem</span>, you emit radiation pulses every once in a while. It won't harm fellow golems, but organic lifeforms will be affected."
|
||||
|
||||
var/last_event = 0
|
||||
@@ -305,7 +305,7 @@
|
||||
name = "Sand Golem"
|
||||
id = "sand golem"
|
||||
fixed_mut_color = "ffdc8f"
|
||||
meat = /obj/item/weapon/ore/glass //this is sand
|
||||
meat = /obj/item/ore/glass //this is sand
|
||||
armor = 0
|
||||
burnmod = 3 //melts easily
|
||||
brutemod = 0.25
|
||||
@@ -318,7 +318,7 @@
|
||||
for(var/obj/item/W in H)
|
||||
H.dropItemToGround(W)
|
||||
for(var/i=1, i <= rand(3,5), i++)
|
||||
new /obj/item/weapon/ore/glass(get_turf(H))
|
||||
new /obj/item/ore/glass(get_turf(H))
|
||||
qdel(H)
|
||||
|
||||
/datum/species/golem/sand/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
@@ -335,7 +335,7 @@
|
||||
name = "Glass Golem"
|
||||
id = "glass golem"
|
||||
fixed_mut_color = "5a96b4aa" //transparent body
|
||||
meat = /obj/item/weapon/shard
|
||||
meat = /obj/item/shard
|
||||
armor = 0
|
||||
brutemod = 3 //very fragile
|
||||
burnmod = 0.25
|
||||
@@ -349,7 +349,7 @@
|
||||
for(var/obj/item/W in H)
|
||||
H.dropItemToGround(W)
|
||||
for(var/i=1, i <= rand(3,5), i++)
|
||||
new /obj/item/weapon/shard(get_turf(H))
|
||||
new /obj/item/shard(get_turf(H))
|
||||
qdel(H)
|
||||
|
||||
/datum/species/golem/glass/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
@@ -378,7 +378,7 @@
|
||||
name = "Bluespace Golem"
|
||||
id = "bluespace golem"
|
||||
fixed_mut_color = "33f"
|
||||
meat = /obj/item/weapon/ore/bluespace_crystal
|
||||
meat = /obj/item/ore/bluespace_crystal
|
||||
info_text = "As a <span class='danger'>Bluespace Golem</span>, are spatially unstable: you will teleport when hit, and you can teleport manually at a long distance."
|
||||
attack_verb = "bluespace punch"
|
||||
attack_sound = 'sound/effects/phasein.ogg'
|
||||
@@ -473,7 +473,7 @@
|
||||
punchdamagelow = 0
|
||||
punchdamagehigh = 1
|
||||
punchstunthreshold = 2 //Harmless and can't stun
|
||||
meat = /obj/item/weapon/ore/bananium
|
||||
meat = /obj/item/ore/bananium
|
||||
info_text = "As a <span class='danger'>Bananium Golem</span>, you are made for pranking. Your body emits natural honks, and you cannot hurt people when punching them. Your skin also emits bananas when damaged."
|
||||
attack_verb = "honk"
|
||||
attack_sound = 'sound/items/airhorn2.ogg'
|
||||
@@ -493,19 +493,19 @@
|
||||
/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
|
||||
..()
|
||||
if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP)
|
||||
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
|
||||
new/obj/item/grown/bananapeel/specialpeel(get_turf(H))
|
||||
last_banana = world.time
|
||||
|
||||
/datum/species/golem/bananium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
|
||||
..()
|
||||
if(world.time > last_banana + banana_cooldown && user != H)
|
||||
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
|
||||
new/obj/item/grown/bananapeel/specialpeel(get_turf(H))
|
||||
last_banana = world.time
|
||||
|
||||
/datum/species/golem/bananium/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
..()
|
||||
if(world.time > last_banana + banana_cooldown)
|
||||
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
|
||||
new/obj/item/grown/bananapeel/specialpeel(get_turf(H))
|
||||
last_banana = world.time
|
||||
|
||||
/datum/species/golem/bananium/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
|
||||
@@ -516,7 +516,7 @@
|
||||
if(I.thrownby == H) //No throwing stuff at yourself to make bananas
|
||||
return 0
|
||||
else
|
||||
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
|
||||
new/obj/item/grown/bananapeel/specialpeel(get_turf(H))
|
||||
last_banana = world.time
|
||||
|
||||
/datum/species/golem/bananium/spec_life(mob/living/carbon/human/H)
|
||||
@@ -628,7 +628,7 @@
|
||||
desc = "It emits a strange aura, as if there was still life within it..."
|
||||
max_integrity = 50
|
||||
armor = list(melee = 90, bullet = 90, laser = 25, energy = 80, bomb = 50, bio = 100, fire = -50, acid = -50)
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "pile_bandages"
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
@@ -672,7 +672,7 @@
|
||||
cloth_golem = null
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/cloth_pile/attackby(obj/item/weapon/P, mob/living/carbon/human/user, params)
|
||||
/obj/structure/cloth_pile/attackby(obj/item/P, mob/living/carbon/human/user, params)
|
||||
. = ..()
|
||||
|
||||
if(resistance_flags & ON_FIRE)
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
/datum/species/human
|
||||
name = "Human"
|
||||
id = "human"
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(MUTCOLORS_PARTSONLY,EYECOLOR,HAIR,FACEHAIR,LIPS)
|
||||
mutant_bodyparts = list("tail_human", "ears", "taur")
|
||||
default_features = list("tail_human" = "None", "ears" = "None", "taur" = "none")
|
||||
use_skintones = 1
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
|
||||
|
||||
/datum/species/human/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
|
||||
//Curiosity killed the cat's wagging tail.
|
||||
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
/datum/species/human/space_move(mob/living/carbon/human/H)
|
||||
var/obj/item/device/flightpack/F = H.get_flightpack()
|
||||
if(istype(F) && (F.flight) && F.allow_thrust(0.01, src))
|
||||
/datum/species/human
|
||||
name = "Human"
|
||||
id = "human"
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(MUTCOLORS_PARTSONLY,EYECOLOR,HAIR,FACEHAIR,LIPS)
|
||||
mutant_bodyparts = list("tail_human", "ears", "taur")
|
||||
default_features = list("tail_human" = "None", "ears" = "None", "taur" = "none")
|
||||
use_skintones = 1
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
disliked_food = GROSS | RAW
|
||||
liked_food = JUNKFOOD | FRIED
|
||||
|
||||
|
||||
/datum/species/human/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
|
||||
//Curiosity killed the cat's wagging tail.
|
||||
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
/datum/species/human/space_move(mob/living/carbon/human/H)
|
||||
var/obj/item/device/flightpack/F = H.get_flightpack()
|
||||
if(istype(F) && (F.flight) && F.allow_thrust(0.01, src))
|
||||
return TRUE
|
||||
|
||||
datum/species/human/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
|
||||
@@ -28,4 +30,4 @@ datum/species/human/on_species_gain(mob/living/carbon/human/H, datum/species/old
|
||||
if(H.dna.features["tail_human"] == "Cat")
|
||||
var/tail = /obj/item/organ/tail/cat
|
||||
mutant_organs += tail
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
id = "jelly"
|
||||
default_color = "00FF90"
|
||||
say_mod = "chirps"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,TOXINLOVER)
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,TOXINLOVER)
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
exotic_blood = "slimejelly"
|
||||
damage_overlay_type = ""
|
||||
var/datum/action/innate/regenerate_limbs/regenerate_limbs
|
||||
toxic_food = NONE
|
||||
liked_food = MEAT
|
||||
|
||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||
if(regenerate_limbs)
|
||||
@@ -227,7 +229,7 @@
|
||||
else
|
||||
ui_interact(owner)
|
||||
|
||||
/datum/action/innate/swap_body/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.conscious_state)
|
||||
/datum/action/innate/swap_body/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.conscious_state)
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
@@ -324,4 +326,4 @@
|
||||
M.transfer_to(dupe)
|
||||
dupe.visible_message("<span class='notice'>[dupe] blinks and looks \
|
||||
around.</span>",
|
||||
"<span class='notice'>...and move this one instead.</span>")
|
||||
"<span class='notice'>...and move this one instead.</span>")
|
||||
|
||||
@@ -13,9 +13,11 @@
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/lizard
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/lizard
|
||||
exotic_bloodtype = "L"
|
||||
disliked_food = NONE
|
||||
liked_food = NONE
|
||||
|
||||
/datum/species/lizard/after_equip_job(datum/job/J, mob/living/carbon/human/H)
|
||||
H.grant_language(/datum/language/draconic)
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
speedmod = 1
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
var/internal_fire = FALSE //If the bones themselves are burning clothes won't help you much
|
||||
disliked_food = NONE
|
||||
liked_food = NONE
|
||||
|
||||
/datum/species/plasmaman/spec_life(mob/living/carbon/human/H)
|
||||
var/datum/gas_mixture/environment = H.loc.return_air()
|
||||
var/atmos_sealed = (H.wear_suit && (H.wear_suit.flags & STOPSPRESSUREDMAGE)) && (H.head && (H.head.flags & STOPSPRESSUREDMAGE))
|
||||
var/atmos_sealed = (H.wear_suit && (H.wear_suit.flags_1 & STOPSPRESSUREDMAGE_1)) && (H.head && (H.head.flags_1 & STOPSPRESSUREDMAGE_1))
|
||||
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
|
||||
if(environment)
|
||||
if(environment.total_moles())
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
name = "Podperson"
|
||||
id = "pod"
|
||||
default_color = "59CE00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR)
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slice.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
burnmod = 1.25
|
||||
heatmod = 1.5
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/plant
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/plant
|
||||
disliked_food = NONE
|
||||
liked_food = NONE
|
||||
|
||||
/datum/species/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
sexes = 0
|
||||
blacklisted = 1
|
||||
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
|
||||
species_traits = list(NOBREATH,NOBLOOD,RADIMMUNE,VIRUSIMMUNE)
|
||||
dangerous_existence = 1
|
||||
mutanteyes = /obj/item/organ/eyes/night_vision
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
say_mod = "rattles"
|
||||
blacklisted = 1
|
||||
sexes = 0
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
|
||||
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
|
||||
mutant_organs = list(/obj/item/organ/tongue/bone)
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
disliked_food = NONE
|
||||
liked_food = NONE
|
||||
|
||||
@@ -118,4 +118,4 @@
|
||||
else
|
||||
return ..()
|
||||
else
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
say_mod = "moans"
|
||||
sexes = 0
|
||||
blacklisted = 1
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT)
|
||||
mutant_organs = list(/obj/item/organ/tongue/zombie)
|
||||
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
|
||||
disliked_food = NONE
|
||||
liked_food = NONE
|
||||
|
||||
/datum/species/zombie/infectious
|
||||
name = "Infectious Zombie"
|
||||
@@ -52,5 +54,5 @@
|
||||
id = "goofzombies"
|
||||
limbs_id = "zombie" //They look like zombies
|
||||
sexes = 0
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
mutant_organs = list(/obj/item/organ/tongue/zombie)
|
||||
|
||||
@@ -521,8 +521,21 @@ generate/load female uniform sprites matching all previously decided variables
|
||||
|
||||
. += "-[gender]"
|
||||
|
||||
|
||||
var/is_taur = FALSE
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(("taur" in H.dna.species.mutant_bodyparts) && (H.dna.features["taur"] != "None"))
|
||||
is_taur = TRUE
|
||||
|
||||
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
|
||||
if(istype(BP, /obj/item/bodypart/r_leg) || istype(BP, /obj/item/bodypart/l_leg))
|
||||
if(is_taur)
|
||||
continue
|
||||
|
||||
|
||||
. += "-[BP.body_zone]"
|
||||
if(BP.status == BODYPART_ORGANIC)
|
||||
. += "-organic"
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
put_in_hands(I)
|
||||
update_inv_hands()
|
||||
if(slot_in_backpack)
|
||||
var/obj/item/weapon/storage/B = back
|
||||
var/obj/item/storage/B = back
|
||||
var/prev_jimmies = B.rustle_jimmies
|
||||
B.rustle_jimmies = FALSE //don't conspicously rustle
|
||||
B.handle_item_insertion(I, 1, src)
|
||||
@@ -95,24 +95,30 @@
|
||||
|
||||
if(I == head)
|
||||
head = null
|
||||
head_update(I)
|
||||
if(!QDELETED(src))
|
||||
head_update(I)
|
||||
else if(I == back)
|
||||
back = null
|
||||
update_inv_back()
|
||||
if(!QDELETED(src))
|
||||
update_inv_back()
|
||||
else if(I == wear_mask)
|
||||
wear_mask = null
|
||||
wear_mask_update(I, toggle_off = 1)
|
||||
if(!QDELETED(src))
|
||||
wear_mask_update(I, toggle_off = 1)
|
||||
if(I == wear_neck)
|
||||
wear_neck = null
|
||||
update_inv_neck(I)
|
||||
if(!QDELETED(src))
|
||||
update_inv_neck(I)
|
||||
else if(I == handcuffed)
|
||||
handcuffed = null
|
||||
if(buckled && buckled.buckle_requires_restraints)
|
||||
buckled.unbuckle_mob(src)
|
||||
update_handcuffed()
|
||||
if(!QDELETED(src))
|
||||
update_handcuffed()
|
||||
else if(I == legcuffed)
|
||||
legcuffed = null
|
||||
update_inv_legcuffed()
|
||||
if(!QDELETED(src))
|
||||
update_inv_legcuffed()
|
||||
|
||||
//handle stuff to update when a mob equips/unequips a mask.
|
||||
/mob/living/proc/wear_mask_update(obj/item/clothing/C, toggle_off = 1)
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
return
|
||||
if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
return
|
||||
if(istype(loc, /obj/item/device/dogborg/sleeper))
|
||||
return
|
||||
if(ismob(loc))
|
||||
return
|
||||
var/datum/gas_mixture/environment
|
||||
@@ -214,7 +216,7 @@
|
||||
if(internal.loc != src)
|
||||
internal = null
|
||||
update_internals_hud_icon(0)
|
||||
else if ((!wear_mask || !(wear_mask.flags & MASKINTERNALS)) && !getorganslot("breathing_tube"))
|
||||
else if ((!wear_mask || !(wear_mask.flags_1 & MASKINTERNALS_1)) && !getorganslot("breathing_tube"))
|
||||
internal = null
|
||||
update_internals_hud_icon(0)
|
||||
else
|
||||
@@ -431,4 +433,3 @@
|
||||
adjustToxLoss(8)
|
||||
if(prob(30))
|
||||
to_chat(src, "<span class='notice'>You feel confused and nauseous...</span>")//actual symptoms of liver failure
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
// WEAPONS
|
||||
if(istype(I, /obj/item/weapon))
|
||||
var/obj/item/weapon/W = I
|
||||
var/obj/item/W = I
|
||||
if(W.force >= best_force)
|
||||
put_in_hands(W)
|
||||
best_force = W.force
|
||||
@@ -153,7 +153,7 @@
|
||||
if(!locate(/obj/item/weapon) in held_items)
|
||||
best_force = 0
|
||||
|
||||
if(restrained() || blacklistItems[pickupTarget] || (pickupTarget && (pickupTarget.flags & NODROP)))
|
||||
if(restrained() || blacklistItems[pickupTarget] || (pickupTarget && (pickupTarget.flags_1 & NODROP_1)))
|
||||
pickupTarget = null
|
||||
|
||||
if(!resisting && pickupTarget)
|
||||
@@ -245,7 +245,7 @@
|
||||
|
||||
// pickup any nearby weapon
|
||||
if(!pickupTarget && prob(MONKEY_WEAPON_PROB))
|
||||
var/obj/item/weapon/W = locate(/obj/item/weapon/) in oview(2,src)
|
||||
var/obj/item/W = locate(/obj/item/) in oview(2,src)
|
||||
if(W && !blacklistItems[W] && W.force > best_force)
|
||||
pickupTarget = W
|
||||
|
||||
@@ -272,9 +272,9 @@
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
|
||||
// check if target has a weapon
|
||||
var/obj/item/weapon/W
|
||||
for(var/obj/item/weapon/I in target.held_items)
|
||||
if(!(I.flags & ABSTRACT))
|
||||
var/obj/item/W
|
||||
for(var/obj/item/I in target.held_items)
|
||||
if(!(I.flags_1 & ABSTRACT_1))
|
||||
W = I
|
||||
break
|
||||
|
||||
@@ -388,7 +388,7 @@
|
||||
|
||||
// attack using a held weapon otherwise bite the enemy, then if we are angry there is a chance we might calm down a little
|
||||
/mob/living/carbon/monkey/proc/monkey_attack(mob/living/L)
|
||||
var/obj/item/weapon/Weapon = locate(/obj/item/weapon) in held_items
|
||||
var/obj/item/Weapon = locate(/obj/item/weapon) in held_items
|
||||
|
||||
// attack with weapon if we have one
|
||||
if(Weapon)
|
||||
@@ -439,7 +439,7 @@
|
||||
retaliate(L)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/monkey/attackby(obj/item/weapon/W, mob/user, params)
|
||||
/mob/living/carbon/monkey/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if((W.force) && (!target) && (W.damtype != STAMINA) )
|
||||
retaliate(user)
|
||||
|
||||
@@ -1,170 +1,173 @@
|
||||
|
||||
|
||||
/mob/living/carbon/monkey
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/Life()
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if (notransform)
|
||||
return
|
||||
|
||||
if(..())
|
||||
|
||||
if(!client)
|
||||
if(stat == CONSCIOUS)
|
||||
if(!handle_combat())
|
||||
if(prob(33) && canmove && isturf(loc) && !pulledby)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/Life()
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if (notransform)
|
||||
return
|
||||
|
||||
if(..())
|
||||
|
||||
if(!client)
|
||||
if(stat == CONSCIOUS)
|
||||
if(!handle_combat())
|
||||
if(prob(33) && canmove && isturf(loc) && !pulledby)
|
||||
step(src, pick(GLOB.cardinals))
|
||||
if(prob(1))
|
||||
emote(pick("scratch","jump","roll","tail"))
|
||||
else
|
||||
walk_to(src,0)
|
||||
|
||||
/mob/living/carbon/monkey/handle_mutations_and_radiation()
|
||||
|
||||
if (radiation)
|
||||
if (radiation > 100)
|
||||
if(!IsKnockdown())
|
||||
emote("collapse")
|
||||
Knockdown(200)
|
||||
to_chat(src, "<span class='danger'>You feel weak.</span>")
|
||||
|
||||
switch(radiation)
|
||||
|
||||
if(50 to 75)
|
||||
if(prob(5))
|
||||
if(!IsKnockdown())
|
||||
emote("collapse")
|
||||
Knockdown(60)
|
||||
to_chat(src, "<span class='danger'>You feel weak.</span>")
|
||||
|
||||
if(75 to 100)
|
||||
if(prob(1))
|
||||
to_chat(src, "<span class='danger'>You mutate!</span>")
|
||||
randmutb()
|
||||
emote("gasp")
|
||||
domutcheck()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/handle_breath_temperature(datum/gas_mixture/breath)
|
||||
if(abs(310.15 - breath.temperature) > 50)
|
||||
switch(breath.temperature)
|
||||
if(-INFINITY to 120)
|
||||
adjustFireLoss(3)
|
||||
if(120 to 200)
|
||||
adjustFireLoss(1.5)
|
||||
if(200 to 260)
|
||||
adjustFireLoss(0.5)
|
||||
if(360 to 400)
|
||||
adjustFireLoss(2)
|
||||
if(400 to 1000)
|
||||
adjustFireLoss(3)
|
||||
if(1000 to INFINITY)
|
||||
adjustFireLoss(8)
|
||||
|
||||
/mob/living/carbon/monkey/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
return
|
||||
|
||||
var/loc_temp = get_temperature(environment)
|
||||
|
||||
if(stat != DEAD)
|
||||
natural_bodytemperature_stabilization()
|
||||
|
||||
if(!on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases
|
||||
if(loc_temp < bodytemperature)
|
||||
bodytemperature += min(((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX)
|
||||
else
|
||||
bodytemperature += min(((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)
|
||||
|
||||
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
|
||||
switch(bodytemperature)
|
||||
if(360 to 400)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 1)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
|
||||
if(400 to 460)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 2)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
if(460 to INFINITY)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 3)
|
||||
if(on_fire)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
|
||||
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
switch(bodytemperature)
|
||||
if(200 to 260)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 1)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_1, BURN)
|
||||
if(120 to 200)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 2)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_2, BURN)
|
||||
if(-INFINITY to 120)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 3)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
//Account for massive pressure differences
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
|
||||
switch(adjusted_pressure)
|
||||
if(HAZARD_HIGH_PRESSURE to INFINITY)
|
||||
adjustBruteLoss( min( ( (adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) )
|
||||
throw_alert("pressure", /obj/screen/alert/highpressure, 2)
|
||||
if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
|
||||
throw_alert("pressure", /obj/screen/alert/highpressure, 1)
|
||||
if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE)
|
||||
clear_alert("pressure")
|
||||
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
|
||||
throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
|
||||
else
|
||||
adjustBruteLoss( LOW_PRESSURE_DAMAGE )
|
||||
throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
|
||||
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/handle_random_events()
|
||||
if (prob(1) && prob(2))
|
||||
emote("scratch")
|
||||
|
||||
/mob/living/carbon/monkey/has_smoke_protection()
|
||||
if(wear_mask)
|
||||
if(wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/monkey/handle_fire()
|
||||
. = ..()
|
||||
if(on_fire)
|
||||
|
||||
//the fire tries to damage the exposed clothes and items
|
||||
var/list/burning_items = list()
|
||||
//HEAD//
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
head_clothes = wear_neck
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
burning_items += head_clothes
|
||||
|
||||
if(back)
|
||||
burning_items += back
|
||||
|
||||
for(var/X in burning_items)
|
||||
var/obj/item/I = X
|
||||
if(!(I.resistance_flags & FIRE_PROOF))
|
||||
I.take_damage(fire_stacks, BURN, "fire", 0)
|
||||
|
||||
bodytemperature += BODYTEMP_HEATING_MAX
|
||||
|
||||
if(prob(1))
|
||||
emote(pick("scratch","jump","roll","tail"))
|
||||
else
|
||||
walk_to(src,0)
|
||||
|
||||
/mob/living/carbon/monkey/handle_mutations_and_radiation()
|
||||
|
||||
if (radiation)
|
||||
if (radiation > 100)
|
||||
if(!IsKnockdown())
|
||||
emote("collapse")
|
||||
Knockdown(200)
|
||||
to_chat(src, "<span class='danger'>You feel weak.</span>")
|
||||
if(radiation > 30 && prob((radiation - 30) * (radiation - 30) * 0.00002))
|
||||
gorillize()
|
||||
return
|
||||
switch(radiation)
|
||||
|
||||
if(50 to 75)
|
||||
if(prob(5))
|
||||
if(!IsKnockdown())
|
||||
emote("collapse")
|
||||
Knockdown(60)
|
||||
to_chat(src, "<span class='danger'>You feel weak.</span>")
|
||||
|
||||
if(75 to 100)
|
||||
if(prob(1))
|
||||
to_chat(src, "<span class='danger'>You mutate!</span>")
|
||||
randmutb()
|
||||
emote("gasp")
|
||||
domutcheck()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/handle_breath_temperature(datum/gas_mixture/breath)
|
||||
if(abs(310.15 - breath.temperature) > 50)
|
||||
switch(breath.temperature)
|
||||
if(-INFINITY to 120)
|
||||
adjustFireLoss(3)
|
||||
if(120 to 200)
|
||||
adjustFireLoss(1.5)
|
||||
if(200 to 260)
|
||||
adjustFireLoss(0.5)
|
||||
if(360 to 400)
|
||||
adjustFireLoss(2)
|
||||
if(400 to 1000)
|
||||
adjustFireLoss(3)
|
||||
if(1000 to INFINITY)
|
||||
adjustFireLoss(8)
|
||||
|
||||
/mob/living/carbon/monkey/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
return
|
||||
|
||||
var/loc_temp = get_temperature(environment)
|
||||
|
||||
if(stat != DEAD)
|
||||
natural_bodytemperature_stabilization()
|
||||
|
||||
if(!on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases
|
||||
if(loc_temp < bodytemperature)
|
||||
bodytemperature += min(((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX)
|
||||
else
|
||||
bodytemperature += min(((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)
|
||||
|
||||
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
|
||||
switch(bodytemperature)
|
||||
if(360 to 400)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 1)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
|
||||
if(400 to 460)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 2)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
if(460 to INFINITY)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 3)
|
||||
if(on_fire)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
|
||||
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
switch(bodytemperature)
|
||||
if(200 to 260)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 1)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_1, BURN)
|
||||
if(120 to 200)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 2)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_2, BURN)
|
||||
if(-INFINITY to 120)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 3)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
//Account for massive pressure differences
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
|
||||
switch(adjusted_pressure)
|
||||
if(HAZARD_HIGH_PRESSURE to INFINITY)
|
||||
adjustBruteLoss( min( ( (adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) )
|
||||
throw_alert("pressure", /obj/screen/alert/highpressure, 2)
|
||||
if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
|
||||
throw_alert("pressure", /obj/screen/alert/highpressure, 1)
|
||||
if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE)
|
||||
clear_alert("pressure")
|
||||
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
|
||||
throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
|
||||
else
|
||||
adjustBruteLoss( LOW_PRESSURE_DAMAGE )
|
||||
throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
|
||||
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/handle_random_events()
|
||||
if (prob(1) && prob(2))
|
||||
emote("scratch")
|
||||
|
||||
/mob/living/carbon/monkey/has_smoke_protection()
|
||||
if(wear_mask)
|
||||
|
||||
if(wear_mask.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/monkey/handle_fire()
|
||||
. = ..()
|
||||
if(on_fire)
|
||||
|
||||
//the fire tries to damage the exposed clothes and items
|
||||
var/list/burning_items = list()
|
||||
//HEAD//
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
head_clothes = wear_neck
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
burning_items += head_clothes
|
||||
|
||||
if(back)
|
||||
burning_items += back
|
||||
|
||||
for(var/X in burning_items)
|
||||
var/obj/item/I = X
|
||||
if(!(I.resistance_flags & FIRE_PROOF))
|
||||
I.take_damage(fire_stacks, BURN, "fire", 0)
|
||||
|
||||
bodytemperature += BODYTEMP_HEATING_MAX
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
gender = NEUTER
|
||||
pass_flags = PASSTABLE
|
||||
ventcrawler = VENTCRAWLER_NUDE
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
|
||||
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/monkey
|
||||
gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
unique_name = 1
|
||||
bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey,
|
||||
@@ -105,11 +105,11 @@
|
||||
//Lasertag bullshit
|
||||
if(lasercolor)
|
||||
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag))
|
||||
if(is_holding_item_of_type(/obj/item/gun/energy/laser/redtag))
|
||||
threatcount += 4
|
||||
|
||||
if(lasercolor == "r")
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag))
|
||||
if(is_holding_item_of_type(/obj/item/gun/energy/laser/bluetag))
|
||||
threatcount += 4
|
||||
|
||||
return threatcount
|
||||
@@ -140,8 +140,8 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/monkey/can_use_guns(var/obj/item/weapon/G)
|
||||
return 1
|
||||
/mob/living/carbon/monkey/can_use_guns(obj/item/G)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/monkey/angry
|
||||
aggressive = TRUE
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
..()
|
||||
|
||||
//These have to be after the parent new to ensure that the monkey
|
||||
//bodyparts are actually created before we try to equip things to
|
||||
//bodyparts are actually created before we try to equip things to
|
||||
//those slots
|
||||
if(relic_hat)
|
||||
equip_to_slot_or_del(new relic_hat, slot_head)
|
||||
@@ -42,32 +42,40 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
|
||||
S["ancestor_name"] >> ancestor_name
|
||||
S["ancestor_chain"] >> ancestor_chain
|
||||
S["relic_hat"] >> relic_hat
|
||||
S["relic_mask"] >> relic_mask
|
||||
if(fexists("data/npc_saves/Punpun.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
|
||||
S["ancestor_name"] >> ancestor_name
|
||||
S["ancestor_chain"] >> ancestor_chain
|
||||
S["relic_hat"] >> relic_hat
|
||||
S["relic_mask"] >> relic_mask
|
||||
fdel("data/npc_saves/Punpun.sav")
|
||||
else
|
||||
var/json_file = file("data/npc_saves/Punpun.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
ancestor_name = json["ancestor_name"]
|
||||
ancestor_chain = json["ancestor_chain"]
|
||||
relic_hat = json["relic_hat"]
|
||||
relic_mask = json["relic_hat"]
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed)
|
||||
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
|
||||
var/json_file = file("data/npc_saves/Punpun.json")
|
||||
var/list/file_data = list()
|
||||
if(gibbed)
|
||||
WRITE_FILE(S["ancestor_name"], null)
|
||||
WRITE_FILE(S["ancestor_chain"], 1)
|
||||
WRITE_FILE(S["relic_hat"], null)
|
||||
WRITE_FILE(S["relic_mask"], null)
|
||||
return
|
||||
file_data["ancestor_name"] = null
|
||||
file_data["ancestor_chain"] = null
|
||||
file_data["relic_hat"] = null
|
||||
file_data["relic_mask"] = null
|
||||
if(dead)
|
||||
WRITE_FILE(S["ancestor_name"], ancestor_name)
|
||||
WRITE_FILE(S["ancestor_chain"], ancestor_chain + 1)
|
||||
if(!ancestor_name) //new monkey name this round
|
||||
WRITE_FILE(S["ancestor_name"], name)
|
||||
if(head)
|
||||
WRITE_FILE(S["relic_hat"], head.type)
|
||||
else
|
||||
WRITE_FILE(S["relic_hat"], null)
|
||||
if(wear_mask)
|
||||
WRITE_FILE(S["relic_mask"], wear_mask.type)
|
||||
else
|
||||
WRITE_FILE(S["relic_mask"], null)
|
||||
file_data["ancestor_name"] = ancestor_name
|
||||
file_data["ancestor_chain"] = ancestor_chain + 1
|
||||
file_data["relic_hat"] = head ? head.type : null
|
||||
file_data["relic_mask"] = wear_mask ? wear_mask.type : null
|
||||
if(!ancestor_name)
|
||||
file_data["ancestor_name"] = name
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(json_file))
|
||||
if(!dead)
|
||||
memory_saved = 1
|
||||
|
||||
@@ -34,4 +34,4 @@
|
||||
if(T)
|
||||
. = T.could_speak_in_language(dt)
|
||||
else
|
||||
. = initial(dt.flags) & TONGUELESS_SPEECH
|
||||
. = initial(dt.flags_1) & TONGUELESS_SPEECH
|
||||
|
||||
@@ -63,6 +63,17 @@
|
||||
clear_fullscreen("high")
|
||||
clear_alert("high")
|
||||
|
||||
/mob/living/carbon/adjust_disgust(amount)
|
||||
var/old_disgust = disgust
|
||||
if(amount>0)
|
||||
disgust = min(disgust+amount, DISGUST_LEVEL_MAXEDOUT)
|
||||
|
||||
else if(old_disgust)
|
||||
disgust = max(disgust+amount, 0)
|
||||
|
||||
/mob/living/carbon/set_disgust(amount)
|
||||
if(amount >= 0)
|
||||
disgust = amount
|
||||
|
||||
/mob/living/carbon/cure_blind()
|
||||
if(disabilities & BLIND)
|
||||
|
||||
@@ -234,11 +234,22 @@
|
||||
if(limb_icon_cache[icon_render_key])
|
||||
load_limb_from_cache()
|
||||
return
|
||||
//Taur code goes here, since humans just inherit this proc
|
||||
var/is_taur = FALSE
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(("taur" in H.dna.species.mutant_bodyparts) && (H.dna.features["taur"] != "None"))
|
||||
is_taur = TRUE
|
||||
|
||||
//GENERATE NEW LIMBS
|
||||
var/list/new_limbs = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
|
||||
if(istype(BP, /obj/item/bodypart/r_leg) || istype(BP, /obj/item/bodypart/l_leg))
|
||||
if(is_taur)
|
||||
continue
|
||||
|
||||
new_limbs += BP.get_limb_icon()
|
||||
if(new_limbs.len)
|
||||
overlays_standing[BODYPARTS_LAYER] = new_limbs
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
var/area/A = get_area(T)
|
||||
for(var/obj/item/I in contents)
|
||||
I.on_mob_death(src, gibbed)
|
||||
if(mind && mind.name && mind.active && (!(T.flags & NO_DEATHRATTLE)))
|
||||
if(mind && mind.name && mind.active && (!(T.flags_1 & NO_DEATHRATTLE_1)))
|
||||
var/rendered = "<span class='deadsay'><b>[mind.name]</b> has died at <b>[A.name]</b>.</span>"
|
||||
deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
|
||||
if(mind)
|
||||
@@ -61,6 +61,7 @@
|
||||
if(!gibbed)
|
||||
GLOB.dead_mob_list += src
|
||||
set_drugginess(0)
|
||||
set_disgust(0)
|
||||
SetSleeping(0, 0)
|
||||
blind_eyes(1)
|
||||
reset_perspective(null)
|
||||
|
||||
@@ -465,7 +465,6 @@
|
||||
/datum/emote/living/spin
|
||||
key = "spin"
|
||||
key_third_person = "spins"
|
||||
message = "spins around dizzily!"
|
||||
|
||||
/datum/emote/living/spin/run_emote(mob/user)
|
||||
user.spin(20, 1)
|
||||
@@ -486,7 +485,7 @@
|
||||
|
||||
/datum/emote/living/circle/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
var/obj/item/weapon/circlegame/N = new(user)
|
||||
var/obj/item/circlegame/N = new(user)
|
||||
if(user.put_in_hands(N))
|
||||
to_chat(user, "<span class='notice'>You make a circle with your hand.</span>")
|
||||
else
|
||||
|
||||
@@ -241,7 +241,7 @@
|
||||
return 1
|
||||
|
||||
/mob/living/proc/InCritical()
|
||||
return (health < 0 && health > -100 && stat == UNCONSCIOUS)
|
||||
return (health < HEALTH_THRESHOLD_CRIT && health > HEALTH_THRESHOLD_DEAD && stat == UNCONSCIOUS)
|
||||
|
||||
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
|
||||
//affects them once clothing is factored in. ~Errorage
|
||||
@@ -300,7 +300,7 @@
|
||||
update_canmove()
|
||||
|
||||
//Recursive function to find everything a mob is holding.
|
||||
/mob/living/get_contents(obj/item/weapon/storage/Storage = null)
|
||||
/mob/living/get_contents(obj/item/storage/Storage = null)
|
||||
var/list/L = list()
|
||||
|
||||
if(Storage) //If it called itself
|
||||
@@ -308,11 +308,11 @@
|
||||
return L
|
||||
else
|
||||
L += src.contents
|
||||
for(var/obj/item/weapon/storage/S in src.contents) //Check for storage items
|
||||
for(var/obj/item/storage/S in src.contents) //Check for storage items
|
||||
L += get_contents(S)
|
||||
for(var/obj/item/clothing/under/U in src.contents) //Check for jumpsuit accessories
|
||||
L += U.contents
|
||||
for(var/obj/item/weapon/folder/F in src.contents) //Check for folders
|
||||
for(var/obj/item/folder/F in src.contents) //Check for folders
|
||||
L += F.contents
|
||||
return L
|
||||
|
||||
@@ -374,6 +374,7 @@
|
||||
setBrainLoss(0)
|
||||
setStaminaLoss(0, 0)
|
||||
SetUnconscious(0, FALSE)
|
||||
set_disgust(0)
|
||||
SetStun(0, FALSE)
|
||||
SetKnockdown(0, FALSE)
|
||||
SetSleeping(0, FALSE)
|
||||
@@ -637,7 +638,7 @@
|
||||
// The src mob is trying to strip an item from someone
|
||||
// Override if a certain type of mob should be behave differently when stripping items (can't, for example)
|
||||
/mob/living/stripPanelUnequip(obj/item/what, mob/who, where)
|
||||
if(what.flags & NODROP)
|
||||
if(what.flags_1 & NODROP_1)
|
||||
to_chat(src, "<span class='warning'>You can't remove \the [what.name], it appears to be stuck!</span>")
|
||||
return
|
||||
who.visible_message("<span class='danger'>[src] tries to remove [who]'s [what.name].</span>", \
|
||||
@@ -658,7 +659,7 @@
|
||||
// Override if a certain mob should be behave differently when placing items (can't, for example)
|
||||
/mob/living/stripPanelEquip(obj/item/what, mob/who, where)
|
||||
what = src.get_active_held_item()
|
||||
if(what && (what.flags & NODROP))
|
||||
if(what && (what.flags_1 & NODROP_1))
|
||||
to_chat(src, "<span class='warning'>You can't put \the [what.name] on [who], it's stuck to your hand!</span>")
|
||||
return
|
||||
if(what)
|
||||
@@ -797,11 +798,11 @@
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
/mob/living/proc/can_use_guns(var/obj/item/weapon/G)
|
||||
/mob/living/proc/can_use_guns(obj/item/G)
|
||||
if (G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser())
|
||||
to_chat(src, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/proc/update_stamina()
|
||||
if(staminaloss)
|
||||
|
||||
@@ -67,17 +67,15 @@
|
||||
var/zone = ran_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()
|
||||
if(istype(I, /obj/item/weapon)) //If the item is a weapon...
|
||||
var/obj/item/weapon/W = I
|
||||
dtype = W.damtype
|
||||
dtype = I.damtype
|
||||
|
||||
if (W.throwforce > 0) //If the weapon's throwforce is greater than zero...
|
||||
if (W.throwhitsound) //...and throwhitsound is defined...
|
||||
playsound(loc, W.throwhitsound, volume, 1, -1) //...play the weapon's throwhitsound.
|
||||
else if(W.hitsound) //Otherwise, if the weapon's hitsound is defined...
|
||||
playsound(loc, W.hitsound, volume, 1, -1) //...play the weapon's hitsound.
|
||||
else if(!W.throwhitsound) //Otherwise, if throwhitsound isn't defined...
|
||||
playsound(loc, 'sound/weapons/genhit.ogg',volume, 1, -1) //...play genhit.ogg.
|
||||
if (I.throwforce > 0) //If the weapon's throwforce is greater than zero...
|
||||
if (I.throwhitsound) //...and throwhitsound is defined...
|
||||
playsound(loc, I.throwhitsound, volume, 1, -1) //...play the weapon's throwhitsound.
|
||||
else if(I.hitsound) //Otherwise, if the weapon's hitsound is defined...
|
||||
playsound(loc, I.hitsound, volume, 1, -1) //...play the weapon's hitsound.
|
||||
else if(!I.throwhitsound) //Otherwise, if throwhitsound isn't defined...
|
||||
playsound(loc, 'sound/weapons/genhit.ogg',volume, 1, -1) //...play genhit.ogg.
|
||||
|
||||
else if(!I.throwhitsound && I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', volume, 1, -1)//...play genhit.ogg
|
||||
@@ -280,7 +278,7 @@
|
||||
return 1
|
||||
|
||||
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
if(tesla_shock && HAS_SECONDARY_FLAG(src, TESLA_IGNORE))
|
||||
if(tesla_shock && (flags_2 & TESLA_IGNORE_2))
|
||||
return FALSE
|
||||
if(shock_damage > 0)
|
||||
if(!illusion)
|
||||
@@ -342,7 +340,7 @@
|
||||
return
|
||||
|
||||
if(stat != DEAD && !is_servant_of_ratvar(src))
|
||||
for(var/obj/item/weapon/implant/mindshield/M in implants)
|
||||
for(var/obj/item/implant/mindshield/M in implants)
|
||||
qdel(M)
|
||||
if(!add_servant_of_ratvar(src))
|
||||
to_chat(src, "<span class='userdanger'>A blinding light boils you alive! <i>Run!</i></span>")
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
if(nuking)
|
||||
set_security_level("red")
|
||||
nuking = FALSE
|
||||
for(var/obj/item/weapon/pinpointer/P in GLOB.pinpointer_list)
|
||||
for(var/obj/item/pinpointer/P in GLOB.pinpointer_list)
|
||||
P.switch_mode_to(TRACK_NUKE_DISK) //Party's over, back to work, everyone
|
||||
P.nuke_warning = FALSE
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
var/obj/machinery/camera/current = null
|
||||
icon = 'icons/mob/pai.dmi'
|
||||
icon_state = "repairbot"
|
||||
mouse_opacity = 2
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
density = FALSE
|
||||
luminosity = 0
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
@@ -24,7 +24,7 @@
|
||||
var/speakDoubleExclamation = "alarms"
|
||||
var/speakQuery = "queries"
|
||||
|
||||
var/obj/item/weapon/pai_cable/cable // The cable we produce and use when door or camera jacking
|
||||
var/obj/item/pai_cable/cable // The cable we produce and use when door or camera jacking
|
||||
|
||||
var/master // Name of the one who commands us
|
||||
var/master_dna // DNA string for owner verification
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
var/holoform = FALSE
|
||||
var/canholo = TRUE
|
||||
var/obj/item/weapon/card/id/access_card = null
|
||||
var/obj/item/card/id/access_card = null
|
||||
var/chassis = "repairbot"
|
||||
var/list/possible_chassis = list("cat", "mouse", "monkey", "corgi", "fox", "repairbot", "rabbit")
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
med.remove_hud_from(src)
|
||||
if("translator")
|
||||
if(href_list["toggle"])
|
||||
if(!HAS_SECONDARY_FLAG(src, OMNITONGUE))
|
||||
if(!(flags_2 & OMNITONGUE_2))
|
||||
grant_all_languages(TRUE)
|
||||
// this is PERMAMENT.
|
||||
if("doorjack")
|
||||
@@ -265,7 +265,7 @@
|
||||
src.hackdoor = null
|
||||
if(href_list["cable"])
|
||||
var/turf/T = get_turf(src.loc)
|
||||
cable = new /obj/item/weapon/pai_cable(T)
|
||||
cable = new /obj/item/pai_cable(T)
|
||||
T.visible_message("<span class='warning'>A port on [src] opens to reveal [src.cable], which promptly falls to the floor.</span>", "<span class='italics'>You hear the soft click of something light and hard falling to the ground.</span>")
|
||||
//src.updateUsrDialog() We only need to account for the single mob this is intended for, and he will *always* be able to call this window
|
||||
src.paiInterface() // So we'll just call the update directly rather than doing some default checks
|
||||
@@ -313,7 +313,7 @@
|
||||
if(s == "medical HUD")
|
||||
dat += "<a href='byond://?src=\ref[src];software=medicalhud;sub=0'>Medical Analysis Suite</a>[(src.medHUD) ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
|
||||
if(s == "universal translator")
|
||||
var/translator_on = HAS_SECONDARY_FLAG(src, OMNITONGUE)
|
||||
var/translator_on = (flags_2 & OMNITONGUE_2)
|
||||
dat += "<a href='byond://?src=\ref[src];software=translator;sub=0'>Universal Translator</a>[translator_on ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
|
||||
if(s == "projection array")
|
||||
dat += "<a href='byond://?src=\ref[src];software=projectionarray;sub=0'>Projection Array</a> <br>"
|
||||
@@ -465,7 +465,7 @@
|
||||
|
||||
// Universal Translator
|
||||
/mob/living/silicon/pai/proc/softwareTranslator()
|
||||
var/translator_on = HAS_SECONDARY_FLAG(src, OMNITONGUE)
|
||||
var/translator_on = (flags_2 & OMNITONGUE_2)
|
||||
. = {"<h3>Universal Translator</h3><br>
|
||||
When enabled, this device will permamently be able to speak and understand all known forms of communication.<br><br>
|
||||
The device is currently [translator_on ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>[translator_on ? "" : "<a href='byond://?src=\ref[src];software=translator;sub=0;toggle=1'>Activate Translation Module</a><br>"]"}
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
/mob/living/silicon/robot/proc/uneq_module(obj/item/O)
|
||||
if(!O)
|
||||
return 0
|
||||
O.mouse_opacity = 2
|
||||
O.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
if(istype(O, /obj/item/borg/sight))
|
||||
var/obj/item/borg/sight/S = O
|
||||
sight_mode &= ~S.sight_mode
|
||||
update_sight()
|
||||
else if(istype(O, /obj/item/weapon/storage/bag/tray/))
|
||||
var/obj/item/weapon/storage/bag/tray/T = O
|
||||
else if(istype(O, /obj/item/storage/bag/tray/))
|
||||
var/obj/item/storage/bag/tray/T = O
|
||||
T.do_quick_empty()
|
||||
else if(istype(O,/obj/item/weapon/gun/energy/laser/cyborg))
|
||||
else if(istype(O,/obj/item/gun/energy/laser/cyborg))
|
||||
laser = 0
|
||||
update_icons()
|
||||
else if(istype(O,/obj/item/weapon/gun/energy/disabler/cyborg))
|
||||
else if(istype(O,/obj/item/gun/energy/disabler/cyborg))
|
||||
disabler = 0
|
||||
update_icons()
|
||||
else if(istype(O,/obj/item/device/dogborg/sleeper))
|
||||
@@ -36,8 +36,8 @@
|
||||
observer_screen_update(O,FALSE)
|
||||
O.forceMove(module) //Return item to module so it appears in its contents, so it can be taken out again.
|
||||
|
||||
if(DROPDEL & O.flags)
|
||||
O.flags &= ~DROPDEL //we shouldn't HAVE things with DROPDEL in our modules, but better safe than runtiming horribly
|
||||
if(O.flags_1 & DROPDEL_1)
|
||||
O.flags_1 &= ~DROPDEL_1 //we shouldn't HAVE things with DROPDEL_1 in our modules, but better safe than runtiming horribly
|
||||
|
||||
O.dropped(src)
|
||||
|
||||
@@ -62,10 +62,10 @@
|
||||
if(activated(O))
|
||||
to_chat(src, "<span class='warning'>That module is already activated.</span>")
|
||||
return
|
||||
if(istype(O,/obj/item/weapon/gun/energy/laser/cyborg))
|
||||
if(istype(O,/obj/item/gun/energy/laser/cyborg))
|
||||
laser = 1
|
||||
update_icons()
|
||||
if(istype(O,/obj/item/weapon/gun/energy/disabler/cyborg))
|
||||
if(istype(O,/obj/item/gun/energy/disabler/cyborg))
|
||||
disabler = 1
|
||||
update_icons()
|
||||
if(!held_items[1])
|
||||
|
||||
@@ -34,14 +34,14 @@
|
||||
var/obj/screen/robot_modules_background
|
||||
|
||||
//3 Modules can be activated at any one time.
|
||||
var/obj/item/weapon/robot_module/module = null
|
||||
var/obj/item/robot_module/module = null
|
||||
var/obj/item/module_active = null
|
||||
held_items = list(null, null, null) //we use held_items for the module holding, because that makes sense to do!
|
||||
|
||||
var/mutable_appearance/eye_lights
|
||||
|
||||
var/mob/living/silicon/ai/connected_ai = null
|
||||
var/obj/item/weapon/stock_parts/cell/cell = null
|
||||
var/obj/item/stock_parts/cell/cell = null
|
||||
|
||||
var/opened = 0
|
||||
var/emagged = FALSE
|
||||
@@ -115,7 +115,7 @@
|
||||
ident = rand(1, 999)
|
||||
|
||||
if(!cell)
|
||||
cell = new /obj/item/weapon/stock_parts/cell(src)
|
||||
cell = new /obj/item/stock_parts/cell(src)
|
||||
cell.maxcharge = 7500
|
||||
cell.charge = 7500
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
builtInCamera.network = list("SS13")
|
||||
if(wires.is_cut(WIRE_CAMERA))
|
||||
builtInCamera.status = 0
|
||||
module = new /obj/item/weapon/robot_module(src)
|
||||
module = new /obj/item/robot_module(src)
|
||||
module.rebuild_modules()
|
||||
update_icons()
|
||||
. = ..()
|
||||
@@ -194,29 +194,29 @@
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/pick_module()
|
||||
if(module.type != /obj/item/weapon/robot_module)
|
||||
if(module.type != /obj/item/robot_module)
|
||||
return
|
||||
|
||||
if(wires.is_cut(WIRE_RESET_MODULE))
|
||||
to_chat(src,"<span class='userdanger'>ERROR: Module installer reply timeout. Please check internal connections.</span>")
|
||||
return
|
||||
|
||||
var/list/modulelist = list("Standard" = /obj/item/weapon/robot_module/standard, \
|
||||
"Engineering" = /obj/item/weapon/robot_module/engineering, \
|
||||
"Medical" = /obj/item/weapon/robot_module/medical, \
|
||||
"Miner" = /obj/item/weapon/robot_module/miner, \
|
||||
"Janitor" = /obj/item/weapon/robot_module/janitor, \
|
||||
"Service" = /obj/item/weapon/robot_module/butler, \
|
||||
"MediHound" = /obj/item/weapon/robot_module/medihound, \
|
||||
"Security K9" = /obj/item/weapon/robot_module/k9, \
|
||||
"Scrub Puppy" = /obj/item/weapon/robot_module/scrubpup)
|
||||
var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \
|
||||
"Engineering" = /obj/item/robot_module/engineering, \
|
||||
"Medical" = /obj/item/robot_module/medical, \
|
||||
"Miner" = /obj/item/robot_module/miner, \
|
||||
"Janitor" = /obj/item/robot_module/janitor, \
|
||||
"Service" = /obj/item/robot_module/butler, \
|
||||
"MediHound" = /obj/item/robot_module/medihound, \
|
||||
"Security K9" = /obj/item/robot_module/k9, \
|
||||
"Scrub Puppy" = /obj/item/robot_module/scrubpup)
|
||||
if(!config.forbid_peaceborg)
|
||||
modulelist["Peacekeeper"] = /obj/item/weapon/robot_module/peacekeeper
|
||||
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
|
||||
if(!config.forbid_secborg)
|
||||
modulelist["Security"] = /obj/item/weapon/robot_module/security
|
||||
modulelist["Security"] = /obj/item/robot_module/security
|
||||
|
||||
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist
|
||||
if(!input_module || module.type != /obj/item/weapon/robot_module)
|
||||
if(!input_module || module.type != /obj/item/robot_module)
|
||||
return
|
||||
|
||||
module.transform_to(modulelist[input_module])
|
||||
@@ -367,10 +367,10 @@
|
||||
queueAlarm("--- [class] alarm in [A.name] has been cleared.", class, 0)
|
||||
return !cleared
|
||||
|
||||
/mob/living/silicon/robot/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && (user.a_intent != INTENT_HARM || user == src))
|
||||
/mob/living/silicon/robot/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weldingtool) && (user.a_intent != INTENT_HARM || user == src))
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
var/obj/item/weldingtool/WT = W
|
||||
if (!getBruteLoss())
|
||||
to_chat(user, "<span class='warning'>[src] is already in good condition!</span>")
|
||||
return
|
||||
@@ -407,7 +407,7 @@
|
||||
else
|
||||
to_chat(user, "The wires seem fine, there's no need to fix them.")
|
||||
|
||||
else if(istype(W, /obj/item/weapon/crowbar)) // crowbar means open or close the cover
|
||||
else if(istype(W, /obj/item/crowbar)) // crowbar means open or close the cover
|
||||
if(opened)
|
||||
to_chat(user, "<span class='notice'>You close the cover.</span>")
|
||||
opened = 0
|
||||
@@ -420,7 +420,7 @@
|
||||
opened = 1
|
||||
update_icons()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/stock_parts/cell) && opened) // trying to put a cell inside
|
||||
else if(istype(W, /obj/item/stock_parts/cell) && opened) // trying to put a cell inside
|
||||
if(wiresexposed)
|
||||
to_chat(user, "<span class='warning'>Close the cover first!</span>")
|
||||
else if(cell)
|
||||
@@ -440,12 +440,12 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't reach the wiring!</span>")
|
||||
|
||||
else if(istype(W, /obj/item/weapon/screwdriver) && opened && !cell) // haxing
|
||||
else if(istype(W, /obj/item/screwdriver) && opened && !cell) // haxing
|
||||
wiresexposed = !wiresexposed
|
||||
to_chat(user, "The wires have been [wiresexposed ? "exposed" : "unexposed"]")
|
||||
update_icons()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/screwdriver) && opened && cell) // radio
|
||||
else if(istype(W, /obj/item/screwdriver) && opened && cell) // radio
|
||||
if(shell)
|
||||
to_chat(user, "You cannot seem to open the radio compartment") //Prevent AI radio key theft
|
||||
else if(radio)
|
||||
@@ -454,7 +454,7 @@
|
||||
to_chat(user, "<span class='warning'>Unable to locate a radio!</span>")
|
||||
update_icons()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/wrench) && opened && !cell) //Deconstruction. The flashes break from the fall, to prevent this from being a ghetto reset module.
|
||||
else if(istype(W, /obj/item/wrench) && opened && !cell) //Deconstruction. The flashes break from the fall, to prevent this from being a ghetto reset module.
|
||||
if(!lockcharge)
|
||||
to_chat(user, "<span class='boldannounce'>[src]'s bolts spark! Maybe you should lock them down first!</span>")
|
||||
spark_system.start()
|
||||
@@ -466,8 +466,8 @@
|
||||
user.visible_message("[user] deconstructs [src]!", "<span class='notice'>You unfasten the securing bolts, and [src] falls to pieces!</span>")
|
||||
deconstruct()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/aiModule))
|
||||
var/obj/item/weapon/aiModule/MOD = W
|
||||
else if(istype(W, /obj/item/aiModule))
|
||||
var/obj/item/aiModule/MOD = W
|
||||
if(!opened)
|
||||
to_chat(user, "<span class='warning'>You need access to the robot's insides to do that!</span>")
|
||||
return
|
||||
@@ -495,7 +495,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Unable to locate a radio!</span>")
|
||||
|
||||
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card
|
||||
else if (istype(W, /obj/item/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card
|
||||
if(emagged)//still allow them to open the cover
|
||||
to_chat(user, "<span class='notice'>The interface seems slightly damaged.</span>")
|
||||
if(opened)
|
||||
@@ -570,7 +570,7 @@
|
||||
return check_access(george.get_active_held_item())
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/proc/check_access(obj/item/weapon/card/id/I)
|
||||
/mob/living/silicon/robot/proc/check_access(obj/item/card/id/I)
|
||||
if(!istype(req_access, /list)) //something's very wrong
|
||||
return 1
|
||||
|
||||
@@ -578,7 +578,7 @@
|
||||
if(!L.len) //no requirements
|
||||
return 1
|
||||
|
||||
if(!istype(I, /obj/item/weapon/card/id) && isitem(I))
|
||||
if(!istype(I, /obj/item/card/id) && isitem(I))
|
||||
I = I.GetID()
|
||||
|
||||
if(!I || !I.access) //not ID or no access
|
||||
@@ -825,7 +825,7 @@
|
||||
<b>You are armed with powerful offensive tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
|
||||
Your cyborg LMG will slowly produce ammunition from your power supply, and your operative pinpointer will find and locate fellow nuclear operatives. \
|
||||
<i>Help the operatives secure the disk at all costs!</i></b>"
|
||||
var/set_module = /obj/item/weapon/robot_module/syndicate
|
||||
var/set_module = /obj/item/robot_module/syndicate
|
||||
|
||||
/mob/living/silicon/robot/syndicate/Initialize()
|
||||
..()
|
||||
@@ -851,7 +851,7 @@
|
||||
Your defibrillator paddles can revive operatives through their hardsuits, or can be used on harm intent to shock enemies! \
|
||||
Your energy saw functions as a circular saw, but can be activated to deal more damage, and your operative pinpointer will find and locate fellow nuclear operatives. \
|
||||
<i>Help the operatives secure the disk at all costs!</i></b>"
|
||||
set_module = /obj/item/weapon/robot_module/syndicate_medical
|
||||
set_module = /obj/item/robot_module/syndicate_medical
|
||||
|
||||
/mob/living/silicon/robot/proc/notify_ai(notifytype, oldname, newname)
|
||||
if(!connected_ai)
|
||||
@@ -977,7 +977,7 @@
|
||||
shown_robot_modules = FALSE
|
||||
if(hud_used)
|
||||
hud_used.update_robot_modules_display()
|
||||
module.transform_to(/obj/item/weapon/robot_module)
|
||||
module.transform_to(/obj/item/robot_module)
|
||||
|
||||
// Remove upgrades.
|
||||
for(var/obj/item/I in upgrades)
|
||||
@@ -992,7 +992,7 @@
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/robot/proc/has_module()
|
||||
if(!module || module.type == /obj/item/weapon/robot_module)
|
||||
if(!module || module.type == /obj/item/robot_module)
|
||||
. = FALSE
|
||||
else
|
||||
. = TRUE
|
||||
@@ -1007,9 +1007,9 @@
|
||||
status_flags &= ~CANPUSH
|
||||
|
||||
if(module.clean_on_move)
|
||||
flags |= CLEAN_ON_MOVE
|
||||
flags_1 |= CLEAN_ON_MOVE_1
|
||||
else
|
||||
flags &= ~CLEAN_ON_MOVE
|
||||
flags_1 &= ~CLEAN_ON_MOVE_1
|
||||
|
||||
hat_offset = module.hat_offset
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/obj/item/weapon/robot_module
|
||||
/obj/item/robot_module
|
||||
name = "Default"
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "std_module"
|
||||
w_class = WEIGHT_CLASS_GIGANTIC
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
flags = CONDUCT
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
|
||||
var/list/basic_modules = list() //a list of paths, converted to a list of instances on New()
|
||||
var/list/emag_modules = list() //ditto
|
||||
@@ -34,7 +34,7 @@
|
||||
var/ride_allow_incapacitated = FALSE
|
||||
var/allow_riding = TRUE
|
||||
|
||||
/obj/item/weapon/robot_module/New()
|
||||
/obj/item/robot_module/New()
|
||||
..()
|
||||
for(var/i in basic_modules)
|
||||
var/obj/item/I = new i(src)
|
||||
@@ -49,7 +49,7 @@
|
||||
ratvar_modules += I
|
||||
ratvar_modules -= i
|
||||
|
||||
/obj/item/weapon/robot_module/Destroy()
|
||||
/obj/item/robot_module/Destroy()
|
||||
basic_modules.Cut()
|
||||
emag_modules.Cut()
|
||||
ratvar_modules.Cut()
|
||||
@@ -58,29 +58,29 @@
|
||||
storages.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/robot_module/emp_act(severity)
|
||||
/obj/item/robot_module/emp_act(severity)
|
||||
for(var/obj/O in modules)
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/robot_module/proc/get_usable_modules()
|
||||
/obj/item/robot_module/proc/get_usable_modules()
|
||||
. = modules.Copy()
|
||||
|
||||
/obj/item/weapon/robot_module/proc/get_inactive_modules()
|
||||
/obj/item/robot_module/proc/get_inactive_modules()
|
||||
. = list()
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
for(var/m in get_usable_modules())
|
||||
if(!(m in R.held_items))
|
||||
. += m
|
||||
|
||||
/obj/item/weapon/robot_module/proc/get_or_create_estorage(var/storage_type)
|
||||
/obj/item/robot_module/proc/get_or_create_estorage(var/storage_type)
|
||||
for(var/datum/robot_energy_storage/S in storages)
|
||||
if(istype(S, storage_type))
|
||||
return S
|
||||
|
||||
return new storage_type(src)
|
||||
|
||||
/obj/item/weapon/robot_module/proc/add_module(obj/item/I, nonstandard, requires_rebuild)
|
||||
/obj/item/robot_module/proc/add_module(obj/item/I, nonstandard, requires_rebuild)
|
||||
if(istype(I, /obj/item/stack))
|
||||
var/obj/item/stack/S = I
|
||||
|
||||
@@ -114,22 +114,22 @@
|
||||
S.materials = list()
|
||||
S.is_cyborg = 1
|
||||
|
||||
if(istype(I, /obj/item/weapon/restraints/handcuffs/cable))
|
||||
var/obj/item/weapon/restraints/handcuffs/cable/C = I
|
||||
if(istype(I, /obj/item/restraints/handcuffs/cable))
|
||||
var/obj/item/restraints/handcuffs/cable/C = I
|
||||
C.wirestorage = get_or_create_estorage(/datum/robot_energy_storage/wire)
|
||||
|
||||
if(I.loc != src)
|
||||
I.forceMove(src)
|
||||
modules += I
|
||||
I.flags |= NODROP
|
||||
I.mouse_opacity = 2
|
||||
I.flags_1 |= NODROP_1
|
||||
I.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
if(nonstandard)
|
||||
added_modules += I
|
||||
if(requires_rebuild)
|
||||
rebuild_modules()
|
||||
return I
|
||||
|
||||
/obj/item/weapon/robot_module/proc/remove_module(obj/item/I, delete_after)
|
||||
/obj/item/robot_module/proc/remove_module(obj/item/I, delete_after)
|
||||
basic_modules -= I
|
||||
modules -= I
|
||||
emag_modules -= I
|
||||
@@ -139,7 +139,7 @@
|
||||
if(delete_after)
|
||||
qdel(I)
|
||||
|
||||
/obj/item/weapon/robot_module/proc/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
/obj/item/robot_module/proc/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
for(var/datum/robot_energy_storage/st in storages)
|
||||
st.energy = min(st.max_energy, st.energy + coeff * st.recharge_rate)
|
||||
|
||||
@@ -149,18 +149,18 @@
|
||||
F.times_used = 0
|
||||
F.crit_fail = 0
|
||||
F.update_icon()
|
||||
else if(istype(I, /obj/item/weapon/melee/baton))
|
||||
var/obj/item/weapon/melee/baton/B = I
|
||||
else if(istype(I, /obj/item/melee/baton))
|
||||
var/obj/item/melee/baton/B = I
|
||||
if(B.cell)
|
||||
B.cell.charge = B.cell.maxcharge
|
||||
else if(istype(I, /obj/item/weapon/gun/energy))
|
||||
var/obj/item/weapon/gun/energy/EG = I
|
||||
else if(istype(I, /obj/item/gun/energy))
|
||||
var/obj/item/gun/energy/EG = I
|
||||
if(!EG.chambered)
|
||||
EG.recharge_newshot() //try to reload a new shot.
|
||||
|
||||
R.toner = R.tonermax
|
||||
|
||||
/obj/item/weapon/robot_module/proc/rebuild_modules() //builds the usable module list from the modules we have
|
||||
/obj/item/robot_module/proc/rebuild_modules() //builds the usable module list from the modules we have
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/held_modules = R.held_items.Copy()
|
||||
R.uneq_all()
|
||||
@@ -181,9 +181,9 @@
|
||||
if(R.hud_used)
|
||||
R.hud_used.update_robot_modules_display()
|
||||
|
||||
/obj/item/weapon/robot_module/proc/transform_to(new_module_type)
|
||||
/obj/item/robot_module/proc/transform_to(new_module_type)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/obj/item/weapon/robot_module/RM = new new_module_type(R)
|
||||
var/obj/item/robot_module/RM = new new_module_type(R)
|
||||
if(!RM.be_transformed_to(src))
|
||||
qdel(RM)
|
||||
return
|
||||
@@ -194,14 +194,14 @@
|
||||
qdel(src)
|
||||
return RM
|
||||
|
||||
/obj/item/weapon/robot_module/proc/be_transformed_to(obj/item/weapon/robot_module/old_module)
|
||||
/obj/item/robot_module/proc/be_transformed_to(obj/item/robot_module/old_module)
|
||||
for(var/i in old_module.added_modules)
|
||||
added_modules += i
|
||||
old_module.added_modules -= i
|
||||
did_feedback = old_module.did_feedback
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/robot_module/proc/do_transform_animation()
|
||||
/obj/item/robot_module/proc/do_transform_animation()
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
R.notransform = TRUE
|
||||
var/obj/effect/temp_visual/decoy/fading/fivesecond/ANM = new /obj/effect/temp_visual/decoy/fading/fivesecond(R.loc, R)
|
||||
@@ -230,25 +230,25 @@
|
||||
if(feedback_key && !did_feedback)
|
||||
SSblackbox.inc(feedback_key, 1)
|
||||
|
||||
/obj/item/weapon/robot_module/standard
|
||||
/obj/item/robot_module/standard
|
||||
name = "Standard"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/reagent_containers/borghypo/epi,
|
||||
/obj/item/reagent_containers/borghypo/epi,
|
||||
/obj/item/device/healthanalyzer,
|
||||
/obj/item/weapon/weldingtool/largetank/cyborg,
|
||||
/obj/item/weapon/wrench/cyborg,
|
||||
/obj/item/weapon/crowbar/cyborg,
|
||||
/obj/item/weldingtool/largetank/cyborg,
|
||||
/obj/item/wrench/cyborg,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/stack/sheet/metal/cyborg,
|
||||
/obj/item/stack/rods/cyborg,
|
||||
/obj/item/stack/tile/plasteel/cyborg,
|
||||
/obj/item/weapon/extinguisher,
|
||||
/obj/item/weapon/pickaxe,
|
||||
/obj/item/extinguisher,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/device/t_scanner/adv_mining_scanner,
|
||||
/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg,
|
||||
/obj/item/weapon/soap/nanotrasen,
|
||||
/obj/item/restraints/handcuffs/cable/zipties/cyborg,
|
||||
/obj/item/soap/nanotrasen,
|
||||
/obj/item/borg/cyborghug)
|
||||
emag_modules = list(/obj/item/weapon/melee/transforming/energy/sword/cyborg)
|
||||
emag_modules = list(/obj/item/melee/transforming/energy/sword/cyborg)
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg,
|
||||
/obj/item/clockwork/ratvarian_spear/cyborg,
|
||||
@@ -257,29 +257,29 @@
|
||||
feedback_key = "cyborg_standard"
|
||||
hat_offset = -3
|
||||
|
||||
/obj/item/weapon/robot_module/medical
|
||||
/obj/item/robot_module/medical
|
||||
name = "Medical"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/device/healthanalyzer,
|
||||
/obj/item/weapon/reagent_containers/borghypo,
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/large,
|
||||
/obj/item/weapon/reagent_containers/dropper,
|
||||
/obj/item/weapon/reagent_containers/syringe,
|
||||
/obj/item/weapon/surgical_drapes,
|
||||
/obj/item/weapon/retractor,
|
||||
/obj/item/weapon/hemostat,
|
||||
/obj/item/weapon/cautery,
|
||||
/obj/item/weapon/surgicaldrill,
|
||||
/obj/item/weapon/scalpel,
|
||||
/obj/item/weapon/circular_saw,
|
||||
/obj/item/weapon/extinguisher/mini,
|
||||
/obj/item/reagent_containers/borghypo,
|
||||
/obj/item/reagent_containers/glass/beaker/large,
|
||||
/obj/item/reagent_containers/dropper,
|
||||
/obj/item/reagent_containers/syringe,
|
||||
/obj/item/surgical_drapes,
|
||||
/obj/item/retractor,
|
||||
/obj/item/hemostat,
|
||||
/obj/item/cautery,
|
||||
/obj/item/surgicaldrill,
|
||||
/obj/item/scalpel,
|
||||
/obj/item/circular_saw,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/roller/robo,
|
||||
/obj/item/borg/cyborghug/medical,
|
||||
/obj/item/stack/medical/gauze/cyborg,
|
||||
/obj/item/weapon/organ_storage,
|
||||
/obj/item/organ_storage,
|
||||
/obj/item/borg/lollipop)
|
||||
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/hacked)
|
||||
emag_modules = list(/obj/item/reagent_containers/borghypo/hacked)
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg/medical,
|
||||
/obj/item/clockwork/ratvarian_spear/cyborg)
|
||||
@@ -289,19 +289,19 @@
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = 3
|
||||
|
||||
/obj/item/weapon/robot_module/engineering
|
||||
/obj/item/robot_module/engineering
|
||||
name = "Engineering"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/borg/sight/meson,
|
||||
/obj/item/weapon/construction/rcd/borg,
|
||||
/obj/item/weapon/pipe_dispenser,
|
||||
/obj/item/weapon/extinguisher,
|
||||
/obj/item/weapon/weldingtool/largetank/cyborg,
|
||||
/obj/item/weapon/screwdriver/cyborg,
|
||||
/obj/item/weapon/wrench/cyborg,
|
||||
/obj/item/weapon/crowbar/cyborg,
|
||||
/obj/item/weapon/wirecutters/cyborg,
|
||||
/obj/item/construction/rcd/borg,
|
||||
/obj/item/pipe_dispenser,
|
||||
/obj/item/extinguisher,
|
||||
/obj/item/weldingtool/largetank/cyborg,
|
||||
/obj/item/screwdriver/cyborg,
|
||||
/obj/item/wrench/cyborg,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/wirecutters/cyborg,
|
||||
/obj/item/device/multitool/cyborg,
|
||||
/obj/item/device/t_scanner,
|
||||
/obj/item/device/analyzer,
|
||||
@@ -323,15 +323,15 @@
|
||||
magpulsing = TRUE
|
||||
hat_offset = INFINITY // No hats
|
||||
|
||||
/obj/item/weapon/robot_module/security
|
||||
/obj/item/robot_module/security
|
||||
name = "Security"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg,
|
||||
/obj/item/weapon/melee/baton/loaded,
|
||||
/obj/item/weapon/gun/energy/disabler/cyborg,
|
||||
/obj/item/restraints/handcuffs/cable/zipties/cyborg,
|
||||
/obj/item/melee/baton/loaded,
|
||||
/obj/item/gun/energy/disabler/cyborg,
|
||||
/obj/item/clothing/mask/gas/sechailer/cyborg)
|
||||
emag_modules = list(/obj/item/weapon/gun/energy/laser/cyborg)
|
||||
emag_modules = list(/obj/item/gun/energy/laser/cyborg)
|
||||
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
|
||||
/obj/item/clockwork/ratvarian_spear/cyborg)
|
||||
cyborg_base_icon = "sec"
|
||||
@@ -340,23 +340,23 @@
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = 3
|
||||
|
||||
/obj/item/weapon/robot_module/security/do_transform_animation()
|
||||
/obj/item/robot_module/security/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc, "<span class='userdanger'>While you have picked the security module, you still have to follow your laws, NOT Space Law. \
|
||||
For Asimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
|
||||
|
||||
/obj/item/weapon/robot_module/k9
|
||||
/obj/item/robot_module/k9
|
||||
name = "Security K-9 Unit module"
|
||||
basic_modules = list(
|
||||
/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/dog,
|
||||
/obj/item/weapon/dogborg/jaws/big,
|
||||
/obj/item/weapon/dogborg/pounce,
|
||||
/obj/item/restraints/handcuffs/cable/zipties/cyborg/dog,
|
||||
/obj/item/dogborg/jaws/big,
|
||||
/obj/item/dogborg/pounce,
|
||||
/obj/item/clothing/mask/gas/sechailer/cyborg,
|
||||
/obj/item/weapon/soap/tongue,
|
||||
/obj/item/soap/tongue,
|
||||
/obj/item/device/analyzer/nose,
|
||||
/obj/item/device/dogborg/sleeper/K9,
|
||||
/obj/item/weapon/gun/energy/disabler/cyborg)
|
||||
emag_modules = list(/obj/item/weapon/gun/energy/laser/cyborg)
|
||||
/obj/item/gun/energy/disabler/cyborg)
|
||||
emag_modules = list(/obj/item/gun/energy/laser/cyborg)
|
||||
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
|
||||
/obj/item/clockwork/ratvarian_spear/cyborg)
|
||||
cyborg_base_icon = "k9"
|
||||
@@ -365,14 +365,14 @@
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = INFINITY
|
||||
|
||||
/obj/item/weapon/robot_module/k9/do_transform_animation()
|
||||
/obj/item/robot_module/k9/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc,"<span class='userdanger'>While you have picked the security-k9 module, you still have to follow your laws, NOT Space Law. \
|
||||
For Asimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
|
||||
|
||||
/obj/item/weapon/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
/obj/item/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
..()
|
||||
var/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg/T = locate(/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg) in basic_modules
|
||||
var/obj/item/gun/energy/e_gun/advtaser/cyborg/T = locate(/obj/item/gun/energy/e_gun/advtaser/cyborg) in basic_modules
|
||||
if(T)
|
||||
if(T.cell.charge < T.cell.maxcharge)
|
||||
var/obj/item/ammo_casing/energy/S = T.ammo_type[T.select]
|
||||
@@ -381,17 +381,17 @@
|
||||
else
|
||||
T.charge_tick = 0
|
||||
|
||||
/obj/item/weapon/robot_module/medihound
|
||||
/obj/item/robot_module/medihound
|
||||
name = "MediHound module"
|
||||
basic_modules = list(
|
||||
/obj/item/weapon/dogborg/jaws/small,
|
||||
/obj/item/dogborg/jaws/small,
|
||||
/obj/item/device/analyzer/nose,
|
||||
/obj/item/weapon/soap/tongue,
|
||||
/obj/item/soap/tongue,
|
||||
/obj/item/device/healthanalyzer,
|
||||
/obj/item/device/dogborg/sleeper,
|
||||
/obj/item/weapon/twohanded/shockpaddles/hound,
|
||||
/obj/item/twohanded/shockpaddles/hound,
|
||||
/obj/item/device/sensor_device)
|
||||
emag_modules = list(/obj/item/weapon/dogborg/pounce)
|
||||
emag_modules = list(/obj/item/dogborg/pounce)
|
||||
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical,
|
||||
/obj/item/clockwork/ratvarian_spear/cyborg)
|
||||
cyborg_base_icon = "medihound"
|
||||
@@ -400,21 +400,21 @@
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = INFINITY
|
||||
|
||||
/obj/item/weapon/robot_module/medihound/do_transform_animation()
|
||||
/obj/item/robot_module/medihound/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc, "<span class='userdanger'>Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \
|
||||
You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.</span>")
|
||||
|
||||
/obj/item/weapon/robot_module/scrubpup
|
||||
/obj/item/robot_module/scrubpup
|
||||
name = "Janitor"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/dogborg/jaws/small,
|
||||
/obj/item/dogborg/jaws/small,
|
||||
/obj/item/device/analyzer/nose,
|
||||
/obj/item/weapon/soap/tongue,
|
||||
/obj/item/soap/tongue,
|
||||
/obj/item/device/lightreplacer/cyborg,
|
||||
/obj/item/device/dogborg/sleeper/compactor)
|
||||
emag_modules = list(/obj/item/weapon/dogborg/pounce)
|
||||
emag_modules = list(/obj/item/dogborg/pounce)
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg/janitor,
|
||||
/obj/item/clockwork/replica_fabricator/cyborg)
|
||||
@@ -424,30 +424,30 @@
|
||||
hat_offset = INFINITY
|
||||
clean_on_move = TRUE
|
||||
|
||||
/obj/item/weapon/robot_module/scrubpup/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
/obj/item/robot_module/scrubpup/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
..()
|
||||
var/obj/item/device/lightreplacer/LR = locate(/obj/item/device/lightreplacer) in basic_modules
|
||||
if(LR)
|
||||
for(var/i in 1 to coeff)
|
||||
LR.Charge(R)
|
||||
|
||||
/obj/item/weapon/robot_module/scrubpup/do_transform_animation()
|
||||
/obj/item/robot_module/scrubpup/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc,"<span class='userdanger'>As tempting as it might be, do not begin binging on important items. Eat your garbage responsibly. People are not included under Garbage.</span>")
|
||||
|
||||
|
||||
/obj/item/weapon/robot_module/peacekeeper
|
||||
/obj/item/robot_module/peacekeeper
|
||||
name = "Peacekeeper"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/cookiesynth,
|
||||
/obj/item/cookiesynth,
|
||||
/obj/item/device/harmalarm,
|
||||
/obj/item/weapon/reagent_containers/borghypo/peace,
|
||||
/obj/item/weapon/holosign_creator/cyborg,
|
||||
/obj/item/reagent_containers/borghypo/peace,
|
||||
/obj/item/holosign_creator/cyborg,
|
||||
/obj/item/borg/cyborghug/peacekeeper,
|
||||
/obj/item/weapon/extinguisher,
|
||||
/obj/item/extinguisher,
|
||||
/obj/item/borg/projectile_dampen)
|
||||
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/peace/hacked)
|
||||
emag_modules = list(/obj/item/reagent_containers/borghypo/peace/hacked)
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg/peacekeeper,
|
||||
/obj/item/clockwork/ratvarian_spear/cyborg)
|
||||
@@ -457,26 +457,26 @@
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = -2
|
||||
|
||||
/obj/item/weapon/robot_module/peacekeeper/do_transform_animation()
|
||||
/obj/item/robot_module/peacekeeper/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc, "<span class='userdanger'>Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \
|
||||
You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.</span>")
|
||||
|
||||
/obj/item/weapon/robot_module/janitor
|
||||
/obj/item/robot_module/janitor
|
||||
name = "Janitor"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/screwdriver/cyborg,
|
||||
/obj/item/weapon/crowbar/cyborg,
|
||||
/obj/item/screwdriver/cyborg,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/stack/tile/plasteel/cyborg,
|
||||
/obj/item/weapon/soap/nanotrasen,
|
||||
/obj/item/weapon/storage/bag/trash/cyborg,
|
||||
/obj/item/weapon/extinguisher/mini,
|
||||
/obj/item/weapon/mop/cyborg,
|
||||
/obj/item/soap/nanotrasen,
|
||||
/obj/item/storage/bag/trash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/mop/cyborg,
|
||||
/obj/item/device/lightreplacer/cyborg,
|
||||
/obj/item/weapon/holosign_creator,
|
||||
/obj/item/weapon/reagent_containers/spray/cyborg_drying)
|
||||
emag_modules = list(/obj/item/weapon/reagent_containers/spray/cyborg_lube)
|
||||
/obj/item/holosign_creator,
|
||||
/obj/item/reagent_containers/spray/cyborg_drying)
|
||||
emag_modules = list(/obj/item/reagent_containers/spray/cyborg_lube)
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg/janitor,
|
||||
/obj/item/clockwork/replica_fabricator/cyborg)
|
||||
@@ -486,50 +486,50 @@
|
||||
hat_offset = -5
|
||||
clean_on_move = TRUE
|
||||
|
||||
/obj/item/weapon/reagent_containers/spray/cyborg_drying
|
||||
/obj/item/reagent_containers/spray/cyborg_drying
|
||||
name = "drying agent spray"
|
||||
color = "#A000A0"
|
||||
list_reagents = list("drying_agent" = 250)
|
||||
|
||||
/obj/item/weapon/reagent_containers/spray/cyborg_lube
|
||||
/obj/item/reagent_containers/spray/cyborg_lube
|
||||
name = "lube spray"
|
||||
list_reagents = list("lube" = 250)
|
||||
|
||||
/obj/item/weapon/robot_module/janitor/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
/obj/item/robot_module/janitor/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
..()
|
||||
var/obj/item/device/lightreplacer/LR = locate(/obj/item/device/lightreplacer) in basic_modules
|
||||
if(LR)
|
||||
for(var/i in 1 to coeff)
|
||||
LR.Charge(R)
|
||||
|
||||
var/obj/item/weapon/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/weapon/reagent_containers/spray/cyborg_drying) in basic_modules
|
||||
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)
|
||||
|
||||
var/obj/item/weapon/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/weapon/reagent_containers/spray/cyborg_lube) in emag_modules
|
||||
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)
|
||||
|
||||
/obj/item/weapon/robot_module/butler
|
||||
/obj/item/robot_module/butler
|
||||
name = "Service"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass,
|
||||
/obj/item/weapon/reagent_containers/food/condiment/enzyme,
|
||||
/obj/item/weapon/pen,
|
||||
/obj/item/reagent_containers/food/drinks/drinkingglass,
|
||||
/obj/item/reagent_containers/food/condiment/enzyme,
|
||||
/obj/item/pen,
|
||||
/obj/item/toy/crayon/spraycan/borg,
|
||||
/obj/item/weapon/extinguisher/mini,
|
||||
/obj/item/weapon/hand_labeler/borg,
|
||||
/obj/item/weapon/razor,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/hand_labeler/borg,
|
||||
/obj/item/razor,
|
||||
/obj/item/device/instrument/violin,
|
||||
/obj/item/device/instrument/guitar,
|
||||
/obj/item/weapon/rsf/cyborg,
|
||||
/obj/item/weapon/reagent_containers/dropper,
|
||||
/obj/item/weapon/lighter,
|
||||
/obj/item/weapon/storage/bag/tray,
|
||||
/obj/item/weapon/reagent_containers/borghypo/borgshaker,
|
||||
/obj/item/rsf/cyborg,
|
||||
/obj/item/reagent_containers/dropper,
|
||||
/obj/item/lighter,
|
||||
/obj/item/storage/bag/tray,
|
||||
/obj/item/reagent_containers/borghypo/borgshaker,
|
||||
/obj/item/borg/lollipop)
|
||||
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/borgshaker/hacked)
|
||||
emag_modules = list(/obj/item/reagent_containers/borghypo/borgshaker/hacked)
|
||||
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/service,
|
||||
/obj/item/borg/sight/xray/truesight_lens)
|
||||
moduleselect_icon = "service"
|
||||
@@ -537,13 +537,13 @@
|
||||
feedback_key = "cyborg_service"
|
||||
hat_offset = 0
|
||||
|
||||
/obj/item/weapon/robot_module/butler/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
/obj/item/robot_module/butler/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
..()
|
||||
var/obj/item/weapon/reagent_containers/O = locate(/obj/item/weapon/reagent_containers/food/condiment/enzyme) in basic_modules
|
||||
var/obj/item/reagent_containers/O = locate(/obj/item/reagent_containers/food/condiment/enzyme) in basic_modules
|
||||
if(O)
|
||||
O.reagents.add_reagent("enzyme", 2 * coeff)
|
||||
|
||||
/obj/item/weapon/robot_module/butler/be_transformed_to(obj/item/weapon/robot_module/old_module)
|
||||
/obj/item/robot_module/butler/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("Waitress", "Butler", "Tophat", "Kent", "Bro")
|
||||
if(!borg_icon)
|
||||
@@ -565,19 +565,19 @@
|
||||
hat_offset = INFINITY //He is already wearing a hat
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/robot_module/miner
|
||||
/obj/item/robot_module/miner
|
||||
name = "Miner"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/storage/bag/ore/cyborg,
|
||||
/obj/item/weapon/pickaxe/drill/cyborg,
|
||||
/obj/item/weapon/shovel,
|
||||
/obj/item/weapon/crowbar/cyborg,
|
||||
/obj/item/weapon/weldingtool/mini,
|
||||
/obj/item/weapon/extinguisher/mini,
|
||||
/obj/item/weapon/storage/bag/sheetsnatcher/borg,
|
||||
/obj/item/storage/bag/ore/cyborg,
|
||||
/obj/item/pickaxe/drill/cyborg,
|
||||
/obj/item/shovel,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/weldingtool/mini,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/storage/bag/sheetsnatcher/borg,
|
||||
/obj/item/device/t_scanner/adv_mining_scanner,
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg,
|
||||
/obj/item/gun/energy/kinetic_accelerator/cyborg,
|
||||
/obj/item/device/gps/cyborg,
|
||||
/obj/item/stack/marker_beacon)
|
||||
emag_modules = list(/obj/item/borg/stun)
|
||||
@@ -590,16 +590,16 @@
|
||||
feedback_key = "cyborg_miner"
|
||||
hat_offset = 0
|
||||
|
||||
/obj/item/weapon/robot_module/syndicate
|
||||
/obj/item/robot_module/syndicate
|
||||
name = "Syndicate Assault"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/melee/transforming/energy/sword/cyborg,
|
||||
/obj/item/weapon/gun/energy/printer,
|
||||
/obj/item/weapon/gun/ballistic/revolver/grenadelauncher/cyborg,
|
||||
/obj/item/weapon/card/emag,
|
||||
/obj/item/weapon/crowbar/cyborg,
|
||||
/obj/item/weapon/pinpointer/syndicate/cyborg)
|
||||
/obj/item/melee/transforming/energy/sword/cyborg,
|
||||
/obj/item/gun/energy/printer,
|
||||
/obj/item/gun/ballistic/revolver/grenadelauncher/cyborg,
|
||||
/obj/item/card/emag,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/pinpointer/syndicate/cyborg)
|
||||
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg/security,
|
||||
@@ -609,25 +609,25 @@
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = 3
|
||||
|
||||
/obj/item/weapon/robot_module/syndicate_medical
|
||||
/obj/item/robot_module/syndicate_medical
|
||||
name = "Syndicate Medical"
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/reagent_containers/borghypo/syndicate,
|
||||
/obj/item/weapon/twohanded/shockpaddles/syndicate,
|
||||
/obj/item/reagent_containers/borghypo/syndicate,
|
||||
/obj/item/twohanded/shockpaddles/syndicate,
|
||||
/obj/item/device/healthanalyzer,
|
||||
/obj/item/weapon/surgical_drapes,
|
||||
/obj/item/weapon/retractor,
|
||||
/obj/item/weapon/hemostat,
|
||||
/obj/item/weapon/cautery,
|
||||
/obj/item/weapon/scalpel,
|
||||
/obj/item/weapon/melee/transforming/energy/sword/cyborg/saw,
|
||||
/obj/item/surgical_drapes,
|
||||
/obj/item/retractor,
|
||||
/obj/item/hemostat,
|
||||
/obj/item/cautery,
|
||||
/obj/item/scalpel,
|
||||
/obj/item/melee/transforming/energy/sword/cyborg/saw,
|
||||
/obj/item/roller/robo,
|
||||
/obj/item/weapon/card/emag,
|
||||
/obj/item/weapon/crowbar/cyborg,
|
||||
/obj/item/weapon/pinpointer/syndicate/cyborg,
|
||||
/obj/item/card/emag,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/pinpointer/syndicate/cyborg,
|
||||
/obj/item/stack/medical/gauze/cyborg,
|
||||
/obj/item/weapon/gun/medbeam)
|
||||
/obj/item/gun/medbeam)
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg/medical,
|
||||
/obj/item/clockwork/ratvarian_spear/cyborg)
|
||||
@@ -642,7 +642,7 @@
|
||||
var/recharge_rate = 1000
|
||||
var/energy
|
||||
|
||||
/datum/robot_energy_storage/New(var/obj/item/weapon/robot_module/R = null)
|
||||
/datum/robot_energy_storage/New(var/obj/item/robot_module/R = null)
|
||||
energy = max_energy
|
||||
if(R)
|
||||
R.storages |= src
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
var/d_hud = DATA_HUD_DIAGNOSTIC //There is only one kind of diag hud
|
||||
|
||||
var/law_change_counter = 0
|
||||
var/obj/machinery/camera/builtInCamera = null
|
||||
var/updating = FALSE //portable camera camerachunk update
|
||||
var/obj/machinery/camera/builtInCamera = null
|
||||
var/updating = FALSE //portable camera camerachunk update
|
||||
|
||||
/mob/living/silicon/Initialize()
|
||||
. = ..()
|
||||
. = ..()
|
||||
GLOB.silicon_mobs += src
|
||||
var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
|
||||
diag_hud.add_to_hud(src)
|
||||
@@ -56,7 +56,7 @@
|
||||
/mob/living/silicon/Destroy()
|
||||
radio = null
|
||||
aicamera = null
|
||||
QDEL_NULL(builtInCamera)
|
||||
QDEL_NULL(builtInCamera)
|
||||
GLOB.silicon_mobs -= src
|
||||
return ..()
|
||||
|
||||
@@ -310,7 +310,7 @@
|
||||
else //For department channels, if any, given by the internal radio.
|
||||
for(var/key in GLOB.department_radio_keys)
|
||||
if(GLOB.department_radio_keys[key] == Autochan)
|
||||
radiomod = key
|
||||
radiomod = ":" + key
|
||||
break
|
||||
|
||||
to_chat(src, "<span class='notice'>Automatic announcements [Autochan == "None" ? "will not use the radio." : "set to [Autochan]."]</span>")
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
/mob/living/simple_animal/bot/Initialize()
|
||||
. = ..()
|
||||
access_card = new /obj/item/weapon/card/id(src)
|
||||
access_card = new /obj/item/card/id(src)
|
||||
//This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
|
||||
access_card.access += ACCESS_ROBOTICS
|
||||
set_custom_texts()
|
||||
@@ -241,14 +241,14 @@
|
||||
/mob/living/simple_animal/bot/interact(mob/user)
|
||||
show_controls(user)
|
||||
|
||||
/mob/living/simple_animal/bot/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
/mob/living/simple_animal/bot/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
if(!locked)
|
||||
open = !open
|
||||
to_chat(user, "<span class='notice'>The maintenance panel is now [open ? "opened" : "closed"].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The maintenance panel is locked.</span>")
|
||||
else if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))
|
||||
else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/device/pda))
|
||||
if(bot_core.allowed(user) && !open && !emagged)
|
||||
locked = !locked
|
||||
to_chat(user, "Controls are now [locked ? "locked." : "unlocked."]")
|
||||
@@ -261,7 +261,7 @@
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
else if(istype(W, /obj/item/device/paicard))
|
||||
insertpai(user, W)
|
||||
else if(istype(W, /obj/item/weapon/hemostat) && paicard)
|
||||
else if(istype(W, /obj/item/hemostat) && paicard)
|
||||
if(open)
|
||||
to_chat(user, "<span class='warning'>Close the access panel before manipulating the personality slot!</span>")
|
||||
else
|
||||
@@ -272,14 +272,14 @@
|
||||
ejectpai(user)
|
||||
else
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != INTENT_HARM)
|
||||
if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM)
|
||||
if(health >= maxHealth)
|
||||
to_chat(user, "<span class='warning'>[src] does not need a repair!</span>")
|
||||
return
|
||||
if(!open)
|
||||
to_chat(user, "<span class='warning'>Unable to repair with the maintenance panel closed!</span>")
|
||||
return
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
var/obj/item/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0, user))
|
||||
adjustHealth(-10)
|
||||
user.visible_message("[user] repairs [src]!","<span class='notice'>You repair [src].</span>")
|
||||
@@ -472,7 +472,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
to_chat(src, "<span class='noticebig'>Priority waypoint set by [icon2html(caller, src)] <b>[caller]</b>. Proceed to <b>[end_area.name]<\b>.")
|
||||
|
||||
//For giving the bot temporary all-access.
|
||||
var/obj/item/weapon/card/id/all_access = new /obj/item/weapon/card/id
|
||||
var/obj/item/card/id/all_access = new /obj/item/card/id
|
||||
var/datum/job/captain/All = new/datum/job/captain
|
||||
all_access.access = All.get_access()
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@
|
||||
text_dehack = "[name]'s software has been reset!"
|
||||
text_dehack_fail = "[name] does not seem to respond to your repair code!"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
/mob/living/simple_animal/bot/cleanbot/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/card/id)||istype(W, /obj/item/device/pda))
|
||||
if(bot_core.allowed(user) && !open && !emagged)
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [ locked ? "lock" : "unlock"] \the [src] behaviour controls.</span>")
|
||||
@@ -254,7 +254,7 @@
|
||||
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/weapon/reagent_containers/glass/bucket(Tsec)
|
||||
new /obj/item/reagent_containers/glass/bucket(Tsec)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//Bot Construction
|
||||
|
||||
//Cleanbot assembly
|
||||
/obj/item/weapon/bucket_sensor
|
||||
/obj/item/bucket_sensor
|
||||
desc = "It's a bucket. With a sensor attached."
|
||||
name = "proxy bucket"
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
@@ -13,7 +13,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/created_name = "Cleanbot"
|
||||
|
||||
/obj/item/weapon/bucket_sensor/attackby(obj/item/W, mob/user as mob, params)
|
||||
/obj/item/bucket_sensor/attackby(obj/item/W, mob/user as mob, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/bodypart/l_arm/robot) || istype(W, /obj/item/bodypart/r_arm/robot))
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
@@ -25,7 +25,7 @@
|
||||
to_chat(user, "<span class='notice'>You add the robot arm to the bucket and sensor assembly. Beep boop!</span>")
|
||||
qdel(src)
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pen))
|
||||
else if(istype(W, /obj/item/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
//Edbot Assembly
|
||||
|
||||
/obj/item/weapon/ed209_assembly
|
||||
/obj/item/ed209_assembly
|
||||
name = "\improper ED-209 assembly"
|
||||
desc = "Some sort of bizarre assembly."
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
@@ -45,10 +45,10 @@
|
||||
var/created_name = "ED-209 Security Robot" //To preserve the name if it's a unique securitron I guess
|
||||
var/lasercolor = ""
|
||||
|
||||
/obj/item/weapon/ed209_assembly/attackby(obj/item/weapon/W, mob/user, params)
|
||||
/obj/item/ed209_assembly/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
if(istype(W, /obj/item/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
@@ -91,8 +91,8 @@
|
||||
icon_state = "[lasercolor]ed209_shell"
|
||||
|
||||
if(3)
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(istype(W, /obj/item/weldingtool))
|
||||
var/obj/item/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0,user))
|
||||
build_step++
|
||||
name = "shielded frame assembly"
|
||||
@@ -149,15 +149,15 @@
|
||||
var/newname = ""
|
||||
switch(lasercolor)
|
||||
if("b")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/laser/bluetag))
|
||||
if(!istype(W, /obj/item/gun/energy/laser/bluetag))
|
||||
return
|
||||
newname = "bluetag ED-209 assembly"
|
||||
if("r")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/laser/redtag))
|
||||
if(!istype(W, /obj/item/gun/energy/laser/redtag))
|
||||
return
|
||||
newname = "redtag ED-209 assembly"
|
||||
if("")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/e_gun/advtaser))
|
||||
if(!istype(W, /obj/item/gun/energy/e_gun/advtaser))
|
||||
return
|
||||
newname = "taser ED-209 assembly"
|
||||
else
|
||||
@@ -172,7 +172,7 @@
|
||||
qdel(W)
|
||||
|
||||
if(8)
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
playsound(loc, W.usesound, 100, 1)
|
||||
to_chat(user, "<span class='notice'>You start attaching the gun to the frame...</span>")
|
||||
if(do_after(user, 40*W.toolspeed, 0, src, 1))
|
||||
@@ -181,7 +181,7 @@
|
||||
to_chat(user, "<span class='notice'>Taser gun attached.</span>")
|
||||
|
||||
if(9)
|
||||
if(istype(W, /obj/item/weapon/stock_parts/cell))
|
||||
if(istype(W, /obj/item/stock_parts/cell))
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
build_step++
|
||||
@@ -192,7 +192,7 @@
|
||||
qdel(src)
|
||||
|
||||
//Floorbot assemblies
|
||||
/obj/item/weapon/toolbox_tiles
|
||||
/obj/item/toolbox_tiles
|
||||
desc = "It's a toolbox with tiles sticking out the top"
|
||||
name = "tiles and toolbox"
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
@@ -204,7 +204,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/created_name = "Floorbot"
|
||||
|
||||
/obj/item/weapon/toolbox_tiles_sensor
|
||||
/obj/item/toolbox_tiles_sensor
|
||||
desc = "It's a toolbox with tiles sticking out the top and a sensor attached"
|
||||
name = "tiles, toolbox and sensor arrangement"
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
@@ -216,7 +216,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/created_name = "Floorbot"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical/attackby(obj/item/stack/tile/plasteel/T, mob/user, params)
|
||||
/obj/item/storage/toolbox/mechanical/attackby(obj/item/stack/tile/plasteel/T, mob/user, params)
|
||||
if(!istype(T, /obj/item/stack/tile/plasteel))
|
||||
..()
|
||||
return
|
||||
@@ -226,7 +226,7 @@
|
||||
if(T.use(10))
|
||||
if(user.s_active)
|
||||
user.s_active.close(user)
|
||||
var/obj/item/weapon/toolbox_tiles/B = new /obj/item/weapon/toolbox_tiles
|
||||
var/obj/item/toolbox_tiles/B = new /obj/item/toolbox_tiles
|
||||
user.put_in_hands(B)
|
||||
to_chat(user, "<span class='notice'>You add the tiles into the empty toolbox. They protrude from the top.</span>")
|
||||
qdel(src)
|
||||
@@ -234,17 +234,17 @@
|
||||
to_chat(user, "<span class='warning'>You need 10 floor tiles to start building a floorbot!</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/toolbox_tiles/attackby(obj/item/W, mob/user, params)
|
||||
/obj/item/toolbox_tiles/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(isprox(W))
|
||||
qdel(W)
|
||||
var/obj/item/weapon/toolbox_tiles_sensor/B = new /obj/item/weapon/toolbox_tiles_sensor()
|
||||
var/obj/item/toolbox_tiles_sensor/B = new /obj/item/toolbox_tiles_sensor()
|
||||
B.created_name = created_name
|
||||
user.put_in_hands(B)
|
||||
to_chat(user, "<span class='notice'>You add the sensor to the toolbox and tiles.</span>")
|
||||
qdel(src)
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pen))
|
||||
else if(istype(W, /obj/item/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
@@ -253,7 +253,7 @@
|
||||
|
||||
created_name = t
|
||||
|
||||
/obj/item/weapon/toolbox_tiles_sensor/attackby(obj/item/W, mob/user, params)
|
||||
/obj/item/toolbox_tiles_sensor/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/bodypart/l_arm/robot) || istype(W, /obj/item/bodypart/r_arm/robot))
|
||||
qdel(W)
|
||||
@@ -262,7 +262,7 @@
|
||||
A.name = created_name
|
||||
to_chat(user, "<span class='notice'>You add the robot arm to the odd looking toolbox assembly. Boop beep!</span>")
|
||||
qdel(src)
|
||||
else if(istype(W, /obj/item/weapon/pen))
|
||||
else if(istype(W, /obj/item/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
@@ -272,7 +272,7 @@
|
||||
created_name = t
|
||||
|
||||
//Medbot Assembly
|
||||
/obj/item/weapon/firstaid_arm_assembly
|
||||
/obj/item/firstaid_arm_assembly
|
||||
name = "incomplete medibot assembly"
|
||||
desc = "A first aid kit with a robot arm permanently grafted to it."
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
@@ -282,13 +282,13 @@
|
||||
var/skin = null //Same as medbot, set to tox or ointment for the respective kits.
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/weapon/firstaid_arm_assembly/New()
|
||||
/obj/item/firstaid_arm_assembly/New()
|
||||
..()
|
||||
spawn(5)
|
||||
if(skin)
|
||||
add_overlay("kit_skin_[skin]")
|
||||
|
||||
/obj/item/weapon/storage/firstaid/attackby(obj/item/bodypart/S, mob/user, params)
|
||||
/obj/item/storage/firstaid/attackby(obj/item/bodypart/S, mob/user, params)
|
||||
|
||||
if((!istype(S, /obj/item/bodypart/l_arm/robot)) && (!istype(S, /obj/item/bodypart/r_arm/robot)))
|
||||
return ..()
|
||||
@@ -298,14 +298,14 @@
|
||||
to_chat(user, "<span class='warning'>You need to empty [src] out first!</span>")
|
||||
return
|
||||
|
||||
var/obj/item/weapon/firstaid_arm_assembly/A = new /obj/item/weapon/firstaid_arm_assembly
|
||||
if(istype(src, /obj/item/weapon/storage/firstaid/fire))
|
||||
var/obj/item/firstaid_arm_assembly/A = new /obj/item/firstaid_arm_assembly
|
||||
if(istype(src, /obj/item/storage/firstaid/fire))
|
||||
A.skin = "ointment"
|
||||
else if(istype(src, /obj/item/weapon/storage/firstaid/toxin))
|
||||
else if(istype(src, /obj/item/storage/firstaid/toxin))
|
||||
A.skin = "tox"
|
||||
else if(istype(src, /obj/item/weapon/storage/firstaid/o2))
|
||||
else if(istype(src, /obj/item/storage/firstaid/o2))
|
||||
A.skin = "o2"
|
||||
else if(istype(src, /obj/item/weapon/storage/firstaid/brute))
|
||||
else if(istype(src, /obj/item/storage/firstaid/brute))
|
||||
A.skin = "brute"
|
||||
|
||||
qdel(S)
|
||||
@@ -314,9 +314,9 @@
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/weapon/firstaid_arm_assembly/attackby(obj/item/weapon/W, mob/user, params)
|
||||
/obj/item/firstaid_arm_assembly/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
if(istype(W, /obj/item/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
@@ -348,7 +348,7 @@
|
||||
qdel(src)
|
||||
|
||||
//Secbot Assembly
|
||||
/obj/item/weapon/secbot_assembly
|
||||
/obj/item/secbot_assembly
|
||||
name = "incomplete securitron assembly"
|
||||
desc = "Some sort of bizarre assembly made from a proximity sensor, helmet, and signaler."
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
@@ -372,24 +372,24 @@
|
||||
|
||||
if(S.secured)
|
||||
qdel(S)
|
||||
var/obj/item/weapon/secbot_assembly/A = new /obj/item/weapon/secbot_assembly
|
||||
var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly
|
||||
user.put_in_hands(A)
|
||||
to_chat(user, "<span class='notice'>You add the signaler to the helmet.</span>")
|
||||
qdel(src)
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/weapon/secbot_assembly/attackby(obj/item/I, mob/user, params)
|
||||
/obj/item/secbot_assembly/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/weapon/weldingtool))
|
||||
if(istype(I, /obj/item/weldingtool))
|
||||
if(!build_step)
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
var/obj/item/weldingtool/WT = I
|
||||
if(WT.remove_fuel(0, user))
|
||||
build_step++
|
||||
add_overlay("hs_hole")
|
||||
to_chat(user, "<span class='notice'>You weld a hole in [src]!</span>")
|
||||
else if(build_step == 1)
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
var/obj/item/weldingtool/WT = I
|
||||
if(WT.remove_fuel(0, user))
|
||||
build_step--
|
||||
cut_overlay("hs_hole")
|
||||
@@ -413,7 +413,7 @@
|
||||
add_overlay("hs_arm")
|
||||
qdel(I)
|
||||
|
||||
else if((istype(I, /obj/item/weapon/melee/baton)) && (build_step >= 3))
|
||||
else if((istype(I, /obj/item/melee/baton)) && (build_step >= 3))
|
||||
if(!user.temporarilyRemoveItemFromInventory(I))
|
||||
return
|
||||
build_step++
|
||||
@@ -424,7 +424,7 @@
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(I, /obj/item/weapon/pen))
|
||||
else if(istype(I, /obj/item/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
@@ -432,7 +432,7 @@
|
||||
return
|
||||
created_name = t
|
||||
|
||||
else if(istype(I, /obj/item/weapon/screwdriver))
|
||||
else if(istype(I, /obj/item/screwdriver))
|
||||
if(!build_step)
|
||||
new /obj/item/device/assembly/signaler(get_turf(src))
|
||||
new /obj/item/clothing/head/helmet/sec(get_turf(src))
|
||||
|
||||
@@ -179,11 +179,11 @@ Auto Patrol[]"},
|
||||
retaliate(H)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/attackby(obj/item/weapon/W, mob/user, params)
|
||||
/mob/living/simple_animal/bot/ed209/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
|
||||
if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
|
||||
return
|
||||
if(!istype(W, /obj/item/weapon/screwdriver) && (!target)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
|
||||
if(!istype(W, /obj/item/screwdriver) && (!target)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
|
||||
if(W.force && W.damtype != STAMINA)//If force is non-zero and damage type isn't stamina.
|
||||
retaliate(user)
|
||||
if(lasercolor)//To make up for the fact that lasertag bots don't hunt
|
||||
@@ -373,22 +373,22 @@ Auto Patrol[]"},
|
||||
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
var/obj/item/weapon/ed209_assembly/Sa = new /obj/item/weapon/ed209_assembly(Tsec)
|
||||
var/obj/item/ed209_assembly/Sa = new /obj/item/ed209_assembly(Tsec)
|
||||
Sa.build_step = 1
|
||||
Sa.add_overlay("hs_hole")
|
||||
Sa.created_name = name
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if(!lasercolor)
|
||||
var/obj/item/weapon/gun/energy/e_gun/advtaser/G = new /obj/item/weapon/gun/energy/e_gun/advtaser(Tsec)
|
||||
var/obj/item/gun/energy/e_gun/advtaser/G = new /obj/item/gun/energy/e_gun/advtaser(Tsec)
|
||||
G.cell.charge = 0
|
||||
G.update_icon()
|
||||
else if(lasercolor == "b")
|
||||
var/obj/item/weapon/gun/energy/laser/bluetag/G = new /obj/item/weapon/gun/energy/laser/bluetag(Tsec)
|
||||
var/obj/item/gun/energy/laser/bluetag/G = new /obj/item/gun/energy/laser/bluetag(Tsec)
|
||||
G.cell.charge = 0
|
||||
G.update_icon()
|
||||
else if(lasercolor == "r")
|
||||
var/obj/item/weapon/gun/energy/laser/redtag/G = new /obj/item/weapon/gun/energy/laser/redtag(Tsec)
|
||||
var/obj/item/gun/energy/laser/redtag/G = new /obj/item/gun/energy/laser/redtag(Tsec)
|
||||
G.cell.charge = 0
|
||||
G.update_icon()
|
||||
|
||||
@@ -562,6 +562,6 @@ Auto Patrol[]"},
|
||||
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_handcuffed()
|
||||
back_to_idle()
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
var/obj/item/weapon/storage/toolbox/mechanical/N = new /obj/item/weapon/storage/toolbox/mechanical(Tsec)
|
||||
var/obj/item/storage/toolbox/mechanical/N = new /obj/item/storage/toolbox/mechanical(Tsec)
|
||||
N.contents = list()
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
window_name = "Automatic Medical Unit v1.1"
|
||||
data_hud_type = DATA_HUD_MEDICAL_ADVANCED
|
||||
|
||||
var/obj/item/weapon/reagent_containers/glass/reagent_glass = null //Can be set to draw from this for reagents.
|
||||
var/obj/item/reagent_containers/glass/reagent_glass = null //Can be set to draw from this for reagents.
|
||||
var/skin = null //Set to "tox", "ointment" or "o2" for the other two firstaid kits.
|
||||
var/mob/living/carbon/patient = null
|
||||
var/mob/living/carbon/oldpatient = null
|
||||
@@ -214,8 +214,8 @@
|
||||
update_controls()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/weapon/reagent_containers/glass))
|
||||
/mob/living/simple_animal/bot/medbot/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/reagent_containers/glass))
|
||||
. = 1 //no afterattack
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>You cannot insert a beaker because the panel is locked!</span>")
|
||||
@@ -516,7 +516,7 @@
|
||||
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/weapon/storage/firstaid(Tsec)
|
||||
new /obj/item/storage/firstaid(Tsec)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
var/auto_pickup = 1 // true if auto-pickup at beacon
|
||||
var/report_delivery = 1 // true if bot will announce an arrival to a location.
|
||||
|
||||
var/obj/item/weapon/stock_parts/cell/cell
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/bloodiness = 0
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Initialize()
|
||||
@@ -79,19 +79,19 @@
|
||||
reached_target = 0
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(istype(I, /obj/item/screwdriver))
|
||||
..()
|
||||
if(open)
|
||||
on = FALSE
|
||||
else if(istype(I, /obj/item/weapon/stock_parts/cell) && open && !cell)
|
||||
else if(istype(I, /obj/item/stock_parts/cell) && open && !cell)
|
||||
if(!user.drop_item())
|
||||
return
|
||||
var/obj/item/weapon/stock_parts/cell/C = I
|
||||
var/obj/item/stock_parts/cell/C = I
|
||||
C.loc = src
|
||||
cell = C
|
||||
visible_message("[user] inserts a cell into [src].",
|
||||
"<span class='notice'>You insert the new cell into [src].</span>")
|
||||
else if(istype(I, /obj/item/weapon/crowbar) && open && cell)
|
||||
else if(istype(I, /obj/item/crowbar) && open && cell)
|
||||
cell.add_fingerprint(usr)
|
||||
cell.loc = loc
|
||||
cell = null
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
bot_type = SEC_BOT
|
||||
model = "Securitron"
|
||||
bot_core_type = /obj/machinery/bot_core/secbot
|
||||
var/baton_type = /obj/item/weapon/melee/baton
|
||||
var/baton_type = /obj/item/melee/baton
|
||||
window_id = "autosec"
|
||||
window_name = "Automatic Security Unit v1.6"
|
||||
allow_pai = 0
|
||||
@@ -51,8 +51,8 @@
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/explode()
|
||||
var/turf/Tsec = get_turf(src)
|
||||
new /obj/item/weapon/stock_parts/cell/potato(Tsec)
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass/S = new(Tsec)
|
||||
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.on_reagent_change()
|
||||
..()
|
||||
@@ -173,11 +173,11 @@ Auto Patrol: []"},
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/attackby(obj/item/weapon/W, mob/user, params)
|
||||
/mob/living/simple_animal/bot/secbot/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
|
||||
if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
|
||||
return
|
||||
if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
|
||||
if(!istype(W, /obj/item/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
|
||||
retaliate(user)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
|
||||
@@ -229,7 +229,7 @@ Auto Patrol: []"},
|
||||
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_handcuffed()
|
||||
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
|
||||
back_to_idle()
|
||||
@@ -401,7 +401,7 @@ Auto Patrol: []"},
|
||||
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/secbot_assembly(Tsec)
|
||||
var/obj/item/secbot_assembly/Sa = new /obj/item/secbot_assembly(Tsec)
|
||||
Sa.build_step = 1
|
||||
Sa.add_overlay("hs_hole")
|
||||
Sa.created_name = name
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
pressure_resistance = 100
|
||||
unique_name = 1
|
||||
AIStatus = AI_OFF //normal constructs don't have AI
|
||||
loot = list(/obj/item/weapon/ectoplasm)
|
||||
loot = list(/obj/item/ectoplasm)
|
||||
del_on_death = TRUE
|
||||
initial_language_holder = /datum/language_holder/construct
|
||||
deathmessage = "collapses in a shattered heap."
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
ears = /obj/item/device/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas
|
||||
head = /obj/item/clothing/head/helmet/swat
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
id = /obj/item/weapon/card/id
|
||||
back = /obj/item/storage/backpack
|
||||
id = /obj/item/card/id
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/syndicatecommando
|
||||
@@ -41,9 +41,9 @@
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
ears = /obj/item/device/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas/syndicate
|
||||
back = /obj/item/weapon/tank/jetpack/oxygen
|
||||
r_pocket = /obj/item/weapon/tank/internals/emergency_oxygen
|
||||
id = /obj/item/weapon/card/id
|
||||
back = /obj/item/tank/jetpack/oxygen
|
||||
r_pocket = /obj/item/tank/internals/emergency_oxygen
|
||||
id = /obj/item/card/id
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/syndicatestormtrooper
|
||||
@@ -60,8 +60,8 @@
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
ears = /obj/item/device/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas/syndicate
|
||||
back = /obj/item/weapon/tank/jetpack/oxygen/harness
|
||||
id = /obj/item/weapon/card/id
|
||||
back = /obj/item/tank/jetpack/oxygen/harness
|
||||
id = /obj/item/card/id
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/clown/corpse
|
||||
@@ -163,5 +163,5 @@
|
||||
ears = /obj/item/device/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas/sechailer/swat
|
||||
head = /obj/item/clothing/head/helmet/swat/nanotrasen
|
||||
back = /obj/item/weapon/storage/backpack/security
|
||||
id = /obj/item/weapon/card/id
|
||||
back = /obj/item/storage/backpack/security
|
||||
id = /obj/item/card/id
|
||||
|
||||
@@ -28,3 +28,6 @@
|
||||
. = ..()
|
||||
var/newcolor = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
|
||||
add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/mob/living/simple_animal/butterfly/bee_friendly()
|
||||
return TRUE //treaty signed at the Beeneeva convention
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
unsuitable_atmos_damage = 1
|
||||
animal_species = /mob/living/simple_animal/pet/cat
|
||||
childtype = list(/mob/living/simple_animal/pet/cat/kitten)
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
@@ -113,14 +113,22 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
S["family"] >> family
|
||||
|
||||
if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
S["family"] >> family
|
||||
fdel("data/npc_saves/Runtime.sav")
|
||||
else
|
||||
var/json_file = file("data/npc_saves/Runtime.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
family = json["family"]
|
||||
if(isnull(family))
|
||||
family = list()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead)
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
var/json_file = file("data/npc_saves/Runtime.json")
|
||||
family = list()
|
||||
if(!dead)
|
||||
for(var/mob/living/simple_animal/pet/cat/kitten/C in children)
|
||||
@@ -130,7 +138,8 @@
|
||||
family[C.type] += 1
|
||||
else
|
||||
family[C.type] = 1
|
||||
WRITE_FILE(S["family"], family)
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(family))
|
||||
memory_saved = 1
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Deploy_The_Cats()
|
||||
@@ -232,8 +241,8 @@
|
||||
maxHealth = 50
|
||||
gender = FEMALE
|
||||
harm_intent_damage = 10
|
||||
butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/weapon/reagent_containers/food/snacks/cakeslice/birthday = 3, \
|
||||
/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2)
|
||||
butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/reagent_containers/food/snacks/cakeslice/birthday = 3, \
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab = 2)
|
||||
response_harm = "takes a bite out of"
|
||||
attacked_sound = 'sound/items/eatfood.ogg'
|
||||
deathmessage = "loses its false life and collapses!"
|
||||
@@ -259,7 +268,7 @@
|
||||
return
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-8) //Fast life regen
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts!
|
||||
for(var/obj/item/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts!
|
||||
if(D.icon_state != "donut2")
|
||||
D.name = "frosted donut"
|
||||
D.icon_state = "donut2"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
emote_see = list("clacks.")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 1)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "stomps"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
icon_state = "corgi"
|
||||
icon_living = "corgi"
|
||||
icon_dead = "corgi_dead"
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/corgi = 3, /obj/item/stack/sheet/animalhide/corgi = 1)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/corgi = 3, /obj/item/stack/sheet/animalhide/corgi = 1)
|
||||
childtype = list(/mob/living/simple_animal/pet/dog/corgi/puppy = 95, /mob/living/simple_animal/pet/dog/corgi/puppy/void = 5)
|
||||
animal_species = /mob/living/simple_animal/pet/dog
|
||||
var/shaved = 0
|
||||
@@ -41,7 +41,7 @@
|
||||
icon_state = "pug"
|
||||
icon_living = "pug"
|
||||
icon_dead = "pug_dead"
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/pug = 3)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/pug = 3)
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/pet/dog/Initialize()
|
||||
@@ -98,7 +98,7 @@
|
||||
return armorval*0.5
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/attackby(obj/item/O, mob/user, params)
|
||||
if (istype(O, /obj/item/weapon/razor))
|
||||
if (istype(O, /obj/item/razor))
|
||||
if (shaved)
|
||||
to_chat(user, "<span class='warning'>You can't shave this corgi, it's already been shaved!</span>")
|
||||
return
|
||||
@@ -178,7 +178,7 @@
|
||||
to_chat(usr, "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!</span>")
|
||||
return
|
||||
|
||||
if(istype(item_to_add, /obj/item/weapon/grenade/plastic)) // last thing he ever wears, I guess
|
||||
if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess
|
||||
item_to_add.afterattack(src,usr,1)
|
||||
return
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user)
|
||||
|
||||
if(istype(item_to_add, /obj/item/weapon/grenade/plastic)) // last thing he ever wears, I guess
|
||||
if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess
|
||||
item_to_add.afterattack(src,user,1)
|
||||
return
|
||||
|
||||
@@ -328,33 +328,44 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
|
||||
S["age"] >> age
|
||||
S["record_age"] >> record_age
|
||||
S["saved_head"] >> saved_head
|
||||
|
||||
if(fexists("data/npc_saves/Ian.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
|
||||
S["age"] >> age
|
||||
S["record_age"] >> record_age
|
||||
S["saved_head"] >> saved_head
|
||||
fdel("data/npc_saves/Ian.sav")
|
||||
else
|
||||
var/json_file = file("data/npc_saves/Ian.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
age = json["age"]
|
||||
record_age = json["record_age"]
|
||||
saved_head = json["saved_head"]
|
||||
if(isnull(age))
|
||||
age = 0
|
||||
if(isnull(record_age))
|
||||
record_age = 1
|
||||
|
||||
if(saved_head)
|
||||
place_on_head(new saved_head)
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Write_Memory(dead)
|
||||
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
|
||||
var/json_file = file("data/npc_saves/Ian.json")
|
||||
var/list/file_data = list()
|
||||
if(!dead)
|
||||
WRITE_FILE(S["age"], age + 1)
|
||||
file_data["age"] = age + 1
|
||||
if((age + 1) > record_age)
|
||||
WRITE_FILE(S["record_age"], record_age + 1)
|
||||
file_data["record_age"] = record_age + 1
|
||||
if(inventory_head)
|
||||
WRITE_FILE(S["saved_head"], inventory_head.type)
|
||||
file_data["saved_head"] = inventory_head.type
|
||||
else
|
||||
WRITE_FILE(S["age"], 0)
|
||||
WRITE_FILE(S["saved_head"], null)
|
||||
file_data["age"] = 0
|
||||
file_data["saved_head"] = null
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
memory_saved = 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/Life()
|
||||
..()
|
||||
|
||||
@@ -369,7 +380,7 @@
|
||||
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/S in oview(src,3))
|
||||
for(var/obj/item/reagent_containers/food/snacks/S in oview(src,3))
|
||||
if(isturf(S.loc) || ishuman(S.loc))
|
||||
movement_target = S
|
||||
break
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
var/alarms = list("Atmosphere" = list(), "Fire" = list(), "Power" = list())
|
||||
var/obj/item/internal_storage //Drones can store one item, of any size/type in their body
|
||||
var/obj/item/head
|
||||
var/obj/item/default_storage = /obj/item/weapon/storage/backpack/duffelbag/drone //If this exists, it will spawn in internal storage
|
||||
var/obj/item/default_storage = /obj/item/storage/backpack/duffelbag/drone //If this exists, it will spawn in internal storage
|
||||
var/obj/item/default_hatmask //If this exists, it will spawn in the hat/mask slot if it can fit
|
||||
var/seeStatic = 1 //Whether we see static instead of mobs
|
||||
var/visualAppearence = MAINTDRONE //What we appear as
|
||||
@@ -81,7 +81,7 @@
|
||||
/mob/living/simple_animal/drone/Initialize()
|
||||
. = ..()
|
||||
|
||||
access_card = new /obj/item/weapon/card/id(src)
|
||||
access_card = new /obj/item/card/id(src)
|
||||
var/datum/job/captain/C = new /datum/job/captain
|
||||
access_card.access = C.get_access()
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
var/obj/item/I = new default_hatmask(src)
|
||||
equip_to_slot_or_del(I, slot_head)
|
||||
|
||||
access_card.flags |= NODROP
|
||||
access_card.flags_1 |= NODROP_1
|
||||
|
||||
alert_drones(DRONE_NET_CONNECT)
|
||||
|
||||
@@ -175,21 +175,21 @@
|
||||
|
||||
//Hands
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & ABSTRACT))
|
||||
if(!(I.flags_1 & ABSTRACT_1))
|
||||
if(I.blood_DNA)
|
||||
msg += "<span class='warning'>It has [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
|
||||
else
|
||||
msg += "It has [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
|
||||
|
||||
//Internal storage
|
||||
if(internal_storage && !(internal_storage.flags&ABSTRACT))
|
||||
if(internal_storage && !(internal_storage.flags_1&ABSTRACT_1))
|
||||
if(internal_storage.blood_DNA)
|
||||
msg += "<span class='warning'>It is holding [icon2html(internal_storage, user)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!</span>\n"
|
||||
else
|
||||
msg += "It is holding [icon2html(internal_storage, user)] \a [internal_storage] in its internal storage.\n"
|
||||
|
||||
//Cosmetic hat - provides no function other than looks
|
||||
if(head && !(head.flags&ABSTRACT))
|
||||
if(head && !(head.flags_1&ABSTRACT_1))
|
||||
if(head.blood_DNA)
|
||||
msg += "<span class='warning'>It is wearing [icon2html(head, user)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on its head!</span>\n"
|
||||
else
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
/mob/living/simple_animal/drone/syndrone/badass/Initialize()
|
||||
..()
|
||||
internal_storage.hidden_uplink.telecrystals = 30
|
||||
var/obj/item/weapon/implant/weapons_auth/W = new/obj/item/weapon/implant/weapons_auth(src)
|
||||
var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(src)
|
||||
W.implant(src)
|
||||
|
||||
/mob/living/simple_animal/drone/snowflake
|
||||
@@ -125,7 +125,7 @@
|
||||
light_color = "#E42742"
|
||||
heavy_emp_damage = 0
|
||||
laws = "0. Purge all untruths and honor Ratvar."
|
||||
default_storage = /obj/item/weapon/storage/toolbox/brass/prefilled
|
||||
default_storage = /obj/item/storage/toolbox/brass/prefilled
|
||||
seeStatic = 0
|
||||
hacked = TRUE
|
||||
visualAppearence = CLOCKDRONE
|
||||
@@ -135,10 +135,10 @@
|
||||
temperatures and pressures. \nYour goal is to serve the Justiciar and his servants by repairing and defending all they create.</b>"
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal fabricator
|
||||
default_storage = /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar
|
||||
default_storage = /obj/item/storage/toolbox/brass/prefilled/ratvar
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/admin //an admin-only subtype of cogscarab with a no-cost fabricator and slab in its box
|
||||
default_storage = /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin
|
||||
default_storage = /obj/item/storage/toolbox/brass/prefilled/ratvar/admin
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/Initialize()
|
||||
. = ..()
|
||||
@@ -165,7 +165,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/drone/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/screwdriver) && stat == DEAD)
|
||||
if(istype(I, /obj/item/screwdriver) && stat == DEAD)
|
||||
try_reactivate(user)
|
||||
else
|
||||
..()
|
||||
@@ -176,7 +176,7 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/can_use_guns(obj/item/weapon/G)
|
||||
/mob/living/simple_animal/drone/cogscarab/can_use_guns(obj/item/G)
|
||||
return GLOB.ratvar_awakens
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/get_armor_effectiveness()
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/screwdriver) && stat != DEAD)
|
||||
if(istype(I, /obj/item/screwdriver) && stat != DEAD)
|
||||
if(health < maxHealth)
|
||||
to_chat(user, "<span class='notice'>You start to tighten loose screws on [src]...</span>")
|
||||
if(do_after(user,80*I.toolspeed,target=user))
|
||||
@@ -92,7 +92,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src]'s screws can't get any tighter!</span>")
|
||||
return //This used to not exist and drones who repaired themselves also stabbed the shit out of themselves.
|
||||
else if(istype(I, /obj/item/weapon/wrench) && user != src) //They aren't required to be hacked, because laws can change in other ways (i.e. admins)
|
||||
else if(istype(I, /obj/item/wrench) && user != src) //They aren't required to be hacked, because laws can change in other ways (i.e. admins)
|
||||
user.visible_message("<span class='notice'>[user] starts resetting [src]...</span>", \
|
||||
"<span class='notice'>You press down on [src]'s factory reset control...</span>")
|
||||
playsound(src, I.usesound, 50, 1)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 4)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 4)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
@@ -85,7 +85,7 @@
|
||||
say("Nom")
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/attackby(obj/item/O, mob/user, params)
|
||||
if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass))
|
||||
if(stat == CONSCIOUS && istype(O, /obj/item/reagent_containers/glass))
|
||||
udder.milkAnimal(O, user)
|
||||
return 1
|
||||
else
|
||||
@@ -107,7 +107,7 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 6)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 6)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
@@ -130,7 +130,7 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/cow/attackby(obj/item/O, mob/user, params)
|
||||
if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass))
|
||||
if(stat == CONSCIOUS && istype(O, /obj/item/reagent_containers/glass))
|
||||
udder.milkAnimal(O, user)
|
||||
return 1
|
||||
else
|
||||
@@ -182,7 +182,7 @@
|
||||
density = FALSE
|
||||
speak_chance = 2
|
||||
turns_per_move = 2
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 1)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
@@ -229,9 +229,9 @@
|
||||
density = FALSE
|
||||
speak_chance = 2
|
||||
turns_per_move = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2)
|
||||
var/egg_type = /obj/item/weapon/reagent_containers/food/snacks/egg
|
||||
var/food_type = /obj/item/weapon/reagent_containers/food/snacks/grown/wheat
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
|
||||
var/egg_type = /obj/item/reagent_containers/food/snacks/egg
|
||||
var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
@@ -295,8 +295,8 @@
|
||||
if(chicken_count < MAX_CHICKENS && prob(25))
|
||||
START_PROCESSING(SSobj, E)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/process()
|
||||
/obj/item/reagent_containers/food/snacks/egg/var/amount_grown = 0
|
||||
/obj/item/reagent_containers/food/snacks/egg/process()
|
||||
if(isturf(loc))
|
||||
amount_grown += rand(1,2)
|
||||
if(amount_grown >= 100)
|
||||
@@ -321,7 +321,7 @@
|
||||
reagents.add_reagent("milk", rand(5, 10))
|
||||
|
||||
/obj/item/udder/proc/milkAnimal(obj/O, mob/user)
|
||||
var/obj/item/weapon/reagent_containers/glass/G = O
|
||||
var/obj/item/reagent_containers/glass/G = O
|
||||
if(G.reagents.total_volume >= G.volume)
|
||||
to_chat(user, "<span class='danger'>[O] is full.</span>")
|
||||
return
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 3)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
see_in_dark = 6
|
||||
maxHealth = 5
|
||||
health = 5
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 1)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "splats"
|
||||
@@ -43,7 +43,7 @@
|
||||
/mob/living/simple_animal/mouse/death(gibbed, toast)
|
||||
if(!ckey)
|
||||
..(1)
|
||||
var/obj/item/trash/deadmouse/M = new(src.loc)
|
||||
var/obj/item/reagent_containers/food/snacks/deadmouse/M = new(loc)
|
||||
M.icon_state = icon_dead
|
||||
M.name = name
|
||||
if(toast)
|
||||
@@ -101,8 +101,12 @@
|
||||
response_harm = "splats"
|
||||
gold_core_spawnable = 0
|
||||
|
||||
/obj/item/trash/deadmouse
|
||||
/obj/item/reagent_containers/food/snacks/deadmouse
|
||||
name = "dead mouse"
|
||||
desc = "It looks like somebody dropped the bass on it."
|
||||
desc = "It looks like somebody dropped the bass on it. A lizard's favorite meal."
|
||||
icon = 'icons/mob/animal.dmi'
|
||||
icon_state = "mouse_gray_dead"
|
||||
bitesize = 3
|
||||
eatverb = "devours"
|
||||
list_reagents = list("nutriment" = 3, "vitamin" = 2)
|
||||
foodtype = GROSS | MEAT | RAW
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
name = real_name
|
||||
qdel(P)
|
||||
return
|
||||
if(istype(O, /obj/item/weapon/newspaper))
|
||||
if(istype(O, /obj/item/newspaper))
|
||||
if(!stat)
|
||||
user.visible_message("[user] baps [name] on the nose with the rolled up [O].")
|
||||
spawn(0)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
emote_see = list("dozes off.", "looks around sleepily.")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 3)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
|
||||
@@ -35,7 +35,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
obj_damage = 40
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
butcher_results = list(/obj/item/weapon/ectoplasm = 1)
|
||||
butcher_results = list(/obj/item/ectoplasm = 1)
|
||||
AIStatus = AI_OFF
|
||||
dextrous_hud_type = /datum/hud/dextrous/guardian //if we're set to dextrous, account for it.
|
||||
var/list/guardian_overlays[GUARDIAN_TOTAL_LAYERS]
|
||||
@@ -455,7 +455,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
|
||||
////////Creation
|
||||
|
||||
/obj/item/weapon/guardiancreator
|
||||
/obj/item/guardiancreator
|
||||
name = "deck of tarot cards"
|
||||
desc = "An enchanted deck of tarot cards, rumored to be a source of unimaginable power. "
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
@@ -474,7 +474,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
var/allowling = TRUE
|
||||
var/allowguardian = FALSE
|
||||
|
||||
/obj/item/weapon/guardiancreator/attack_self(mob/living/user)
|
||||
/obj/item/guardiancreator/attack_self(mob/living/user)
|
||||
if(isguardian(user) && !allowguardian)
|
||||
to_chat(user, "<span class='holoparasite'>[mob_name] chains are not allowed.</span>")
|
||||
return
|
||||
@@ -490,7 +490,7 @@ 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)
|
||||
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/mob/dead/observer/theghost = null
|
||||
|
||||
if(candidates.len)
|
||||
@@ -503,7 +503,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
used = FALSE
|
||||
|
||||
|
||||
/obj/item/weapon/guardiancreator/proc/spawn_guardian(var/mob/living/user, var/key)
|
||||
/obj/item/guardiancreator/proc/spawn_guardian(var/mob/living/user, var/key)
|
||||
var/guardiantype = "Standard"
|
||||
if(random)
|
||||
guardiantype = pick(possible_guardians)
|
||||
@@ -570,17 +570,17 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
user.verbs += /mob/living/proc/guardian_recall
|
||||
user.verbs += /mob/living/proc/guardian_reset
|
||||
|
||||
/obj/item/weapon/guardiancreator/choose
|
||||
/obj/item/guardiancreator/choose
|
||||
random = FALSE
|
||||
|
||||
/obj/item/weapon/guardiancreator/choose/dextrous
|
||||
/obj/item/guardiancreator/choose/dextrous
|
||||
possible_guardians = list("Assassin", "Chaos", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
|
||||
|
||||
/obj/item/weapon/guardiancreator/choose/wizard
|
||||
/obj/item/guardiancreator/choose/wizard
|
||||
possible_guardians = list("Assassin", "Chaos", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard")
|
||||
allowmultiple = TRUE
|
||||
|
||||
/obj/item/weapon/guardiancreator/tech
|
||||
/obj/item/guardiancreator/tech
|
||||
name = "holoparasite injector"
|
||||
desc = "It contains an alien nanoswarm of unknown origin. Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, it requires an organic host as a home base and source of fuel."
|
||||
icon = 'icons/obj/syringe.dmi'
|
||||
@@ -593,16 +593,16 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
ling_failure = "<span class='holoparasitebold'>The holoparasites recoil in horror. They want nothing to do with a creature like you.</span>"
|
||||
activation_message = "<span class='holoparasite'>The injector self destructs after you inject yourself with it.</span>"
|
||||
|
||||
/obj/item/weapon/guardiancreator/tech/choose/traitor
|
||||
/obj/item/guardiancreator/tech/choose/traitor
|
||||
possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
|
||||
|
||||
/obj/item/weapon/guardiancreator/tech/choose
|
||||
/obj/item/guardiancreator/tech/choose
|
||||
random = FALSE
|
||||
|
||||
/obj/item/weapon/guardiancreator/tech/choose/dextrous
|
||||
/obj/item/guardiancreator/tech/choose/dextrous
|
||||
possible_guardians = list("Assassin", "Chaos", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
|
||||
|
||||
/obj/item/weapon/paper/guides/antag/guardian
|
||||
/obj/item/paper/guides/antag/guardian
|
||||
name = "Holoparasite Guide"
|
||||
icon_state = "alienpaper_words"
|
||||
info = {"<b>A list of Holoparasite Types</b><br>
|
||||
@@ -626,10 +626,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
<br>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/paper/guides/antag/guardian/update_icon()
|
||||
/obj/item/paper/guides/antag/guardian/update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/paper/guides/antag/guardian/wizard
|
||||
/obj/item/paper/guides/antag/guardian/wizard
|
||||
name = "Guardian Guide"
|
||||
info = {"<b>A list of Guardian Types</b><br>
|
||||
|
||||
@@ -655,16 +655,16 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
"}
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/guardian
|
||||
/obj/item/storage/box/syndie_kit/guardian
|
||||
name = "holoparasite injector kit"
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/guardian/Initialize()
|
||||
/obj/item/storage/box/syndie_kit/guardian/Initialize()
|
||||
..()
|
||||
new /obj/item/weapon/guardiancreator/tech/choose/traitor(src)
|
||||
new /obj/item/weapon/paper/guides/antag/guardian(src)
|
||||
new /obj/item/guardiancreator/tech/choose/traitor(src)
|
||||
new /obj/item/paper/guides/antag/guardian(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/guardiancreator/carp
|
||||
/obj/item/guardiancreator/carp
|
||||
name = "holocarp fishsticks"
|
||||
desc = "Using the power of Carp'sie, you can catch a carp from byond the veil of Carpthulu, and bind it to your fleshy flesh form."
|
||||
icon = 'icons/obj/food/food.dmi'
|
||||
@@ -680,5 +680,5 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
allowling = TRUE
|
||||
random = TRUE
|
||||
|
||||
/obj/item/weapon/guardiancreator/carp/choose
|
||||
/obj/item/guardiancreator/carp/choose
|
||||
random = FALSE
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
msg += "[desc]\n"
|
||||
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & ABSTRACT))
|
||||
if(!(I.flags_1 & ABSTRACT_1))
|
||||
if(I.blood_DNA)
|
||||
msg += "<span class='warning'>It has [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
|
||||
else
|
||||
msg += "It has [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
|
||||
|
||||
if(internal_storage && !(internal_storage.flags&ABSTRACT))
|
||||
if(internal_storage && !(internal_storage.flags_1&ABSTRACT_1))
|
||||
if(internal_storage.blood_DNA)
|
||||
msg += "<span class='warning'>It is holding [icon2html(internal_storage, user)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!</span>\n"
|
||||
else
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
response_disarm = "shoves"
|
||||
response_harm = "hits"
|
||||
speed = 0
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 4,
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 4,
|
||||
/obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
maxHealth = 125
|
||||
health = 125
|
||||
@@ -84,7 +84,7 @@
|
||||
retreat_distance = 5
|
||||
minimum_distance = 5
|
||||
move_to_delay = 4
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 4,
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 4,
|
||||
/obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
projectiletype = /obj/item/projectile/neurotox
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
@@ -134,7 +134,7 @@
|
||||
move_to_delay = 4
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 10,
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 10,
|
||||
/obj/item/stack/sheet/animalhide/xeno = 2)
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
gold_core_spawnable = 0
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
taunt_chance = 25
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "hits"
|
||||
@@ -57,7 +57,7 @@
|
||||
icon_living = "combatbear"
|
||||
icon_dead = "combatbear_dead"
|
||||
faction = list("russian")
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1, /obj/item/bear_armor = 1)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1, /obj/item/bear_armor = 1)
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 35
|
||||
armour_penetration = 20
|
||||
@@ -77,7 +77,7 @@
|
||||
name = "pile of bear armor"
|
||||
desc = "A scattered pile of various shaped armor pieces fitted for a bear, some duct tape, and a nail filer. Crude instructions \
|
||||
are written on the back of one of the plates in russian. This seems like an awful idea."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "bear_armor_upgrade"
|
||||
|
||||
/obj/item/bear_armor/afterattack(atom/target, mob/user, proximity_flag)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
move_to_delay = 0
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
mouse_opacity = 2
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
mob_size = MOB_SIZE_TINY
|
||||
movement_type = FLYING
|
||||
@@ -249,8 +249,8 @@
|
||||
|
||||
|
||||
/obj/item/queen_bee/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/syringe))
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = I
|
||||
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)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
icon_gib = "carp_gib"
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/carpmeat = 2)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 2)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "hits"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
speak_chance = 5
|
||||
turns_per_move = 5
|
||||
see_in_dark = 10
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/spider = 2, /obj/item/weapon/reagent_containers/food/snacks/spiderleg = 8)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/spider = 2, /obj/item/reagent_containers/food/snacks/spiderleg = 8)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "hits"
|
||||
@@ -81,7 +81,7 @@
|
||||
icon_living = "nurse"
|
||||
icon_dead = "nurse_dead"
|
||||
gender = FEMALE
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/spider = 2, /obj/item/weapon/reagent_containers/food/snacks/spiderleg = 8, /obj/item/weapon/reagent_containers/food/snacks/spidereggs = 4)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/spider = 2, /obj/item/reagent_containers/food/snacks/spiderleg = 8, /obj/item/reagent_containers/food/snacks/spidereggs = 4)
|
||||
maxHealth = 40
|
||||
health = 40
|
||||
melee_damage_lower = 5
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/emote/sound/gorilla
|
||||
mob_type_allowed_typecache = /mob/living/simple_animal/hostile/gorilla
|
||||
mob_type_blacklist_typecache = list()
|
||||
|
||||
/datum/emote/sound/gorilla/ooga
|
||||
key = "ooga"
|
||||
key_third_person = "oogas"
|
||||
message = "oogas."
|
||||
message_param = "oogas at %t."
|
||||
sound = "sound/creatures/gorilla.ogg"
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#define GORILLA_HANDS_LAYER 1
|
||||
#define GORILLA_TOTAL_LAYERS 1
|
||||
|
||||
/mob/living/simple_animal/hostile/gorilla
|
||||
name = "Gorilla"
|
||||
desc = "A ground-dwelling, predominantly herbivorous ape that inhabits the forests of central Africa."
|
||||
icon = 'icons/mob/gorilla.dmi'
|
||||
icon_state = "crawling"
|
||||
icon_state = "crawling"
|
||||
icon_living = "crawling"
|
||||
icon_dead = "dead"
|
||||
speak_chance = 80
|
||||
maxHealth = 220
|
||||
health = 220
|
||||
loot = list(/obj/effect/gibspawner/generic)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/gorilla = 4)
|
||||
response_help = "prods"
|
||||
response_disarm = "challenges"
|
||||
response_harm = "thumps"
|
||||
speed = 1
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 18
|
||||
damage_coeff = list(BRUTE = 1, BURN = 1.5, TOX = 1.5, CLONE = 0, STAMINA = 0, OXY = 1.5)
|
||||
obj_damage = 20
|
||||
environment_smash = 2
|
||||
attacktext = "pummels"
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
dextrous = TRUE
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_GRAB, INTENT_DISARM, INTENT_HARM)
|
||||
faction = list("jungle")
|
||||
robust_searching = TRUE
|
||||
stat_attack = UNCONSCIOUS
|
||||
minbodytemp = 270
|
||||
maxbodytemp = 350
|
||||
var/list/gorilla_overlays[GORILLA_TOTAL_LAYERS]
|
||||
|
||||
// Gorillas like to dismember limbs from unconcious mobs.
|
||||
// Returns null when the target is not an unconcious carbon mob; a list of limbs (possibly empty) otherwise.
|
||||
/mob/living/simple_animal/hostile/gorilla/proc/target_bodyparts(atom/the_target)
|
||||
var/list/parts = list()
|
||||
if(iscarbon(the_target))
|
||||
var/mob/living/carbon/C = the_target
|
||||
if(C.stat >= UNCONSCIOUS)
|
||||
for(var/X in C.bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.body_part != HEAD && BP.body_part != CHEST)
|
||||
if(BP.dismemberable)
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
/mob/living/simple_animal/hostile/gorilla/AttackingTarget()
|
||||
var/list/parts = target_bodyparts(target)
|
||||
if(parts)
|
||||
if(!parts.len)
|
||||
return FALSE
|
||||
var/obj/item/bodypart/BP = pick(parts)
|
||||
BP.dismember()
|
||||
return ..()
|
||||
. = ..()
|
||||
if(. && isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(prob(80))
|
||||
var/atom/throw_target = get_edge_target_turf(L, dir)
|
||||
L.throw_at(throw_target, rand(1,2), 7, src)
|
||||
else
|
||||
L.Knockdown(20)
|
||||
visible_message("<span class='danger'>[src] knocks [L] down!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/gorilla/CanAttack(atom/the_target)
|
||||
var/list/parts = target_bodyparts(target)
|
||||
return ..() && !istype(the_target, /mob/living/carbon/monkey) && (!parts || parts.len > 3)
|
||||
|
||||
/mob/living/simple_animal/hostile/gorilla/handle_automated_speech(override)
|
||||
if(speak_chance && (override || prob(speak_chance)))
|
||||
playsound(src, "sound/creatures/gorilla.ogg", 200)
|
||||
..()
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/mob/living/simple_animal/hostile/gorilla/proc/apply_overlay(cache_index)
|
||||
. = gorilla_overlays[cache_index]
|
||||
if(.)
|
||||
add_overlay(.)
|
||||
|
||||
/mob/living/simple_animal/hostile/gorilla/proc/remove_overlay(cache_index)
|
||||
var/I = gorilla_overlays[cache_index]
|
||||
if(I)
|
||||
cut_overlay(I)
|
||||
gorilla_overlays[cache_index] = null
|
||||
|
||||
/mob/living/simple_animal/hostile/gorilla/update_inv_hands()
|
||||
cut_overlays("standing_overlay")
|
||||
remove_overlay(GORILLA_HANDS_LAYER)
|
||||
|
||||
var/standing = FALSE
|
||||
for(var/I in held_items)
|
||||
if(I)
|
||||
standing = TRUE
|
||||
break
|
||||
if(!standing)
|
||||
if(stat != DEAD)
|
||||
icon_state = "crawling"
|
||||
speed = 1
|
||||
return ..()
|
||||
if(stat != DEAD)
|
||||
icon_state = "standing"
|
||||
speed = 3 // Gorillas are slow when standing up.
|
||||
|
||||
var/list/hands_overlays = list()
|
||||
|
||||
var/obj/item/l_hand = get_item_for_held_index(1)
|
||||
var/obj/item/r_hand = get_item_for_held_index(2)
|
||||
|
||||
if(r_hand)
|
||||
var/r_state = r_hand.item_state ? r_hand.item_state : r_hand.icon_state
|
||||
var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(state = r_state, default_layer = GORILLA_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE)
|
||||
r_hand_overlay.pixel_y -= 1
|
||||
hands_overlays += r_hand_overlay
|
||||
|
||||
if(l_hand)
|
||||
var/l_state = l_hand.item_state ? l_hand.item_state : l_hand.icon_state
|
||||
var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(state = l_state, default_layer = GORILLA_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE)
|
||||
l_hand_overlay.pixel_y -= 1
|
||||
hands_overlays += l_hand_overlay
|
||||
|
||||
if(hands_overlays.len)
|
||||
gorilla_overlays[GORILLA_HANDS_LAYER] = hands_overlays
|
||||
apply_overlay(GORILLA_HANDS_LAYER)
|
||||
add_overlay("standing_overlay")
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/gorilla/regenerate_icons()
|
||||
update_inv_hands()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
faction = list("hostile")
|
||||
stop_automated_movement_when_pulled = 0
|
||||
obj_damage = 40
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES //Set to 1 to break closets,tables,racks, etc; 2 for walls; 3 for rwalls
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES //Bitflags. Set to ENVIRONMENT_SMASH_STRUCTURES to break closets,tables,racks, etc; ENVIRONMENT_SMASH_WALLS for walls; ENVIRONMENT_SMASH_RWALLS for rwalls
|
||||
var/atom/target
|
||||
var/ranged = 0
|
||||
var/rapid = 0
|
||||
@@ -253,7 +253,7 @@
|
||||
if(target.loc != null && get_dist(targets_from, target.loc) <= vision_range) //We can't see our target, but he's in our vision range still
|
||||
if(ranged_ignores_vision && ranged_cooldown <= world.time) //we can't see our target... but we can fire at them!
|
||||
OpenFire(target)
|
||||
if(environment_smash >= 2) //If we're capable of smashing through walls, forget about vision completely after finding our target
|
||||
if((environment_smash & ENVIRONMENT_SMASH_WALLS) || (environment_smash & ENVIRONMENT_SMASH_RWALLS)) //If we're capable of smashing through walls, forget about vision completely after finding our target
|
||||
Goto(target,move_to_delay,minimum_distance)
|
||||
FindHidden()
|
||||
return 1
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/mob/living/simple_animal/hostile/jungle
|
||||
vision_range = 5
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
faction = list("jungle")
|
||||
weather_immunities = list("acid")
|
||||
obj_damage = 30
|
||||
environment_smash = ENVIRONMENT_SMASH_WALLS
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 450
|
||||
response_help = "pokes"
|
||||
response_disarm = "shoves"
|
||||
response_harm = "strikes"
|
||||
status_flags = NONE
|
||||
a_intent = INTENT_HARM
|
||||
see_in_dark = 4
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
@@ -0,0 +1,263 @@
|
||||
#define PLAYER_HOP_DELAY 25
|
||||
|
||||
//Huge, carnivorous toads that spit an immobilizing toxin at its victims before leaping onto them.
|
||||
//It has no melee attack, and its damage comes from the toxin in its bubbles and its crushing leap.
|
||||
//Its eyes will turn red to signal an imminent attack!
|
||||
/mob/living/simple_animal/hostile/jungle/leaper
|
||||
name = "leaper"
|
||||
desc = "Commonly referred to as 'leapers', the Geron Toad is a massive beast that spits out highly pressurized bubbles containing a unique toxin, knocking down its prey and then crushing it with its girth."
|
||||
icon = 'icons/mob/jungle/leaper.dmi'
|
||||
icon_state = "leaper"
|
||||
icon_living = "leaper"
|
||||
icon_dead = "leaper_dead"
|
||||
maxHealth = 300
|
||||
health = 300
|
||||
ranged = TRUE
|
||||
projectiletype = /obj/item/projectile/leaper
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
ranged_cooldown_time = 30
|
||||
pixel_x = -16
|
||||
layer = LARGE_MOB_LAYER
|
||||
speed = 10
|
||||
stat_attack = 1
|
||||
robust_searching = 1
|
||||
var/hopping = FALSE
|
||||
var/hop_cooldown = 0 //Strictly for player controlled leapers
|
||||
var/projectile_ready = FALSE //Stopping AI leapers from firing whenever they want, and only doing it after a hop has finished instead
|
||||
|
||||
/obj/item/projectile/leaper
|
||||
name = "leaper bubble"
|
||||
icon_state = "leaper"
|
||||
knockdown = 50
|
||||
damage = 0
|
||||
range = 7
|
||||
hitsound = 'sound/effects/snap.ogg'
|
||||
nondirectional_sprite = TRUE
|
||||
impact_effect_type = /obj/effect/temp_visual/leaper_projectile_impact
|
||||
|
||||
/obj/item/projectile/leaper/on_hit(atom/target, blocked = FALSE)
|
||||
..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
C.reagents.add_reagent("leaper_venom", 5)
|
||||
return
|
||||
if(isanimal(target))
|
||||
var/mob/living/simple_animal/L = target
|
||||
L.adjustHealth(25)
|
||||
|
||||
/obj/item/projectile/leaper/on_range()
|
||||
var/turf/T = get_turf(src)
|
||||
..()
|
||||
new /obj/structure/leaper_bubble(T)
|
||||
|
||||
/obj/effect/temp_visual/leaper_projectile_impact
|
||||
name = "leaper bubble"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "leaper_bubble_pop"
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
duration = 3
|
||||
|
||||
/obj/effect/temp_visual/leaper_projectile_impact/Initialize()
|
||||
. = ..()
|
||||
new /obj/effect/decal/cleanable/leaper_sludge(get_turf(src))
|
||||
|
||||
/obj/effect/decal/cleanable/leaper_sludge
|
||||
name = "leaper sludge"
|
||||
desc = "A small pool of sludge, containing trace amounts of leaper venom."
|
||||
icon = 'icons/effects/tomatodecal.dmi'
|
||||
icon_state = "tomato_floor1"
|
||||
|
||||
/obj/structure/leaper_bubble
|
||||
name = "leaper bubble"
|
||||
desc = "A floating bubble containing leaper venom. The contents are under a surprising amount of pressure."
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "leaper"
|
||||
max_integrity = 10
|
||||
density = FALSE
|
||||
|
||||
/obj/structure/leaper_bubble/Initialize()
|
||||
. = ..()
|
||||
float(on = TRUE)
|
||||
QDEL_IN(src, 100)
|
||||
|
||||
/obj/structure/leaper_bubble/Destroy()
|
||||
new /obj/effect/temp_visual/leaper_projectile_impact(get_turf(src))
|
||||
playsound(src,'sound/effects/snap.ogg',50, 1, -1)
|
||||
return ..()
|
||||
|
||||
/obj/structure/leaper_bubble/Crossed(atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!istype(L, /mob/living/simple_animal/hostile/jungle/leaper))
|
||||
playsound(src,'sound/effects/snap.ogg',50, 1, -1)
|
||||
L.Knockdown(50)
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
C.reagents.add_reagent("leaper_venom", 5)
|
||||
if(isanimal(L))
|
||||
var/mob/living/simple_animal/A = L
|
||||
A.adjustHealth(25)
|
||||
qdel(src)
|
||||
return ..()
|
||||
|
||||
/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
|
||||
taste_description = "french cuisine"
|
||||
taste_mult = 1.3
|
||||
|
||||
/datum/reagent/toxin/leaper_venom/on_mob_life(mob/living/M)
|
||||
if(volume >= 10)
|
||||
M.adjustToxLoss(5, 0)
|
||||
..()
|
||||
|
||||
/obj/effect/temp_visual/leaper_crush
|
||||
name = "grim tidings"
|
||||
desc = "Incoming leaper!"
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "lily_pad"
|
||||
layer = BELOW_MOB_LAYER
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
duration = 30
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/Initialize()
|
||||
. = ..()
|
||||
verbs -= /mob/living/verb/pulled
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/CtrlClickOn(atom/A)
|
||||
face_atom(A)
|
||||
target = A
|
||||
if(!isturf(loc))
|
||||
return
|
||||
if(next_move > world.time)
|
||||
return
|
||||
if(hopping)
|
||||
return
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(L.incapacitated())
|
||||
BellyFlop()
|
||||
return
|
||||
if(hop_cooldown <= world.time)
|
||||
Hop(player_hop = TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/AttackingTarget()
|
||||
if(isliving(target))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/handle_automated_action()
|
||||
if(hopping || projectile_ready)
|
||||
return
|
||||
. = ..()
|
||||
if(target)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated())
|
||||
BellyFlop()
|
||||
return
|
||||
if(!hopping)
|
||||
Hop()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/Life()
|
||||
. = ..()
|
||||
update_icons()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(prob(33) && !ckey)
|
||||
ranged_cooldown = 0 //Keeps em on their toes instead of a constant rotation
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/OpenFire()
|
||||
face_atom(target)
|
||||
if(ranged_cooldown <= world.time)
|
||||
if(ckey)
|
||||
if(hopping)
|
||||
return
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated())
|
||||
return //No stunlocking. Hop on them after you stun them, you donk.
|
||||
if(AIStatus == AI_ON && !projectile_ready && !ckey)
|
||||
return
|
||||
. = ..(target)
|
||||
projectile_ready = FALSE
|
||||
update_icons()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/Hop(player_hop = FALSE)
|
||||
if(z != target.z)
|
||||
return
|
||||
hopping = TRUE
|
||||
density = FALSE
|
||||
pass_flags |= PASSMOB
|
||||
notransform = TRUE
|
||||
var/turf/new_turf = locate((target.x + rand(-3,3)),(target.y + rand(-3,3)),target.z)
|
||||
if(player_hop)
|
||||
new_turf = get_turf(target)
|
||||
hop_cooldown = world.time + PLAYER_HOP_DELAY
|
||||
if(AIStatus == AI_ON && ranged_cooldown <= world.time)
|
||||
projectile_ready = TRUE
|
||||
update_icons()
|
||||
throw_at(new_turf, max(3,get_dist(src,new_turf)), 1, src, FALSE, callback = CALLBACK(src, .FinishHop))
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/FinishHop()
|
||||
density = TRUE
|
||||
notransform = FALSE
|
||||
pass_flags &= ~PASSMOB
|
||||
hopping = FALSE
|
||||
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 100, 1)
|
||||
if(target && AIStatus == AI_ON && projectile_ready && !ckey)
|
||||
face_atom(target)
|
||||
addtimer(CALLBACK(src, .proc/OpenFire, target), 5)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/BellyFlop()
|
||||
var/turf/new_turf = get_turf(target)
|
||||
hopping = TRUE
|
||||
notransform = TRUE
|
||||
new /obj/effect/temp_visual/leaper_crush(new_turf)
|
||||
addtimer(CALLBACK(src, .proc/BellyFlopHop, new_turf), 30)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/BellyFlopHop(turf/T)
|
||||
density = FALSE
|
||||
throw_at(T, get_dist(src,T),1,src, FALSE, callback = CALLBACK(src, .proc/Crush))
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/Crush()
|
||||
hopping = FALSE
|
||||
density = TRUE
|
||||
notransform = FALSE
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1)
|
||||
for(var/mob/living/L in orange(1, src))
|
||||
L.adjustBruteLoss(35)
|
||||
if(!QDELETED(L)) // Some mobs are deleted on death
|
||||
var/throw_dir = get_dir(src, L)
|
||||
if(L.loc == loc)
|
||||
throw_dir = pick(GLOB.alldirs)
|
||||
var/throwtarget = get_edge_target_turf(src, throw_dir)
|
||||
L.throw_at(throwtarget, 3, 1)
|
||||
visible_message("<span class='warning'>[L] is thrown clear of [src]!</span>")
|
||||
if(ckey)//Lessens ability to chain stun as a player
|
||||
ranged_cooldown = ranged_cooldown_time + world.time
|
||||
update_icons()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/Goto()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/throw_impact()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/update_icons()
|
||||
. = ..()
|
||||
if(stat)
|
||||
icon_state = "leaper_dead"
|
||||
return
|
||||
if(ranged_cooldown <= world.time)
|
||||
if(AIStatus == AI_ON && projectile_ready || ckey)
|
||||
icon_state = "leaper_alert"
|
||||
return
|
||||
icon_state = "leaper"
|
||||
|
||||
#undef PLAYER_HOP_DELAY
|
||||
@@ -0,0 +1,65 @@
|
||||
//Large and powerful, but timid. It won't engage anything above 50 health, or anything without legcuffs.
|
||||
//It can fire fleshy snares that legcuff anyone that it hits, making them look especially tasty to the arachnid.
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid
|
||||
name = "mega arachnid"
|
||||
desc = "Though physically imposing, it prefers to ambush its prey, and it will only engage with an already crippled opponent."
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "arachnid"
|
||||
icon_living = "arachnid"
|
||||
icon_dead = "arachnid_dead"
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
maxHealth = 300
|
||||
health = 300
|
||||
speed = 1
|
||||
ranged = 1
|
||||
pixel_x = -16
|
||||
move_to_delay = 10
|
||||
aggro_vision_range = 9
|
||||
speak_emote = list("chitters")
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
ranged_cooldown_time = 60
|
||||
projectiletype = /obj/item/projectile/mega_arachnid
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
alpha = 50
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/Life()
|
||||
..()
|
||||
if(target && ranged_cooldown > world.time && iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(!C.legcuffed && C.health < 50)
|
||||
retreat_distance = 9
|
||||
minimum_distance = 9
|
||||
alpha = 125
|
||||
return
|
||||
retreat_distance = 0
|
||||
minimum_distance = 0
|
||||
alpha = 255
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/Aggro()
|
||||
..()
|
||||
alpha = 255
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/LoseAggro()
|
||||
..()
|
||||
alpha = 50
|
||||
|
||||
/obj/item/projectile/mega_arachnid
|
||||
name = "flesh snare"
|
||||
nodamage = 1
|
||||
damage = 0
|
||||
icon_state = "tentacle_end"
|
||||
|
||||
/obj/item/projectile/mega_arachnid/on_hit(atom/target, blocked = FALSE)
|
||||
if(iscarbon(target) && blocked < 100)
|
||||
var/obj/item/restraints/legcuffs/beartrap/mega_arachnid/B = new /obj/item/restraints/legcuffs/beartrap/mega_arachnid(get_turf(target))
|
||||
B.Crossed(target)
|
||||
..()
|
||||
|
||||
/obj/item/restraints/legcuffs/beartrap/mega_arachnid
|
||||
name = "fleshy restraints"
|
||||
desc = "Used by mega arachnids to immobilize their prey."
|
||||
flags_1 = DROPDEL_1
|
||||
icon_state = "tentacle_end"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
@@ -0,0 +1,224 @@
|
||||
#define MOOK_ATTACK_NEUTRAL 0
|
||||
#define MOOK_ATTACK_WARMUP 1
|
||||
#define MOOK_ATTACK_ACTIVE 2
|
||||
#define MOOK_ATTACK_RECOVERY 3
|
||||
#define ATTACK_INTERMISSION_TIME 5
|
||||
|
||||
//Fragile but highly aggressive wanderers that pose a large threat in numbers.
|
||||
//They'll attempt to leap at their target from afar using their hatchets.
|
||||
/mob/living/simple_animal/hostile/jungle/mook
|
||||
name = "wanderer"
|
||||
desc = "This unhealthy looking primitive is wielding a rudimentary hatchet, swinging it with wild abandon. One isn't much of a threat, but in numbers they can quickly overwhelm a superior opponent."
|
||||
icon = 'icons/mob/jungle/mook.dmi'
|
||||
icon_state = "mook"
|
||||
icon_living = "mook"
|
||||
icon_dead = "mook_dead"
|
||||
pixel_x = -16
|
||||
maxHealth = 45
|
||||
health = 45
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
pixel_y = -8
|
||||
ranged = TRUE
|
||||
ranged_cooldown_time = 10
|
||||
pass_flags = LETPASSTHROW
|
||||
robust_searching = TRUE
|
||||
stat_attack = UNCONSCIOUS
|
||||
attack_sound = 'sound/weapons/rapierhit.ogg'
|
||||
death_sound = 'sound/voice/mook_death.ogg'
|
||||
aggro_vision_range = 15 //A little more aggressive once in combat to balance out their really low HP
|
||||
var/attack_state = MOOK_ATTACK_NEUTRAL
|
||||
var/struck_target_leap = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/CanPass(atom/movable/O)
|
||||
if(istype(O, /mob/living/simple_animal/hostile/jungle/mook))
|
||||
var/mob/living/simple_animal/hostile/jungle/mook/M = O
|
||||
if(M.attack_state == MOOK_ATTACK_ACTIVE && M.throwing)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/death()
|
||||
desc = "A deceased primitive. Upon closer inspection, it was suffering from severe cellular degeneration and its garments are machine made..."//Can you guess the twist
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/AttackingTarget()
|
||||
if(isliving(target))
|
||||
if(ranged_cooldown <= world.time && attack_state == MOOK_ATTACK_NEUTRAL)
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated())
|
||||
WarmupAttack(forced_slash_combo = TRUE)
|
||||
return
|
||||
WarmupAttack()
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/Goto()
|
||||
if(attack_state != MOOK_ATTACK_NEUTRAL)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/Move()
|
||||
if(attack_state == MOOK_ATTACK_WARMUP || attack_state == MOOK_ATTACK_RECOVERY)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/WarmupAttack(forced_slash_combo = FALSE)
|
||||
if(attack_state == MOOK_ATTACK_NEUTRAL && target)
|
||||
attack_state = MOOK_ATTACK_WARMUP
|
||||
walk(src,0)
|
||||
update_icons()
|
||||
if(prob(50) && get_dist(src,target) <= 3 || forced_slash_combo)
|
||||
addtimer(CALLBACK(src, .proc/SlashCombo), ATTACK_INTERMISSION_TIME)
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/LeapAttack), ATTACK_INTERMISSION_TIME + rand(0,3))
|
||||
return
|
||||
attack_state = MOOK_ATTACK_RECOVERY
|
||||
ResetNeutral()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/SlashCombo()
|
||||
if(attack_state == MOOK_ATTACK_WARMUP && !stat)
|
||||
attack_state = MOOK_ATTACK_ACTIVE
|
||||
update_icons()
|
||||
SlashAttack()
|
||||
addtimer(CALLBACK(src, .proc/SlashAttack), 3)
|
||||
addtimer(CALLBACK(src, .proc/SlashAttack), 6)
|
||||
addtimer(CALLBACK(src, .proc/AttackRecovery), 9)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/SlashAttack()
|
||||
if(target && !stat && attack_state == MOOK_ATTACK_ACTIVE)
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
var/mob_direction = get_dir(src,target)
|
||||
if(get_dist(src,target) > 1)
|
||||
step(src,mob_direction)
|
||||
if(targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from) && isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.attack_animal(src)
|
||||
return
|
||||
var/swing_turf = get_step(src,mob_direction)
|
||||
new /obj/effect/temp_visual/kinetic_blast(swing_turf)
|
||||
playsound(src, 'sound/weapons/slashmiss.ogg', 50, 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/LeapAttack()
|
||||
if(target && !stat && attack_state == MOOK_ATTACK_WARMUP)
|
||||
attack_state = MOOK_ATTACK_ACTIVE
|
||||
density = FALSE
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
update_icons()
|
||||
new /obj/effect/temp_visual/mook_dust(get_turf(src))
|
||||
playsound(src, 'sound/weapons/thudswoosh.ogg', 25, 1)
|
||||
playsound(src, 'sound/voice/mook_leap_yell.ogg', 100, 1)
|
||||
var/target_turf = get_turf(target)
|
||||
throw_at(target_turf, 7, 1, src, FALSE, callback = CALLBACK(src, .proc/AttackRecovery))
|
||||
return
|
||||
attack_state = MOOK_ATTACK_RECOVERY
|
||||
ResetNeutral()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/AttackRecovery()
|
||||
if(attack_state == MOOK_ATTACK_ACTIVE && !stat)
|
||||
attack_state = MOOK_ATTACK_RECOVERY
|
||||
density = TRUE
|
||||
face_atom(target)
|
||||
if(!struck_target_leap)
|
||||
update_icons()
|
||||
struck_target_leap = FALSE
|
||||
if(prob(40))
|
||||
attack_state = MOOK_ATTACK_NEUTRAL
|
||||
if(target)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated() && L.stat != DEAD)
|
||||
addtimer(CALLBACK(src, .proc/WarmupAttack, TRUE), ATTACK_INTERMISSION_TIME)
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/WarmupAttack), ATTACK_INTERMISSION_TIME)
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/ResetNeutral), ATTACK_INTERMISSION_TIME)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/ResetNeutral()
|
||||
if(attack_state == MOOK_ATTACK_RECOVERY)
|
||||
attack_state = MOOK_ATTACK_NEUTRAL
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
update_icons()
|
||||
if(target && !stat)
|
||||
update_icons()
|
||||
Goto(target, move_to_delay, minimum_distance)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/throw_impact(atom/hit_atom, throwingdatum)
|
||||
. = ..()
|
||||
if(isliving(hit_atom) && attack_state == MOOK_ATTACK_ACTIVE)
|
||||
var/mob/living/L = hit_atom
|
||||
if(CanAttack(L))
|
||||
L.attack_animal(src)
|
||||
struck_target_leap = TRUE
|
||||
density = TRUE
|
||||
update_icons()
|
||||
var/mook_under_us = FALSE
|
||||
for(var/A in get_turf(src))
|
||||
if(struck_target_leap && mook_under_us)
|
||||
break
|
||||
if(A == src)
|
||||
continue
|
||||
if(isliving(A))
|
||||
var/mob/living/ML = A
|
||||
if(!struck_target_leap && CanAttack(ML))//Check if some joker is attempting to use rest to evade us
|
||||
struck_target_leap = TRUE
|
||||
ML.attack_animal(src)
|
||||
density = TRUE
|
||||
struck_target_leap = TRUE
|
||||
update_icons()
|
||||
continue
|
||||
if(istype(ML, /mob/living/simple_animal/hostile/jungle/mook) && !mook_under_us)//If we land on the same tile as another mook, spread out so we don't stack our sprite on the same tile
|
||||
var/mob/living/simple_animal/hostile/jungle/mook/M = ML
|
||||
if(!M.stat)
|
||||
mook_under_us = TRUE
|
||||
var/anydir = pick(GLOB.cardinals)
|
||||
Move(get_step(src, anydir), anydir)
|
||||
continue
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/handle_automated_action()
|
||||
if(attack_state)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/OpenFire()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated())
|
||||
return
|
||||
WarmupAttack()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/update_icons()
|
||||
. = ..()
|
||||
if(!stat)
|
||||
switch(attack_state)
|
||||
if(MOOK_ATTACK_NEUTRAL)
|
||||
icon_state = "mook"
|
||||
if(MOOK_ATTACK_WARMUP)
|
||||
icon_state = "mook_warmup"
|
||||
if(MOOK_ATTACK_ACTIVE)
|
||||
if(!density)
|
||||
icon_state = "mook_leap"
|
||||
return
|
||||
if(struck_target_leap)
|
||||
icon_state = "mook_strike"
|
||||
return
|
||||
icon_state = "mook_slash_combo"
|
||||
if(MOOK_ATTACK_RECOVERY)
|
||||
icon_state = "mook"
|
||||
|
||||
/obj/effect/temp_visual/mook_dust
|
||||
name = "dust"
|
||||
desc = "it's just a dust cloud!"
|
||||
icon = 'icons/mob/jungle/mook.dmi'
|
||||
icon_state = "mook_leap_cloud"
|
||||
layer = BELOW_MOB_LAYER
|
||||
pixel_x = -16
|
||||
pixel_y = -16
|
||||
duration = 10
|
||||
|
||||
#undef MOOK_ATTACK_NEUTRAL
|
||||
#undef MOOK_ATTACK_WARMUP
|
||||
#undef MOOK_ATTACK_ACTIVE
|
||||
#undef MOOK_ATTACK_RECOVERY
|
||||
#undef ATTACK_INTERMISSION_TIME
|
||||
@@ -0,0 +1,244 @@
|
||||
#define SEEDLING_STATE_NEUTRAL 0
|
||||
#define SEEDLING_STATE_WARMUP 1
|
||||
#define SEEDLING_STATE_ACTIVE 2
|
||||
#define SEEDLING_STATE_RECOVERY 3
|
||||
|
||||
//A plant rooted in the ground that forfeits its melee attack in favor of ranged barrages.
|
||||
//It will fire flurries of solar energy, and occasionally charge up a powerful blast that makes it vulnerable to attack.
|
||||
/mob/living/simple_animal/hostile/jungle/seedling
|
||||
name = "seedling"
|
||||
desc = "This oversized, predatory flower conceals what can only be described as an organic energy cannon, and it will not die until its hidden vital organs are sliced out. \
|
||||
The concentrated streams of energy it sometimes produces require its full attention, attacking it during this time will prevent it from finishing its attack."
|
||||
icon = 'icons/mob/jungle/seedling.dmi'
|
||||
icon_state = "seedling"
|
||||
icon_living = "seedling"
|
||||
icon_dead = "seedling_dead"
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
pixel_x = -16
|
||||
pixel_y = -14
|
||||
minimum_distance = 3
|
||||
move_to_delay = 20
|
||||
vision_range = 9
|
||||
aggro_vision_range = 15
|
||||
ranged = TRUE
|
||||
ranged_cooldown_time = 10
|
||||
projectiletype = /obj/item/projectile/seedling
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
robust_searching = TRUE
|
||||
stat_attack = UNCONSCIOUS
|
||||
anchored = TRUE
|
||||
var/combatant_state = SEEDLING_STATE_NEUTRAL
|
||||
var/obj/seedling_weakpoint/weak_point
|
||||
var/mob/living/beam_debuff_target
|
||||
var/solar_beam_identifier = 0
|
||||
|
||||
/obj/item/projectile/seedling
|
||||
name = "solar energy"
|
||||
icon_state = "seedling"
|
||||
damage = 10
|
||||
damage_type = BURN
|
||||
light_range = 2
|
||||
flag = "energy"
|
||||
light_color = LIGHT_COLOR_YELLOW
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
nondirectional_sprite = TRUE
|
||||
|
||||
/obj/item/projectile/seedling/Collide(atom/A)//Stops seedlings from destroying other jungle mobs through FF
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if("jungle" in L.faction)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/effect/temp_visual/solarbeam_killsat
|
||||
name = "beam of solar energy"
|
||||
icon_state = "solar_beam"
|
||||
icon = 'icons/effects/beam.dmi'
|
||||
layer = LIGHTING_LAYER
|
||||
duration = 5
|
||||
randomdir = FALSE
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator
|
||||
id = "seedling beam indicator"
|
||||
duration = 30
|
||||
status_type = STATUS_EFFECT_MULTIPLE
|
||||
alert_type = null
|
||||
tick_interval = 1
|
||||
var/obj/screen/seedling/seedling_screen_object
|
||||
var/atom/target
|
||||
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/on_creation(mob/living/new_owner, target_plant)
|
||||
. = ..()
|
||||
if(.)
|
||||
target = target_plant
|
||||
tick()
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/on_apply()
|
||||
if(owner.client)
|
||||
seedling_screen_object = new /obj/screen/seedling()
|
||||
owner.client.screen += seedling_screen_object
|
||||
tick()
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/Destroy()
|
||||
if(owner)
|
||||
if(owner.client)
|
||||
owner.client.screen -= seedling_screen_object
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/tick()
|
||||
var/target_angle = Get_Angle(owner, target)
|
||||
var/matrix/final = matrix()
|
||||
final.Turn(target_angle)
|
||||
seedling_screen_object.transform = final
|
||||
|
||||
/obj/screen/seedling
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "seedling_beam_indicator"
|
||||
screen_loc = "CENTER:-16,CENTER:-16"
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/Goto()
|
||||
if(combatant_state != SEEDLING_STATE_NEUTRAL)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/AttackingTarget()
|
||||
if(isliving(target))
|
||||
if(ranged_cooldown <= world.time && combatant_state == SEEDLING_STATE_NEUTRAL)
|
||||
OpenFire(target)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/OpenFire()
|
||||
WarmupAttack()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/WarmupAttack()
|
||||
if(combatant_state == SEEDLING_STATE_NEUTRAL)
|
||||
combatant_state = SEEDLING_STATE_WARMUP
|
||||
walk(src,0)
|
||||
update_icons()
|
||||
var/target_dist = get_dist(src,target)
|
||||
var/living_target_check = isliving(target)
|
||||
if(living_target_check)
|
||||
if(target_dist > 7)//Offscreen check
|
||||
SolarBeamStartup(target)
|
||||
return
|
||||
if(get_dist(src,target) >= 4 && prob(40))
|
||||
SolarBeamStartup(target)
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/Volley), 5)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/SolarBeamStartup(mob/living/living_target)//It's more like requiem than final spark
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP && target)
|
||||
combatant_state = SEEDLING_STATE_ACTIVE
|
||||
living_target.apply_status_effect(/datum/status_effect/seedling_beam_indicator, src)
|
||||
beam_debuff_target = living_target
|
||||
playsound(src,'sound/effects/seedling_chargeup.ogg', 100, 0)
|
||||
if(get_dist(src,living_target) > 7)
|
||||
playsound(living_target,'sound/effects/seedling_chargeup.ogg', 100, 0)
|
||||
solar_beam_identifier = world.time
|
||||
addtimer(CALLBACK(src, .proc/Beamu, living_target, solar_beam_identifier), 35)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/Beamu(mob/living/living_target, beam_id = 0)
|
||||
if(combatant_state == SEEDLING_STATE_ACTIVE && living_target && beam_id == solar_beam_identifier)
|
||||
if(living_target.z == z)
|
||||
update_icons()
|
||||
var/obj/effect/temp_visual/solarbeam_killsat/S = new (get_turf(src))
|
||||
var/matrix/starting = matrix()
|
||||
starting.Scale(1,32)
|
||||
starting.Translate(0,520)
|
||||
S.transform = starting
|
||||
var/obj/effect/temp_visual/solarbeam_killsat/K = new (get_turf(living_target))
|
||||
var/matrix/final = matrix()
|
||||
final.Scale(1,32)
|
||||
final.Translate(0,512)
|
||||
K.transform = final
|
||||
living_target.adjustFireLoss(30)
|
||||
living_target.adjust_fire_stacks(0.2)//Just here for the showmanship
|
||||
living_target.IgniteMob()
|
||||
playsound(living_target,'sound/weapons/sear.ogg', 50, 1)
|
||||
addtimer(CALLBACK(src, .proc/AttackRecovery), 5)
|
||||
return
|
||||
AttackRecovery()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/Volley()
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP && target)
|
||||
combatant_state = SEEDLING_STATE_ACTIVE
|
||||
update_icons()
|
||||
var/datum/callback/cb = CALLBACK(src, .proc/InaccurateShot)
|
||||
for(var/i in 1 to 13)
|
||||
addtimer(cb, i)
|
||||
addtimer(CALLBACK(src, .proc/AttackRecovery), 14)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/InaccurateShot()
|
||||
if(!QDELETED(target) && combatant_state == SEEDLING_STATE_ACTIVE && !stat)
|
||||
if(get_dist(src,target) <= 3)//If they're close enough just aim straight at them so we don't miss at point blank ranges
|
||||
Shoot(target)
|
||||
return
|
||||
var/turf/our_turf = get_turf(src)
|
||||
var/obj/item/projectile/seedling/readied_shot = new /obj/item/projectile/seedling(our_turf)
|
||||
readied_shot.current = our_turf
|
||||
readied_shot.starting = our_turf
|
||||
readied_shot.firer = src
|
||||
readied_shot.original = target
|
||||
readied_shot.yo = target.y - our_turf.y + rand(-1,1)
|
||||
readied_shot.xo = target.x - our_turf.x + rand(-1,1)
|
||||
readied_shot.fire()
|
||||
playsound(src, projectilesound, 100, 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/AttackRecovery()
|
||||
if(combatant_state == SEEDLING_STATE_ACTIVE)
|
||||
combatant_state = SEEDLING_STATE_RECOVERY
|
||||
update_icons()
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
if(target)
|
||||
face_atom(target)
|
||||
addtimer(CALLBACK(src, .proc/ResetNeutral), 10)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/ResetNeutral()
|
||||
combatant_state = SEEDLING_STATE_NEUTRAL
|
||||
if(target && !stat)
|
||||
update_icons()
|
||||
Goto(target, move_to_delay, minimum_distance)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/adjustHealth()
|
||||
. = ..()
|
||||
if(combatant_state == SEEDLING_STATE_ACTIVE && beam_debuff_target)
|
||||
beam_debuff_target.remove_status_effect(/datum/status_effect/seedling_beam_indicator)
|
||||
beam_debuff_target = null
|
||||
solar_beam_identifier = 0
|
||||
AttackRecovery()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/update_icons()
|
||||
. = ..()
|
||||
if(!stat)
|
||||
switch(combatant_state)
|
||||
if(SEEDLING_STATE_NEUTRAL)
|
||||
icon_state = "seedling"
|
||||
if(SEEDLING_STATE_WARMUP)
|
||||
icon_state = "seedling_charging"
|
||||
if(SEEDLING_STATE_ACTIVE)
|
||||
icon_state = "seedling_fire"
|
||||
if(SEEDLING_STATE_RECOVERY)
|
||||
icon_state = "seedling"
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/GiveTarget()
|
||||
if(target)
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP || combatant_state == SEEDLING_STATE_ACTIVE)//So it doesn't 180 and blast you in the face while it's firing at someone else
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/LoseTarget()
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP || combatant_state == SEEDLING_STATE_ACTIVE)
|
||||
return
|
||||
return ..()
|
||||
|
||||
#undef SEEDLING_STATE_NEUTRAL
|
||||
#undef SEEDLING_STATE_WARMUP
|
||||
#undef SEEDLING_STATE_ACTIVE
|
||||
#undef SEEDLING_STATE_RECOVERY
|
||||
@@ -1,833 +0,0 @@
|
||||
/mob/living/simple_animal/hostile/jungle
|
||||
vision_range = 5
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
faction = list("jungle")
|
||||
weather_immunities = list("acid")
|
||||
obj_damage = 30
|
||||
environment_smash = ENVIRONMENT_SMASH_WALLS
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 450
|
||||
response_help = "pokes"
|
||||
response_disarm = "shoves"
|
||||
response_harm = "strikes"
|
||||
status_flags = 0
|
||||
a_intent = INTENT_HARM
|
||||
see_in_dark = 4
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
|
||||
|
||||
|
||||
//Mega arachnid
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid
|
||||
name = "mega arachnid"
|
||||
desc = "Though physically imposing, it prefers to ambush its prey, and it will only engage with an already crippled opponent."
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
maxHealth = 300
|
||||
health = 300
|
||||
speed = 1
|
||||
ranged = 1
|
||||
pixel_x = -16
|
||||
move_to_delay = 10
|
||||
aggro_vision_range = 9
|
||||
speak_emote = list("chitters")
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
ranged_cooldown_time = 60
|
||||
projectiletype = /obj/item/projectile/mega_arachnid
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "arachnid"
|
||||
icon_living = "arachnid"
|
||||
icon_dead = "dead_purple"
|
||||
alpha = 50
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/Life()
|
||||
..()
|
||||
if(target && ranged_cooldown > world.time && iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(!C.legcuffed && C.health < 50)
|
||||
retreat_distance = 9
|
||||
minimum_distance = 9
|
||||
alpha = 125
|
||||
return
|
||||
retreat_distance = 0
|
||||
minimum_distance = 0
|
||||
alpha = 255
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/Aggro()
|
||||
..()
|
||||
alpha = 255
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/LoseAggro()
|
||||
..()
|
||||
alpha = 50
|
||||
|
||||
/obj/item/projectile/mega_arachnid
|
||||
name = "flesh snare"
|
||||
nodamage = 1
|
||||
damage = 0
|
||||
icon_state = "tentacle_end"
|
||||
|
||||
/obj/item/projectile/mega_arachnid/on_hit(atom/target, blocked = FALSE)
|
||||
if(iscarbon(target) && blocked < 100)
|
||||
var/obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid/B = new /obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid(get_turf(target))
|
||||
B.Crossed(target)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid
|
||||
name = "fleshy restraints"
|
||||
desc = "Used by mega arachnids to immobilize their prey."
|
||||
flags = DROPDEL
|
||||
icon_state = "tentacle_end"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
|
||||
////Leaper////
|
||||
|
||||
#define PLAYER_HOP_DELAY 25
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
faction = list("jungle")
|
||||
weather_immunities = list("acid")
|
||||
obj_damage = 30
|
||||
environment_smash = ENVIRONMENT_SMASH_WALLS
|
||||
maxHealth = 300
|
||||
health = 300
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 450
|
||||
response_help = "pokes"
|
||||
response_disarm = "shoves"
|
||||
response_harm = "strikes"
|
||||
status_flags = 0
|
||||
a_intent = INTENT_HARM
|
||||
see_in_dark = 4
|
||||
ranged = TRUE
|
||||
projectiletype = /obj/item/projectile/leaper
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
ranged_cooldown_time = 30
|
||||
pixel_x = -16
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "leaper"
|
||||
icon_living = "leaper"
|
||||
icon_dead = "leaper_dead"
|
||||
layer = LARGE_MOB_LAYER
|
||||
name = "leaper"
|
||||
desc = "Commonly referred to as 'leapers', the Geron Toad is a massive beast that spits out highly pressurized bubbles containing a unique toxin, knocking down its prey and then crushing it with its girth."
|
||||
speed = 10
|
||||
stat_attack = 1
|
||||
robust_searching = 1
|
||||
var/hopping = FALSE
|
||||
var/hop_cooldown = 0 //Strictly for player controlled leapers
|
||||
var/projectile_ready = FALSE //Stopping AI leapers from firing whenever they want, and only doing it after a hop has finished instead
|
||||
|
||||
/obj/item/projectile/leaper
|
||||
name = "leaper bubble"
|
||||
icon_state = "leaper"
|
||||
knockdown = 50
|
||||
damage = 0
|
||||
range = 7
|
||||
hitsound = 'sound/effects/snap.ogg'
|
||||
nondirectional_sprite = TRUE
|
||||
impact_effect_type = /obj/effect/temp_visual/leaper_projectile_impact
|
||||
|
||||
/obj/item/projectile/leaper/on_hit(atom/target, blocked = FALSE)
|
||||
..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
C.reagents.add_reagent("leaper_venom", 5)
|
||||
return
|
||||
if(isanimal(target))
|
||||
var/mob/living/simple_animal/L = target
|
||||
L.adjustHealth(25)
|
||||
|
||||
/obj/item/projectile/leaper/on_range()
|
||||
var/turf/T = get_turf(src)
|
||||
..()
|
||||
new /obj/structure/leaper_bubble(T)
|
||||
|
||||
/obj/effect/temp_visual/leaper_projectile_impact
|
||||
name = "leaper bubble"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "leaper_bubble_pop"
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
duration = 3
|
||||
|
||||
/obj/effect/temp_visual/leaper_projectile_impact/Initialize()
|
||||
. = ..()
|
||||
new /obj/effect/decal/cleanable/leaper_sludge(get_turf(src))
|
||||
|
||||
/obj/effect/decal/cleanable/leaper_sludge
|
||||
name = "leaper sludge"
|
||||
desc = "A small pool of sludge, containing trace amounts of leaper venom"
|
||||
icon = 'icons/effects/tomatodecal.dmi'
|
||||
icon_state = "tomato_floor1"
|
||||
|
||||
/obj/structure/leaper_bubble
|
||||
name = "leaper bubble"
|
||||
desc = "A floating bubble containing leaper venom, the contents are under a surprising amount of pressure."
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "leaper"
|
||||
max_integrity = 10
|
||||
density = FALSE
|
||||
|
||||
/obj/structure/leaper_bubble/Initialize()
|
||||
. = ..()
|
||||
float(on = TRUE)
|
||||
QDEL_IN(src, 100)
|
||||
|
||||
/obj/structure/leaper_bubble/Destroy()
|
||||
new /obj/effect/temp_visual/leaper_projectile_impact(get_turf(src))
|
||||
playsound(src,'sound/effects/snap.ogg',50, 1, -1)
|
||||
return ..()
|
||||
|
||||
/obj/structure/leaper_bubble/Crossed(atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!istype(L, /mob/living/simple_animal/hostile/jungle/leaper))
|
||||
playsound(src,'sound/effects/snap.ogg',50, 1, -1)
|
||||
L.Knockdown(50)
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
C.reagents.add_reagent("leaper_venom", 5)
|
||||
if(isanimal(L))
|
||||
var/mob/living/simple_animal/A = L
|
||||
A.adjustHealth(25)
|
||||
qdel(src)
|
||||
return ..()
|
||||
|
||||
/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
|
||||
taste_description = "french cuisine"
|
||||
taste_mult = 1.3
|
||||
|
||||
/datum/reagent/toxin/leaper_venom/on_mob_life(mob/living/M)
|
||||
if(volume >= 10)
|
||||
M.adjustToxLoss(5, 0)
|
||||
..()
|
||||
|
||||
/obj/effect/temp_visual/leaper_crush
|
||||
name = "Grim tidings"
|
||||
desc = "Incoming leaper!"
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "lily_pad"
|
||||
layer = BELOW_MOB_LAYER
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
duration = 30
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/Initialize()
|
||||
. = ..()
|
||||
verbs -= /mob/living/verb/pulled
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/CtrlClickOn(atom/A)
|
||||
face_atom(A)
|
||||
target = A
|
||||
if(!isturf(loc))
|
||||
return
|
||||
if(next_move > world.time)
|
||||
return
|
||||
if(hopping)
|
||||
return
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(L.incapacitated())
|
||||
BellyFlop()
|
||||
return
|
||||
if(hop_cooldown <= world.time)
|
||||
Hop(player_hop = TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/AttackingTarget()
|
||||
if(isliving(target))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/handle_automated_action()
|
||||
if(hopping || projectile_ready)
|
||||
return
|
||||
. = ..()
|
||||
if(target)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated())
|
||||
BellyFlop()
|
||||
return
|
||||
if(!hopping)
|
||||
Hop()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/Life()
|
||||
. = ..()
|
||||
update_icons()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(prob(33) && !ckey)
|
||||
ranged_cooldown = 0 //Keeps em on their toes instead of a constant rotation
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/OpenFire()
|
||||
face_atom(target)
|
||||
if(ranged_cooldown <= world.time)
|
||||
if(ckey)
|
||||
if(hopping)
|
||||
return
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated())
|
||||
return //No stunlocking. Hop on them after you stun them, you donk.
|
||||
if(AIStatus == AI_ON && !projectile_ready && !ckey)
|
||||
return
|
||||
. = ..(target)
|
||||
projectile_ready = FALSE
|
||||
update_icons()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/Hop(player_hop = FALSE)
|
||||
if(z != target.z)
|
||||
return
|
||||
hopping = TRUE
|
||||
density = FALSE
|
||||
pass_flags |= PASSMOB
|
||||
notransform = TRUE
|
||||
var/turf/new_turf = locate((target.x + rand(-3,3)),(target.y + rand(-3,3)),target.z)
|
||||
if(player_hop)
|
||||
new_turf = get_turf(target)
|
||||
hop_cooldown = world.time + PLAYER_HOP_DELAY
|
||||
if(AIStatus == AI_ON && ranged_cooldown <= world.time)
|
||||
projectile_ready = TRUE
|
||||
update_icons()
|
||||
throw_at(new_turf, max(3,get_dist(src,new_turf)), 1, src, FALSE, callback = CALLBACK(src, .FinishHop))
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/FinishHop()
|
||||
density = TRUE
|
||||
notransform = FALSE
|
||||
pass_flags &= ~PASSMOB
|
||||
hopping = FALSE
|
||||
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 100, 1)
|
||||
if(target && AIStatus == AI_ON && projectile_ready && !ckey)
|
||||
face_atom(target)
|
||||
addtimer(CALLBACK(src, .proc/OpenFire, target), 5)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/BellyFlop()
|
||||
var/turf/new_turf = get_turf(target)
|
||||
hopping = TRUE
|
||||
notransform = TRUE
|
||||
new /obj/effect/temp_visual/leaper_crush(new_turf)
|
||||
addtimer(CALLBACK(src, .proc/BellyFlopHop, new_turf), 30)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/BellyFlopHop(turf/T)
|
||||
density = FALSE
|
||||
throw_at(T, get_dist(src,T),1,src, FALSE, callback = CALLBACK(src, .proc/Crush))
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/proc/Crush()
|
||||
hopping = FALSE
|
||||
density = TRUE
|
||||
notransform = FALSE
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1)
|
||||
for(var/mob/living/L in orange(1, src))
|
||||
L.adjustBruteLoss(35)
|
||||
if(!QDELETED(L)) // Some mobs are deleted on death
|
||||
var/throw_dir = get_dir(src, L)
|
||||
if(L.loc == loc)
|
||||
throw_dir = pick(GLOB.alldirs)
|
||||
var/throwtarget = get_edge_target_turf(src, throw_dir)
|
||||
L.throw_at(throwtarget, 3, 1)
|
||||
visible_message("<span class='warning'>[L] is thrown clear of [src]!</span>")
|
||||
if(ckey)//Lessens ability to chain stun as a player
|
||||
ranged_cooldown = ranged_cooldown_time + world.time
|
||||
update_icons()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/Goto()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/throw_impact()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/update_icons()
|
||||
. = ..()
|
||||
if(stat)
|
||||
icon_state = "leaper_dead"
|
||||
return
|
||||
if(ranged_cooldown <= world.time)
|
||||
if(AIStatus == AI_ON && projectile_ready || ckey)
|
||||
icon_state = "leaper_alert"
|
||||
return
|
||||
icon_state = "leaper"
|
||||
|
||||
#undef PLAYER_HOP_DELAY
|
||||
|
||||
////JUNGLE MOOK////
|
||||
|
||||
#define MOOK_ATTACK_NEUTRAL 0
|
||||
#define MOOK_ATTACK_WARMUP 1
|
||||
#define MOOK_ATTACK_ACTIVE 2
|
||||
#define MOOK_ATTACK_RECOVERY 3
|
||||
|
||||
#define ATTACK_INTERMISSION_TIME 5
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook
|
||||
name = "wanderer"
|
||||
desc = "This unhealthy looking primitive is wielding a rudimentary hatchet, swinging it with wild abandon. One isn't much of a threat, but in numbers they can quickly overwhelm a superior opponent."
|
||||
maxHealth = 45
|
||||
health = 45
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "mook"
|
||||
icon_living = "mook"
|
||||
icon_dead = "mook_dead"
|
||||
pixel_x = -16
|
||||
pixel_y = -8
|
||||
ranged = TRUE
|
||||
ranged_cooldown_time = 10
|
||||
pass_flags = LETPASSTHROW
|
||||
robust_searching = TRUE
|
||||
stat_attack = UNCONSCIOUS
|
||||
attack_sound = 'sound/weapons/rapierhit.ogg'
|
||||
death_sound = 'sound/voice/mook_death.ogg'
|
||||
aggro_vision_range = 15 //A little more aggressive once in combat to balance out their really low HP
|
||||
var/attack_state = MOOK_ATTACK_NEUTRAL
|
||||
var/struck_target_leap = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/CanPass(atom/movable/O)
|
||||
if(istype(O, /mob/living/simple_animal/hostile/jungle/mook))
|
||||
var/mob/living/simple_animal/hostile/jungle/mook/M = O
|
||||
if(M.attack_state == MOOK_ATTACK_ACTIVE && M.throwing)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/death()
|
||||
desc = "A deceased primitive. Upon closer inspection, it was suffering from severe cellular degeneration and its garments are machine made..."//Can you guess the twist
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/AttackingTarget()
|
||||
if(isliving(target))
|
||||
if(ranged_cooldown <= world.time && attack_state == MOOK_ATTACK_NEUTRAL)
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated())
|
||||
WarmupAttack(forced_slash_combo = TRUE)
|
||||
return
|
||||
WarmupAttack()
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/Goto()
|
||||
if(attack_state != MOOK_ATTACK_NEUTRAL)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/Move()
|
||||
if(attack_state == MOOK_ATTACK_WARMUP || attack_state == MOOK_ATTACK_RECOVERY)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/WarmupAttack(forced_slash_combo = FALSE)
|
||||
if(attack_state == MOOK_ATTACK_NEUTRAL && target)
|
||||
attack_state = MOOK_ATTACK_WARMUP
|
||||
walk(src,0)
|
||||
update_icons()
|
||||
if(prob(50) && get_dist(src,target) <= 3 || forced_slash_combo)
|
||||
addtimer(CALLBACK(src, .proc/SlashCombo), ATTACK_INTERMISSION_TIME)
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/LeapAttack), ATTACK_INTERMISSION_TIME + rand(0,3))
|
||||
return
|
||||
attack_state = MOOK_ATTACK_RECOVERY
|
||||
ResetNeutral()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/SlashCombo()
|
||||
if(attack_state == MOOK_ATTACK_WARMUP && !stat)
|
||||
attack_state = MOOK_ATTACK_ACTIVE
|
||||
update_icons()
|
||||
SlashAttack()
|
||||
addtimer(CALLBACK(src, .proc/SlashAttack), 3)
|
||||
addtimer(CALLBACK(src, .proc/SlashAttack), 6)
|
||||
addtimer(CALLBACK(src, .proc/AttackRecovery), 9)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/SlashAttack()
|
||||
if(target && !stat && attack_state == MOOK_ATTACK_ACTIVE)
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
var/mob_direction = get_dir(src,target)
|
||||
if(get_dist(src,target) > 1)
|
||||
step(src,mob_direction)
|
||||
if(targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from) && isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.attack_animal(src)
|
||||
return
|
||||
var/swing_turf = get_step(src,mob_direction)
|
||||
new /obj/effect/temp_visual/kinetic_blast(swing_turf)
|
||||
playsound(src, 'sound/weapons/slashmiss.ogg', 50, 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/LeapAttack()
|
||||
if(target && !stat && attack_state == MOOK_ATTACK_WARMUP)
|
||||
attack_state = MOOK_ATTACK_ACTIVE
|
||||
density = FALSE
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
update_icons()
|
||||
new /obj/effect/temp_visual/mook_dust(get_turf(src))
|
||||
playsound(src, 'sound/weapons/thudswoosh.ogg', 25, 1)
|
||||
playsound(src, 'sound/voice/mook_leap_yell.ogg', 100, 1)
|
||||
var/target_turf = get_turf(target)
|
||||
throw_at(target_turf, 7, 1, src, FALSE, callback = CALLBACK(src, .proc/AttackRecovery))
|
||||
return
|
||||
attack_state = MOOK_ATTACK_RECOVERY
|
||||
ResetNeutral()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/AttackRecovery()
|
||||
if(attack_state == MOOK_ATTACK_ACTIVE && !stat)
|
||||
attack_state = MOOK_ATTACK_RECOVERY
|
||||
density = TRUE
|
||||
face_atom(target)
|
||||
if(!struck_target_leap)
|
||||
update_icons()
|
||||
struck_target_leap = FALSE
|
||||
if(prob(40))
|
||||
attack_state = MOOK_ATTACK_NEUTRAL
|
||||
if(target)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated() && L.stat != DEAD)
|
||||
addtimer(CALLBACK(src, .proc/WarmupAttack, TRUE), ATTACK_INTERMISSION_TIME)
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/WarmupAttack), ATTACK_INTERMISSION_TIME)
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/ResetNeutral), ATTACK_INTERMISSION_TIME)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/proc/ResetNeutral()
|
||||
if(attack_state == MOOK_ATTACK_RECOVERY)
|
||||
attack_state = MOOK_ATTACK_NEUTRAL
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
update_icons()
|
||||
if(target && !stat)
|
||||
update_icons()
|
||||
Goto(target, move_to_delay, minimum_distance)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/throw_impact(atom/hit_atom, throwingdatum)
|
||||
. = ..()
|
||||
if(isliving(hit_atom) && attack_state == MOOK_ATTACK_ACTIVE)
|
||||
var/mob/living/L = hit_atom
|
||||
if(CanAttack(L))
|
||||
L.attack_animal(src)
|
||||
struck_target_leap = TRUE
|
||||
density = TRUE
|
||||
update_icons()
|
||||
var/mook_under_us = FALSE
|
||||
for(var/A in get_turf(src))
|
||||
if(struck_target_leap && mook_under_us)
|
||||
break
|
||||
if(A == src)
|
||||
continue
|
||||
if(isliving(A))
|
||||
var/mob/living/ML = A
|
||||
if(!struck_target_leap && CanAttack(ML))//Check if some joker is attempting to use rest to evade us
|
||||
struck_target_leap = TRUE
|
||||
ML.attack_animal(src)
|
||||
density = TRUE
|
||||
struck_target_leap = TRUE
|
||||
update_icons()
|
||||
continue
|
||||
if(istype(ML, /mob/living/simple_animal/hostile/jungle/mook) && !mook_under_us)//If we land on the same tile as another mook, spread out so we don't stack our sprite on the same tile
|
||||
var/mob/living/simple_animal/hostile/jungle/mook/M = ML
|
||||
if(!M.stat)
|
||||
mook_under_us = TRUE
|
||||
var/anydir = pick(GLOB.cardinals)
|
||||
Move(get_step(src, anydir), anydir)
|
||||
continue
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/handle_automated_action()
|
||||
if(attack_state)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/OpenFire()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.incapacitated())
|
||||
return
|
||||
WarmupAttack()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mook/update_icons()
|
||||
. = ..()
|
||||
if(!stat)
|
||||
switch(attack_state)
|
||||
if(MOOK_ATTACK_NEUTRAL)
|
||||
icon_state = "mook"
|
||||
if(MOOK_ATTACK_WARMUP)
|
||||
icon_state = "mook_warmup"
|
||||
if(MOOK_ATTACK_ACTIVE)
|
||||
if(!density)
|
||||
icon_state = "mook_leap"
|
||||
return
|
||||
if(struck_target_leap)
|
||||
icon_state = "mook_strike"
|
||||
return
|
||||
icon_state = "mook_slash_combo"
|
||||
if(MOOK_ATTACK_RECOVERY)
|
||||
icon_state = "mook"
|
||||
|
||||
/obj/effect/temp_visual/mook_dust
|
||||
name = "dust"
|
||||
desc = "it's just a dust cloud!"
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "mook_leap_cloud"
|
||||
layer = BELOW_MOB_LAYER
|
||||
pixel_x = -16
|
||||
pixel_y = -16
|
||||
duration = 10
|
||||
|
||||
#undef MOOK_ATTACK_NEUTRAL
|
||||
#undef MOOK_ATTACK_WARMUP
|
||||
#undef MOOK_ATTACK_ACTIVE
|
||||
#undef MOOK_ATTACK_RECOVERY
|
||||
#undef ATTACK_INTERMISSION_TIME
|
||||
|
||||
////Jungle Seedling////
|
||||
|
||||
#define SEEDLING_STATE_NEUTRAL 0
|
||||
#define SEEDLING_STATE_WARMUP 1
|
||||
#define SEEDLING_STATE_ACTIVE 2
|
||||
#define SEEDLING_STATE_RECOVERY 3
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling
|
||||
name = "seedling"
|
||||
desc = "This oversized, predatory flower conceals what can only be described as an organic energy cannon, and it will not die until its hidden vital organs are sliced out. \
|
||||
The concentrated streams of energy it sometimes produces require its full attention, attacking it during this time will prevent it from finishing its attack."
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "seedling"
|
||||
icon_living = "seedling"
|
||||
icon_dead = "seedling_dead"
|
||||
pixel_x = -16
|
||||
pixel_y = -14
|
||||
minimum_distance = 3
|
||||
move_to_delay = 20
|
||||
vision_range = 9
|
||||
aggro_vision_range = 15
|
||||
ranged = TRUE
|
||||
ranged_cooldown_time = 10
|
||||
projectiletype = /obj/item/projectile/seedling
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
robust_searching = TRUE
|
||||
stat_attack = UNCONSCIOUS
|
||||
anchored = TRUE
|
||||
var/combatant_state = SEEDLING_STATE_NEUTRAL
|
||||
var/obj/seedling_weakpoint/weak_point
|
||||
var/mob/living/beam_debuff_target
|
||||
var/solar_beam_identifier = 0
|
||||
|
||||
/obj/item/projectile/seedling
|
||||
name = "solar energy"
|
||||
icon_state = "seedling"
|
||||
damage = 10
|
||||
damage_type = BURN
|
||||
light_range = 2
|
||||
flag = "energy"
|
||||
light_color = LIGHT_COLOR_YELLOW
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
nondirectional_sprite = TRUE
|
||||
|
||||
/obj/item/projectile/seedling/Collide(atom/A)//Stops seedlings from destroying other jungle mobs through FF
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if("jungle" in L.faction)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/effect/temp_visual/solarbeam_killsat
|
||||
name = "beam of solar energy"
|
||||
icon_state = "solar_beam"
|
||||
icon = 'icons/effects/beam.dmi'
|
||||
layer = LIGHTING_LAYER
|
||||
duration = 5
|
||||
randomdir = FALSE
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator
|
||||
id = "seedling beam indicator"
|
||||
duration = 30
|
||||
status_type = STATUS_EFFECT_MULTIPLE
|
||||
alert_type = null
|
||||
tick_interval = 1
|
||||
var/obj/screen/seedling/seedling_screen_object
|
||||
var/atom/target
|
||||
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/on_creation(mob/living/new_owner, target_plant)
|
||||
. = ..()
|
||||
if(.)
|
||||
target = target_plant
|
||||
tick()
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/on_apply()
|
||||
if(owner.client)
|
||||
seedling_screen_object = new /obj/screen/seedling()
|
||||
owner.client.screen += seedling_screen_object
|
||||
tick()
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/Destroy()
|
||||
if(owner)
|
||||
if(owner.client)
|
||||
owner.client.screen -= seedling_screen_object
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/tick()
|
||||
var/target_angle = Get_Angle(owner, target)
|
||||
var/matrix/final = matrix()
|
||||
final.Turn(target_angle)
|
||||
seedling_screen_object.transform = final
|
||||
|
||||
/obj/screen/seedling
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "seedling_beam_indicator"
|
||||
screen_loc = "CENTER:-16,CENTER:-16"
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/Goto()
|
||||
if(combatant_state != SEEDLING_STATE_NEUTRAL)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/AttackingTarget()
|
||||
if(isliving(target))
|
||||
if(ranged_cooldown <= world.time && combatant_state == SEEDLING_STATE_NEUTRAL)
|
||||
OpenFire(target)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/OpenFire()
|
||||
WarmupAttack()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/WarmupAttack()
|
||||
if(combatant_state == SEEDLING_STATE_NEUTRAL)
|
||||
combatant_state = SEEDLING_STATE_WARMUP
|
||||
walk(src,0)
|
||||
update_icons()
|
||||
var/target_dist = get_dist(src,target)
|
||||
var/living_target_check = isliving(target)
|
||||
if(living_target_check)
|
||||
if(target_dist > 7)//Offscreen check
|
||||
SolarBeamStartup(target)
|
||||
return
|
||||
if(get_dist(src,target) >= 4 && prob(40))
|
||||
SolarBeamStartup(target)
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/Volley), 5)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/SolarBeamStartup(mob/living/living_target)//It's more like requiem than final spark
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP && target)
|
||||
combatant_state = SEEDLING_STATE_ACTIVE
|
||||
living_target.apply_status_effect(/datum/status_effect/seedling_beam_indicator, src)
|
||||
beam_debuff_target = living_target
|
||||
playsound(src,'sound/effects/seedling_chargeup.ogg', 100, 0)
|
||||
if(get_dist(src,living_target) > 7)
|
||||
playsound(living_target,'sound/effects/seedling_chargeup.ogg', 100, 0)
|
||||
solar_beam_identifier = world.time
|
||||
addtimer(CALLBACK(src, .proc/Beamu, living_target, solar_beam_identifier), 35)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/Beamu(mob/living/living_target, beam_id = 0)
|
||||
if(combatant_state == SEEDLING_STATE_ACTIVE && living_target && beam_id == solar_beam_identifier)
|
||||
if(living_target.z == z)
|
||||
update_icons()
|
||||
var/obj/effect/temp_visual/solarbeam_killsat/S = new (get_turf(src))
|
||||
var/matrix/starting = matrix()
|
||||
starting.Scale(1,32)
|
||||
starting.Translate(0,520)
|
||||
S.transform = starting
|
||||
var/obj/effect/temp_visual/solarbeam_killsat/K = new (get_turf(living_target))
|
||||
var/matrix/final = matrix()
|
||||
final.Scale(1,32)
|
||||
final.Translate(0,512)
|
||||
K.transform = final
|
||||
living_target.adjustFireLoss(30)
|
||||
living_target.adjust_fire_stacks(0.2)//Just here for the showmanship
|
||||
living_target.IgniteMob()
|
||||
playsound(living_target,'sound/weapons/sear.ogg', 50, 1)
|
||||
addtimer(CALLBACK(src, .proc/AttackRecovery), 5)
|
||||
return
|
||||
AttackRecovery()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/Volley()
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP && target)
|
||||
combatant_state = SEEDLING_STATE_ACTIVE
|
||||
update_icons()
|
||||
var/datum/callback/cb = CALLBACK(src, .proc/InaccurateShot)
|
||||
for(var/i in 1 to 13)
|
||||
addtimer(cb, i)
|
||||
addtimer(CALLBACK(src, .proc/AttackRecovery), 14)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/InaccurateShot()
|
||||
if(!QDELETED(target) && combatant_state == SEEDLING_STATE_ACTIVE && !stat)
|
||||
if(get_dist(src,target) <= 3)//If they're close enough just aim straight at them so we don't miss at point blank ranges
|
||||
Shoot(target)
|
||||
return
|
||||
var/turf/our_turf = get_turf(src)
|
||||
var/obj/item/projectile/seedling/readied_shot = new /obj/item/projectile/seedling(our_turf)
|
||||
readied_shot.current = our_turf
|
||||
readied_shot.starting = our_turf
|
||||
readied_shot.firer = src
|
||||
readied_shot.original = target
|
||||
readied_shot.yo = target.y - our_turf.y + rand(-1,1)
|
||||
readied_shot.xo = target.x - our_turf.x + rand(-1,1)
|
||||
readied_shot.fire()
|
||||
playsound(src, projectilesound, 100, 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/AttackRecovery()
|
||||
if(combatant_state == SEEDLING_STATE_ACTIVE)
|
||||
combatant_state = SEEDLING_STATE_RECOVERY
|
||||
update_icons()
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
if(target)
|
||||
face_atom(target)
|
||||
addtimer(CALLBACK(src, .proc/ResetNeutral), 10)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/proc/ResetNeutral()
|
||||
combatant_state = SEEDLING_STATE_NEUTRAL
|
||||
if(target && !stat)
|
||||
update_icons()
|
||||
Goto(target, move_to_delay, minimum_distance)
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/adjustHealth()
|
||||
. = ..()
|
||||
if(combatant_state == SEEDLING_STATE_ACTIVE && beam_debuff_target)
|
||||
beam_debuff_target.remove_status_effect(/datum/status_effect/seedling_beam_indicator)
|
||||
beam_debuff_target = null
|
||||
solar_beam_identifier = 0
|
||||
AttackRecovery()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/update_icons()
|
||||
. = ..()
|
||||
if(!stat)
|
||||
switch(combatant_state)
|
||||
if(SEEDLING_STATE_NEUTRAL)
|
||||
icon_state = "seedling"
|
||||
if(SEEDLING_STATE_WARMUP)
|
||||
icon_state = "seedling_charging"
|
||||
if(SEEDLING_STATE_ACTIVE)
|
||||
icon_state = "seedling_fire"
|
||||
if(SEEDLING_STATE_RECOVERY)
|
||||
icon_state = "seedling"
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/GiveTarget()
|
||||
if(target)
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP || combatant_state == SEEDLING_STATE_ACTIVE)//So it doesn't 180 and blast you in the face while it's firing at someone else
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/seedling/LoseTarget()
|
||||
if(combatant_state == SEEDLING_STATE_WARMUP || combatant_state == SEEDLING_STATE_ACTIVE)
|
||||
return
|
||||
return ..()
|
||||
|
||||
#undef SEEDLING_STATE_NEUTRAL
|
||||
#undef SEEDLING_STATE_WARMUP
|
||||
#undef SEEDLING_STATE_ACTIVE
|
||||
#undef SEEDLING_STATE_RECOVERY
|
||||
@@ -10,7 +10,7 @@
|
||||
maxHealth = 30
|
||||
health = 30
|
||||
see_in_dark = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/killertomato = 2)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/killertomato = 2)
|
||||
response_help = "prods"
|
||||
response_disarm = "pushes aside"
|
||||
response_harm = "smacks"
|
||||
|
||||
@@ -38,13 +38,13 @@ Difficulty: Medium
|
||||
ranged = 1
|
||||
ranged_cooldown_time = 16
|
||||
pixel_x = -16
|
||||
crusher_loot = list(/obj/item/weapon/melee/transforming/cleaving_saw, /obj/item/weapon/gun/energy/kinetic_accelerator, /obj/item/crusher_trophy/miner_eye)
|
||||
loot = list(/obj/item/weapon/melee/transforming/cleaving_saw, /obj/item/weapon/gun/energy/kinetic_accelerator)
|
||||
crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator, /obj/item/crusher_trophy/miner_eye)
|
||||
loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator)
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
medal_type = MEDAL_PREFIX
|
||||
var/obj/item/weapon/melee/transforming/cleaving_saw/miner/miner_saw
|
||||
var/obj/item/melee/transforming/cleaving_saw/miner/miner_saw
|
||||
var/time_until_next_transform = 0
|
||||
var/dashing = FALSE
|
||||
var/dash_cooldown = 15
|
||||
@@ -60,11 +60,11 @@ Difficulty: Medium
|
||||
if(. && prob(12))
|
||||
INVOKE_ASYNC(src, .proc/dash)
|
||||
|
||||
/obj/item/weapon/melee/transforming/cleaving_saw/miner //nerfed saw because it is very murdery
|
||||
/obj/item/melee/transforming/cleaving_saw/miner //nerfed saw because it is very murdery
|
||||
force = 6
|
||||
force_on = 10
|
||||
|
||||
/obj/item/weapon/melee/transforming/cleaving_saw/miner/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
/obj/item/melee/transforming/cleaving_saw/miner/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
target.add_stun_absorption("miner", 10, INFINITY)
|
||||
..()
|
||||
target.stun_absorption -= "miner"
|
||||
@@ -251,9 +251,9 @@ Difficulty: Medium
|
||||
|
||||
animate(src, transform = M, pixel_y = -6, dir = final_dir, time = 2, easing = EASE_IN|EASE_OUT)
|
||||
sleep(5)
|
||||
animate(src, color = list("#A7A19E", "#A7A19E", "#A7A19E", list(0, 0, 0)), time = 10, easing = EASE_IN, flags = ANIMATION_PARALLEL)
|
||||
animate(src, color = list("#A7A19E", "#A7A19E", "#A7A19E", list(0, 0, 0)), time = 10, easing = EASE_IN, flags_1 = ANIMATION_PARALLEL)
|
||||
sleep(4)
|
||||
animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags = ANIMATION_PARALLEL)
|
||||
animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags_1 = ANIMATION_PARALLEL)
|
||||
|
||||
/obj/item/device/gps/internal/miner
|
||||
icon_state = null
|
||||
|
||||
@@ -48,7 +48,7 @@ Difficulty: Very Hard
|
||||
score_type = COLOSSUS_SCORE
|
||||
crusher_loot = list(/obj/structure/closet/crate/necropolis/colossus/crusher)
|
||||
loot = list(/obj/structure/closet/crate/necropolis/colossus)
|
||||
butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
|
||||
butcher_results = list(/obj/item/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
|
||||
deathmessage = "disintegrates, leaving a glowing core in its wake."
|
||||
death_sound = 'sound/magic/demon_dies.ogg'
|
||||
|
||||
@@ -250,7 +250,7 @@ Difficulty: Very Hard
|
||||
use_power = NO_POWER_USE
|
||||
var/memory_saved = FALSE
|
||||
var/list/stored_items = list()
|
||||
var/static/list/blacklist = typecacheof(list(/obj/item/weapon/spellbook))
|
||||
var/static/list/blacklist = typecacheof(list(/obj/item/spellbook))
|
||||
|
||||
/obj/machinery/smartfridge/black_box/update_icon()
|
||||
return
|
||||
@@ -262,14 +262,14 @@ Difficulty: Very Hard
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/smartfridge/black_box/New()
|
||||
/obj/machinery/smartfridge/black_box/Initialize()
|
||||
. = ..()
|
||||
var/static/obj/machinery/smartfridge/black_box/current
|
||||
if(current && current != src)
|
||||
qdel(src, force=TRUE)
|
||||
return
|
||||
current = src
|
||||
ReadMemory()
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/smartfridge/black_box/process()
|
||||
..()
|
||||
@@ -277,19 +277,29 @@ Difficulty: Very Hard
|
||||
WriteMemory()
|
||||
|
||||
/obj/machinery/smartfridge/black_box/proc/WriteMemory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav")
|
||||
var/json_file = file("data/npc_saves/Blackbox.json")
|
||||
stored_items = list()
|
||||
|
||||
for(var/obj/O in (contents-component_parts))
|
||||
stored_items += O.type
|
||||
|
||||
WRITE_FILE(S["stored_items"], stored_items)
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = stored_items
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
memory_saved = TRUE
|
||||
|
||||
/obj/machinery/smartfridge/black_box/proc/ReadMemory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav")
|
||||
S["stored_items"] >> stored_items
|
||||
|
||||
if(fexists("data/npc_saves/Blackbox.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav")
|
||||
S["stored_items"] >> stored_items
|
||||
fdel("data/npc_saves/Blackbox.sav")
|
||||
else
|
||||
var/json_file = file("data/npc_saves/Blackbox.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
stored_items = json["data"]
|
||||
if(isnull(stored_items))
|
||||
stored_items = list()
|
||||
|
||||
@@ -351,7 +361,7 @@ Difficulty: Very Hard
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
use_power = NO_POWER_USE
|
||||
density = TRUE
|
||||
flags = HEAR
|
||||
flags_1 = HEAR_1
|
||||
var/activation_method
|
||||
var/list/possible_methods = list(ACTIVATE_TOUCH, ACTIVATE_SPEECH, ACTIVATE_HEAT, ACTIVATE_BULLET, ACTIVATE_ENERGY, ACTIVATE_BOMB, ACTIVATE_MOB_BUMP, ACTIVATE_WEAPON, ACTIVATE_MAGIC)
|
||||
|
||||
@@ -652,7 +662,7 @@ Difficulty: Very Hard
|
||||
activation_method = ACTIVATE_TOUCH
|
||||
cooldown_add = 50
|
||||
activation_sound = 'sound/magic/timeparadox2.ogg'
|
||||
var/list/banned_items_typecache = list(/obj/item/weapon/storage, /obj/item/weapon/implant, /obj/item/weapon/implanter, /obj/item/weapon/disk/nuclear, /obj/item/projectile, /obj/item/weapon/spellbook)
|
||||
var/list/banned_items_typecache = list(/obj/item/storage, /obj/item/implant, /obj/item/implanter, /obj/item/disk/nuclear, /obj/item/projectile, /obj/item/spellbook)
|
||||
|
||||
/obj/machinery/anomalous_crystal/refresher/Initialize()
|
||||
. = ..()
|
||||
@@ -667,7 +677,7 @@ Difficulty: Very Hard
|
||||
for(var/i in T)
|
||||
if(isitem(i) && !is_type_in_typecache(i, banned_items_typecache))
|
||||
var/obj/item/W = i
|
||||
if(!W.admin_spawned && !HAS_SECONDARY_FLAG(W, HOLOGRAM) && !(W.flags & ABSTRACT))
|
||||
if(!W.admin_spawned && !(W.flags_2 & HOLOGRAM_2) && !(W.flags_1 & ABSTRACT_1))
|
||||
L += W
|
||||
if(L.len)
|
||||
var/obj/item/CHOSEN = pick(L)
|
||||
|
||||
@@ -53,7 +53,7 @@ Difficulty: Medium
|
||||
pixel_x = -16
|
||||
crusher_loot = list(/obj/structure/closet/crate/necropolis/dragon/crusher)
|
||||
loot = list(/obj/structure/closet/crate/necropolis/dragon)
|
||||
butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
|
||||
butcher_results = list(/obj/item/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
|
||||
var/swooping = NONE
|
||||
var/swoop_cooldown = 0
|
||||
medal_type = MEDAL_PREFIX
|
||||
@@ -193,11 +193,11 @@ Difficulty: Medium
|
||||
qdel(F)
|
||||
if(stat == DEAD)
|
||||
swooping &= ~SWOOP_DAMAGEABLE
|
||||
animate(src, alpha = 255, transform = oldtransform, time = 0, flags = ANIMATION_END_NOW) //reset immediately
|
||||
animate(src, alpha = 255, transform = oldtransform, time = 0, flags_1 = ANIMATION_END_NOW) //reset immediately
|
||||
return
|
||||
animate(src, alpha = 100, transform = matrix()*0.7, time = 7)
|
||||
swooping |= SWOOP_INVULNERABLE
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
sleep(7)
|
||||
var/list/flame_hit = list()
|
||||
while(swoop_duration > 0)
|
||||
|
||||
@@ -56,8 +56,8 @@ Difficulty: Hard
|
||||
ranged = 1
|
||||
ranged_cooldown_time = 40
|
||||
aggro_vision_range = 21 //so it can see to one side of the arena to the other
|
||||
loot = list(/obj/item/weapon/hierophant_club)
|
||||
crusher_loot = list(/obj/item/weapon/hierophant_club)
|
||||
loot = list(/obj/item/hierophant_club)
|
||||
crusher_loot = list(/obj/item/hierophant_club)
|
||||
wander = FALSE
|
||||
var/burst_range = 3 //range on burst aoe
|
||||
var/beam_range = 5 //range on cross blast beams
|
||||
@@ -664,14 +664,14 @@ Difficulty: Hard
|
||||
return
|
||||
|
||||
/obj/effect/hierophant/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/hierophant_club))
|
||||
var/obj/item/weapon/hierophant_club/H = I
|
||||
if(istype(I, /obj/item/hierophant_club))
|
||||
var/obj/item/hierophant_club/H = I
|
||||
if(H.timer > world.time)
|
||||
return
|
||||
if(H.beacon == src)
|
||||
to_chat(user, "<span class='notice'>You start removing your hierophant beacon...</span>")
|
||||
H.timer = world.time + 51
|
||||
INVOKE_ASYNC(H, /obj/item/weapon/hierophant_club.proc/prepare_icon_update)
|
||||
INVOKE_ASYNC(H, /obj/item/hierophant_club.proc/prepare_icon_update)
|
||||
if(do_after(user, 50, target = src))
|
||||
playsound(src,'sound/magic/blind.ogg', 200, 1, -4)
|
||||
new /obj/effect/temp_visual/hierophant/telegraph/teleport(get_turf(src), user)
|
||||
@@ -681,7 +681,7 @@ Difficulty: Hard
|
||||
qdel(src)
|
||||
else
|
||||
H.timer = world.time
|
||||
INVOKE_ASYNC(H, /obj/item/weapon/hierophant_club.proc/prepare_icon_update)
|
||||
INVOKE_ASYNC(H, /obj/item/hierophant_club.proc/prepare_icon_update)
|
||||
else
|
||||
to_chat(user, "<span class='hierophant_warning'>You touch the beacon with the club, but nothing happens.</span>")
|
||||
else
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user