Merge remote-tracking branch 'upstream/master' into changeling

This commit is contained in:
DZD
2015-02-19 20:59:41 -05:00
606 changed files with 8621 additions and 6628 deletions
+40 -83
View File
@@ -22,8 +22,10 @@
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(var/obj/item/W)
if(lying) return 0
if(!istype(W)) return 0
if(lying && !(W.flags & ABSTRACT))
return 0
if(!istype(W))
return 0
if(!l_hand)
W.loc = src //TODO: move to equipped?
l_hand = W
@@ -38,8 +40,10 @@
//Puts the item into your r_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_r_hand(var/obj/item/W)
if(lying) return 0
if(!istype(W)) return 0
if(lying && !(W.flags & ABSTRACT))
return 0
if(!istype(W))
return 0
if(!r_hand)
W.loc = src
r_hand = W
@@ -76,98 +80,51 @@
return drop_item()
return 0
/mob/proc/drop_from_inventory(var/obj/item/W)
if(W)
if(client) client.screen -= W
u_equip(W)
if(!W) return 1 // self destroying objects (tk, grabs)
W.layer = initial(W.layer)
W.loc = loc
var/turf/T = get_turf(loc)
if(isturf(T))
T.Entered(W)
W.dropped(src)
update_icons()
return 1
return 0
//Drops the item in our left hand
/mob/proc/drop_l_hand(var/atom/Target)
if(l_hand)
if(client) client.screen -= l_hand
l_hand.layer = initial(l_hand.layer)
if(Target) l_hand.loc = Target.loc
else l_hand.loc = loc
var/turf/T = get_turf(loc)
if(isturf(T))
T.Entered(l_hand)
l_hand.dropped(src)
l_hand = null
update_inv_l_hand()
return 1
return 0
/mob/proc/drop_l_hand()
return unEquip(l_hand) //All needed checks are in unEquip
//Drops the item in our right hand
/mob/proc/drop_r_hand(var/atom/Target)
if(r_hand)
if(client) client.screen -= r_hand
r_hand.layer = initial(r_hand.layer)
if(Target) r_hand.loc = Target.loc
else r_hand.loc = loc
var/turf/T = get_turf(Target)
if(istype(T))
T.Entered(r_hand)
r_hand.dropped(src)
r_hand = null
update_inv_r_hand()
return 1
return 0
/mob/proc/drop_r_hand()
return unEquip(r_hand) //Why was this not calling unEquip in the first place jesus fuck.
//Drops the item in our active hand.
/mob/proc/drop_item(var/atom/Target)
if(hand) return drop_l_hand(Target)
else return drop_r_hand(Target)
/mob/proc/drop_item() //THIS. DOES. NOT. NEED. AN. ARGUMENT.
if(hand)
return drop_l_hand()
else
return drop_r_hand()
//TODO: phase out this proc
/mob/proc/before_take_item(var/obj/item/W) //TODO: what is this?
W.loc = null
W.layer = initial(W.layer)
u_equip(W)
update_icons()
return
//Here lie unEquip and before_item_take, already forgotten and not missed.
/mob/proc/u_equip(W as obj)
if (W == r_hand)
/mob/proc/unEquip(obj/item/I, force) //Force overrides NODROP for things like wizarditis and admin undress.
if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for NODROP.
return 1
if((I.flags & NODROP) && !force)
return 0
if(I == r_hand)
r_hand = null
update_inv_r_hand(0)
else if (W == l_hand)
update_inv_r_hand()
else if(I == l_hand)
l_hand = null
update_inv_l_hand(0)
else if (W == back)
back = null
update_inv_back(0)
else if (W == wear_mask)
wear_mask = null
update_inv_wear_mask(0)
return
update_inv_l_hand()
if(I)
if(client)
client.screen -= I
I.loc = loc
I.dropped(src)
if(I)
I.layer = initial(I.layer)
return 1
//Attemps to remove an object on a mob. Will not move it to another area or such, just removes from the mob.
/mob/proc/remove_from_mob(var/obj/O)
src.u_equip(O)
if (src.client)
src.client.screen -= O
O.layer = initial(O.layer)
unEquip(O)
O.screen_loc = null
return 1
@@ -1,23 +1,16 @@
//unequip
/mob/living/carbon/alien/humanoid/u_equip(obj/item/W as obj)
if (W == wear_suit)
wear_suit = null
update_inv_wear_suit(0,0)
else if (W == head)
head = null
update_inv_head(0,0)
else if (W == r_store)
/mob/living/carbon/alien/humanoid/unEquip(obj/item/I as obj)
. = ..()
if(!. || !I)
return
if(I == r_store)
r_store = null
update_inv_pockets(0)
else if (W == l_store)
else if(I == l_store)
l_store = null
update_inv_pockets(0)
else if (W == r_hand)
r_hand = null
update_inv_r_hand(0)
else if (W == l_hand)
l_hand = null
update_inv_l_hand(0)
/mob/living/carbon/alien/humanoid/attack_ui(slot_id)
var/obj/item/W = get_active_hand()
@@ -31,7 +24,7 @@
return
if(W.w_class > 3)
return
u_equip(W)
unEquip(W)
l_store = W
update_inv_pockets()
if(slot_r_store)
@@ -39,7 +32,7 @@
return
if(W.w_class > 3)
return
u_equip(W)
unEquip(W)
r_store = W
update_inv_pockets()
else
@@ -104,7 +104,7 @@
//TODO
wear_suit.screen_loc = ui_alien_oclothing
if (istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
drop_from_inventory(handcuffed)
unEquip(handcuffed)
drop_r_hand()
drop_l_hand()
@@ -1,3 +1,3 @@
//can't unequip since it can't equip anything
/mob/living/carbon/alien/larva/u_equip(obj/item/W as obj)
/mob/living/carbon/alien/larva/unEquip(obj/item/W as obj)
return
@@ -74,7 +74,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
AttemptGrow()
/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1)
var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate")
var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,1)
var/client/C = null
// To stop clientless larva, we will check that our host has a client
@@ -40,7 +40,7 @@ var/const/MAX_ACTIVE_TIME = 400
/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
..()
user.before_take_item(src)
user.unEquip(src)
Attach(M)
/obj/item/clothing/mask/facehugger/examine(mob/user)
@@ -131,9 +131,12 @@ var/const/MAX_ACTIVE_TIME = 400
if(iscarbon(M))
var/mob/living/carbon/target = L
if(target.wear_mask)
if(prob(20)) return 0
if(prob(20))
return 0
var/obj/item/clothing/W = target.wear_mask
target.before_take_item(W)
if(W.flags & NODROP)
return 0
target.unEquip(W)
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
@@ -162,7 +165,7 @@ var/const/MAX_ACTIVE_TIME = 400
var/mob/living/carbon/C = target
if(C.wear_mask != src)
return
if(ishuman(target))
var/mob/living/carbon/human/H = target
if((H.species.flags & IS_SYNTHETIC))
@@ -233,7 +236,7 @@ var/const/MAX_ACTIVE_TIME = 400
/proc/CanHug(var/mob/M)
if(!M || !ismob(M))
return 0
if(M.stat == DEAD)
return 0
@@ -255,4 +258,4 @@ var/const/MAX_ACTIVE_TIME = 400
gender = FEMALE
/obj/item/clothing/mask/facehugger/lamarr/New()//to prevent deleting it if aliums are disabled
return
return
@@ -3,7 +3,6 @@
desc = "A piece of juicy meat found in a persons head."
icon = 'icons/obj/surgery.dmi'
icon_state = "brain2"
flags = TABLEPASS
force = 1.0
w_class = 1.0
throwforce = 1.0
+29 -21
View File
@@ -378,11 +378,13 @@
throw_mode_off()
if(usr.stat || !target)
return
if(target.type == /obj/screen) return
if(target.type == /obj/screen)
return
var/atom/movable/item = src.get_active_hand()
if(!item) return
if(!item || (item.flags & NODROP))
return
if (istype(item, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = item
@@ -404,10 +406,10 @@
else
M.LAssailant = usr
if(!item) return //Grab processing has a chance of returning null
item.layer = initial(item.layer)
u_equip(item)
if(!item)
return //Grab processing has a chance of returning null
if(!ismob(item)) //Honk mobs don't have a dropped() proc honk
unEquip(item)
update_icons()
if (istype(usr, /mob/living/carbon)) //Check if a carbon mob is throwing. Modify/remove this line as required.
@@ -419,6 +421,7 @@
//actually throw it!
if (item)
item.layer = initial(item.layer)
src.visible_message("\red [src] has thrown [item].")
if(!src.lastarea)
@@ -453,29 +456,34 @@
return 1
return
/mob/living/carbon/u_equip(obj/item/W as obj)
if(!W) return 0
/mob/living/carbon/unEquip(obj/item/I) //THIS PROC DID NOT CALL ..()
. = ..() //Sets the default return value to what the parent returns.
if(!. || !I) //We don't want to set anything to null if the parent returned 0.
return
else if (W == handcuffed)
if(I == back)
back = null
update_inv_back(0)
else if(I == wear_mask)
if(istype(src, /mob/living/carbon/human)) //If we don't do this hair won't be properly rebuilt.
return
wear_mask = null
update_inv_wear_mask(0)
else if(I == handcuffed)
handcuffed = null
update_inv_handcuffed()
else if (W == legcuffed)
update_inv_handcuffed(0)
else if(I == legcuffed)
legcuffed = null
update_inv_legcuffed()
else
..()
return
update_inv_legcuffed(0)
/mob/living/carbon/show_inv(mob/living/carbon/user as mob)
user.set_machine(src)
var/dat = {"
<B><HR><FONT size=3>[name]</FONT></B>
<BR><HR>
<BR><B>Head(Mask):</B> <A href='?src=\ref[src];item=mask'>[(wear_mask ? wear_mask : "Nothing")]</A>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand ? l_hand : "Nothing")]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand ? r_hand : "Nothing")]</A>
<BR><B>Head(Mask):</B> <A href='?src=\ref[src];item=mask'>[(wear_mask && !(wear_mask.flags & ABSTRACT)) ? wear_mask : "Nothing"]</A>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand && !(l_hand.flags & ABSTRACT)) ? l_hand : "Nothing"]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand && !(r_hand.flags & ABSTRACT)) ? r_hand : "Nothing"]</A>
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back ? back : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR>[(handcuffed ? text("<A href='?src=\ref[src];item=handcuff'>Handcuffed</A>") : text("<A href='?src=\ref[src];item=handcuff'>Not Handcuffed</A>"))]
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
@@ -579,4 +587,4 @@
return
/mob/living/carbon/proc/canBeHandcuffed()
return 0
return 0
+3
View File
@@ -20,6 +20,9 @@
I = usr.r_hand
if(!I)
return
if((I.flags & NODROP) || (I.flags & ABSTRACT))
usr << "<span class='notice'>That's not exactly something you can give.</span>"
return
if(src.r_hand == null || src.l_hand == null)
switch(alert(src,"[usr] wants to give you \a [I]?",,"Yes","No"))
if("Yes")
@@ -104,14 +104,14 @@
msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n"
//left hand
if(l_hand)
if(l_hand && !(l_hand.flags & ABSTRACT))
if(l_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] blood-stained [l_hand.name] in [t_his] left hand!</span>\n"
else
msg += "[t_He] [t_is] holding \icon[l_hand] \a [l_hand] in [t_his] left hand.\n"
//right hand
if(r_hand)
if(r_hand && !(r_hand.flags & ABSTRACT))
if(r_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] blood-stained [r_hand.name] in [t_his] right hand!</span>\n"
else
@@ -130,7 +130,9 @@
//handcuffed?
if(handcuffed)
if(istype(handcuffed, /obj/item/weapon/handcuffs/cable))
if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable/zipties))
msg += "<span class='warning'>[t_He] [t_is] \icon[handcuffed] restrained with zipties!</span>\n"
else if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable))
msg += "<span class='warning'>[t_He] [t_is] \icon[handcuffed] restrained with cable!</span>\n"
else
msg += "<span class='warning'>[t_He] [t_is] \icon[handcuffed] handcuffed!</span>\n"
+43 -27
View File
@@ -496,24 +496,24 @@
var/dat = {"
<B><HR><FONT size=3>[name]</FONT></B>
<BR><HR>
<BR><B>Head(Mask):</B> <A href='?src=\ref[src];item=mask'>[(wear_mask ? wear_mask : "Nothing")]</A>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand ? l_hand : "Nothing")]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand ? r_hand : "Nothing")]</A>
<BR><B>Gloves:</B> <A href='?src=\ref[src];item=gloves'>[(gloves ? gloves : "Nothing")]</A>
<BR><B>Eyes:</B> <A href='?src=\ref[src];item=eyes'>[(glasses ? glasses : "Nothing")]</A>
<BR><B>Left Ear:</B> <A href='?src=\ref[src];item=l_ear'>[(l_ear ? l_ear : "Nothing")]</A>
<BR><B>Right Ear:</B> <A href='?src=\ref[src];item=r_ear'>[(r_ear ? r_ear : "Nothing")]</A>
<BR><B>Head:</B> <A href='?src=\ref[src];item=head'>[(head ? head : "Nothing")]</A>
<BR><B>Shoes:</B> <A href='?src=\ref[src];item=shoes'>[(shoes ? shoes : "Nothing")]</A>
<BR><B>Belt:</B> <A href='?src=\ref[src];item=belt'>[(belt ? belt : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(belt, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR><B>Uniform:</B> <A href='?src=\ref[src];item=uniform'>[(w_uniform ? w_uniform : "Nothing")]</A> [(suit) ? ((suit.has_sensor == 1) ? text(" <A href='?src=\ref[];item=sensor'>Sensors</A>", src) : "") :]
<BR><B>(Exo)Suit:</B> <A href='?src=\ref[src];item=suit'>[(wear_suit ? wear_suit : "Nothing")]</A>
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back ? back : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR><B>ID:</B> <A href='?src=\ref[src];item=id'>[(wear_id ? wear_id : "Nothing")]</A>
<BR><B>PDA:</B> <A href='?src=\ref[src];item=pda'>[(wear_pda ? wear_pda : "Nothing")]</A>
<BR><B>Suit Storage:</B> <A href='?src=\ref[src];item=s_store'>[(s_store ? s_store : "Nothing")]</A>
<BR><BR><A href='?src=\ref[src];pockets=left'>Left Pocket ([l_store ? (pickpocket ? l_store.name : "Full") : "Empty"])</A>
<BR><A href='?src=\ref[src];pockets=right'>Right Pocket ([r_store ? (pickpocket ? r_store.name : "Full") : "Empty"])</A>
<BR><B>Head(Mask):</B> <A href='?src=\ref[src];item=mask'>[(wear_mask && !(wear_mask.flags & ABSTRACT)) ? wear_mask : "Nothing"]</A>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand && !(l_hand.flags & ABSTRACT)) ? l_hand : "Nothing"]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "Nothing"]</A>
<BR><B>Gloves:</B> <A href='?src=\ref[src];item=gloves'>[(gloves && !(gloves.flags & ABSTRACT)) ? gloves : "Nothing"]</A>
<BR><B>Eyes:</B> <A href='?src=\ref[src];item=eyes'>[(glasses && !(glasses.flags & ABSTRACT)) ? glasses : "Nothing"]</A>
<BR><B>Left Ear:</B> <A href='?src=\ref[src];item=l_ear'>[(l_ear && !(l_ear.flags & ABSTRACT)) ? l_ear : "Nothing"]</A>
<BR><B>Right Ear:</B> <A href='?src=\ref[src];item=r_ear'>[(r_ear && !(r_ear.flags & ABSTRACT)) ? r_ear : "Nothing"]</A>
<BR><B>Head:</B> <A href='?src=\ref[src];item=head'>[(head && !(head.flags & ABSTRACT)) ? head : "Nothing"]</A>
<BR><B>Shoes:</B> <A href='?src=\ref[src];item=shoes'>[(shoes && !(shoes.flags & ABSTRACT)) ? shoes : "Nothing"]</A>
<BR><B>Belt:</B> <A href='?src=\ref[src];item=belt'>[(belt && !(belt.flags & ABSTRACT)) ? belt : "Nothing"]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(belt, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR><B>Uniform:</B> <A href='?src=\ref[src];item=uniform'>[(w_uniform && !(w_uniform.flags & ABSTRACT)) ? w_uniform : "Nothing"]</A> [(suit) ? ((suit.has_sensor == 1) ? text(" <A href='?src=\ref[];item=sensor'>Sensors</A>", src) : "") :]
<BR><B>(Exo)Suit:</B> <A href='?src=\ref[src];item=suit'>[(wear_suit && !(wear_suit.flags & ABSTRACT)) ? wear_suit : "Nothing"]</A>
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back && !(back.flags & ABSTRACT)) ? back : "Nothing"]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR><B>ID:</B> <A href='?src=\ref[src];item=id'>[(wear_id && !(wear_id.flags & ABSTRACT)) ? wear_id : "Nothing"]</A>
<BR><B>PDA:</B> <A href='?src=\ref[src];item=pda'>[(wear_pda && !(wear_pda.flags & ABSTRACT)) ? wear_pda : "Nothing"]</A>
<BR><B>Suit Storage:</B> <A href='?src=\ref[src];item=s_store'>[(s_store && !(s_store.flags & ABSTRACT)) ? s_store : "Nothing"]</A>
<BR><BR><A href='?src=\ref[src];pockets=left'>Left Pocket ([(l_store && !(l_store.flags & ABSTRACT)) ? (pickpocket ? l_store.name : "Full") : "Empty"])</A>
<BR><A href='?src=\ref[src];pockets=right'>Right Pocket ([(r_store && !(r_store.flags & ABSTRACT)) ? (pickpocket ? r_store.name : "Full") : "Empty"])</A>
<BR><A href='?src=\ref[src];item=pockets'>Empty Both Pockets</A>
<BR><BR>[(handcuffed ? text("<A href='?src=\ref[src];item=handcuff'>Handcuffed</A>") : text("<A href='?src=\ref[src];item=handcuff'>Not Handcuffed</A>"))]
<BR>[(legcuffed ? text("<A href='?src=\ref[src];item=legcuff'>Legcuffed</A>") : text(""))]
@@ -538,7 +538,21 @@
var/obj/vehicle/V = AM
V.RunOver(src)
// Get rank from ID, ID inside PDA, PDA, ID in wallet, etc.
/mob/living/carbon/human/proc/get_authentification_rank(var/if_no_id = "No id", var/if_no_job = "No job")
var/obj/item/device/pda/pda = wear_id
if (istype(pda))
if (pda.id)
return pda.id.rank
else
return pda.ownrank
else
var/obj/item/weapon/card/id/id = get_idcard()
if(id)
return id.rank ? id.rank : if_no_job
else
return if_no_id
//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(var/if_no_id = "No id", var/if_no_job = "No job")
@@ -640,20 +654,22 @@
var/obj/item/pocket_item = (pocket_id == slot_r_store ? src.r_store : src.l_store)
var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty
if(pocket_item)
if(pocket_item && !(pocket_item.flags & ABSTRACT))
if(pocket_item.flags & NODROP)
usr << "<span class='notice'>You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!</span>"
usr << "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>"
else if(place_item && place_item.mob_can_equip(src, pocket_id, 1))
else if(place_item && place_item.mob_can_equip(src, pocket_id, 1) && !(place_item.flags & ABSTRACT))
usr << "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>"
else
return
if(do_mob(usr, src, STRIP_DELAY))
if(pocket_item)
u_equip(pocket_item)
unEquip(pocket_item)
usr.put_in_hands(pocket_item)
else
if(place_item)
usr.u_equip(place_item)
usr.unEquip(place_item)
equip_to_slot_if_possible(place_item, pocket_id, 0, 1)
// Update strip window
@@ -687,11 +703,11 @@
if(do_mob(usr, src, STRIP_DELAY))
if(worn_id)
u_equip(worn_id)
unEquip(worn_id)
usr.put_in_hands(worn_id)
else
if(place_item)
usr.u_equip(place_item)
usr.unEquip(place_item)
equip_to_slot_if_possible(place_item, slot_wear_id, 0, 1)
// Update strip window
@@ -1036,10 +1052,10 @@
/mob/living/carbon/human/abiotic(var/full_body = 0)
if(full_body && ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.l_ear || src.r_ear || src.gloves)))
if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.l_ear || src.r_ear || src.gloves)))
return 1
if( (src.l_hand && !src.l_hand.abstract) || (src.r_hand && !src.r_hand.abstract) )
if((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)))
return 1
return 0
@@ -176,11 +176,11 @@
if(head)
var/obj/item/clothing/head/H = head
if(!istype(H) || prob(H.loose))
drop_from_inventory(H)
if(prob(60))
step_away(H,M)
visible_message("<span class='warning'>[M] has knocked [src]'s [H] off!</span>",
"<span class='warning'>[M] knocked \the [H] clean off your head!</span>") */
if(unEquip(H))
if(prob(60))
step_away(H,M)
visible_message("<span class='warning'>[M] has knocked [src]'s [H] off!</span>",
"<span class='warning'>[M] knocked \the [H] clean off your head!</span>") */
var/talked = 0 // BubbleWrap
@@ -209,8 +209,8 @@
//End BubbleWrap
if(!talked) //BubbleWrap
drop_item()
visible_message("\red <B>[M] has disarmed [src]!</B>")
if(drop_item())
visible_message("\red <B>[M] has disarmed [src]!</B>")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
@@ -348,7 +348,7 @@ This function restores all organs.
multiplier = 2
var/obj/item/clothing/head/H = head
if(!istype(H) || prob(H.loose * multiplier))
drop_from_inventory(H)
unEquip(H)
if(prob(60))
step_rand(H)
if(!stat)
@@ -72,7 +72,7 @@ emp_act
if(c_hand && (stun_amount || agony_amount > 10))
msg_admin_attack("[src.name] ([src.ckey]) was disarmed by a stun effect")
u_equip(c_hand)
unEquip(c_hand)
if (affected.status & ORGAN_ROBOT)
emote("me", 1, "drops what they were holding, their [affected.display_name] malfunctioning!")
else
@@ -198,7 +198,17 @@ emp_act
I.emp_act(severity)
..()
/mob/living/carbon/human/emag_act(user as mob, var/datum/organ/external/affecting)
if(!(affecting.status & ORGAN_ROBOT))
user << "\red That limb isn't robotic."
return
if(affecting.sabotaged)
user << "\red [src]'s [affecting.display_name] is already sabotaged!"
else
user << "\red You sneakily slide the card into the dataport on [src]'s [affecting.display_name] and short out the safeties."
affecting.sabotaged = 1
return 1
//Returns 1 if the attack hit, 0 if it missed.
/mob/living/carbon/human/proc/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone)
if(!I || !user) return 0
@@ -236,17 +246,8 @@ emp_act
return 0
if(istype(I,/obj/item/weapon/card/emag))
if(!(affecting.status & ORGAN_ROBOT))
user << "\red That limb isn't robotic."
return
if(affecting.sabotaged)
user << "\red [src]'s [affecting.display_name] is already sabotaged!"
else
user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.display_name] and short out the safeties."
var/obj/item/weapon/card/emag/emag = I
emag.uses--
affecting.sabotaged = 1
return 1
emag_act(user, affecting)
if(! I.discrete)
if(I.attack_verb.len)
visible_message("\red <B>[src] has been [pick(I.attack_verb)] in the [hit_area] with [I.name] by [user]!</B>")
@@ -337,6 +338,15 @@ emp_act
/mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = 5)
if(istype(AM,/obj/))
var/obj/O = AM
if(in_throw_mode && !get_active_hand() && speed <= 5) //empty active hand and we're in throw mode
if(canmove && !restrained())
if(isturf(O.loc))
put_in_active_hand(O)
visible_message("<span class='warning'>[src] catches [O]!</span>")
throw_mode_off()
return
var/zone = ran_zone("chest", 65)
var/dtype = BRUTE
if(istype(O,/obj/item/weapon))
+69 -114
View File
@@ -104,123 +104,76 @@
if(slot_tie)
return 1
/mob/living/carbon/human/u_equip(obj/item/W as obj)
if(!W) return 0
/mob/living/carbon/human/unEquip(obj/item/I)
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
if(!. || !I)
return
var/success
if (W == wear_suit)
if(I == wear_suit)
if(s_store)
drop_from_inventory(s_store)
if(W)
success = 1
unEquip(s_store, 1) //It makes no sense for your suit storage to stay on you if you drop your suit.
wear_suit = null
update_inv_wear_suit()
else if (W == w_uniform)
if (r_store)
drop_from_inventory(r_store)
if (l_store)
drop_from_inventory(l_store)
if (wear_id)
drop_from_inventory(wear_id)
if (belt)
drop_from_inventory(belt)
if(I.flags_inv & HIDEJUMPSUIT)
update_inv_w_uniform()
update_inv_wear_suit(0)
else if(I == w_uniform)
if(r_store)
unEquip(r_store, 1) //Again, makes sense for pockets to drop.
if(l_store)
unEquip(l_store, 1)
if(wear_id)
unEquip(wear_id)
if(belt)
unEquip(belt)
w_uniform = null
success = 1
update_inv_w_uniform()
else if (W == gloves)
update_inv_w_uniform(0)
else if(I == gloves)
gloves = null
success = 1
update_inv_gloves()
else if (W == glasses)
update_inv_gloves(0)
else if(I == glasses)
glasses = null
success = 1
update_inv_glasses()
else if (W == head)
update_inv_glasses(0)
else if(I == head)
head = null
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR))
if(I.flags & BLOCKHAIR)
update_hair(0) //rebuild hair
success = 1
update_inv_head()
else if (W == l_ear)
l_ear = null
success = 1
update_inv_ears()
else if (W == r_ear)
update_inv_head(0)
else if(I == r_ear)
r_ear = null
success = 1
update_inv_ears()
else if (W == shoes)
update_inv_ears(0)
else if (I == l_ear)
l_ear = null
update_inv_ears(0)
else if(I == shoes)
shoes = null
success = 1
update_inv_shoes()
else if (W == belt)
update_inv_shoes(0)
else if(I == belt)
belt = null
success = 1
update_inv_belt()
else if (W == wear_mask)
update_inv_belt(0)
else if(I == wear_mask)
wear_mask = null
success = 1
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR))
if(I.flags & BLOCKHAIR)
update_hair(0) //rebuild hair
if(internal)
if(internals)
internals.icon_state = "internal0"
internal = null
update_inv_wear_mask()
else if (W == wear_id)
update_inv_wear_mask(0)
else if(I == wear_id)
wear_id = null
success = 1
update_inv_wear_id()
else if (W == wear_pda)
wear_pda = null
success = 1
update_inv_wear_pda()
else if (W == r_store)
update_inv_wear_id(0)
else if(I == r_store)
r_store = null
success = 1
update_inv_pockets()
else if (W == l_store)
update_inv_pockets(0)
else if(I == l_store)
l_store = null
success = 1
update_inv_pockets()
else if (W == s_store)
update_inv_pockets(0)
else if(I == s_store)
s_store = null
success = 1
update_inv_s_store()
else if (W == back)
back = null
success = 1
update_inv_back()
else if (W == handcuffed)
handcuffed = null
success = 1
update_inv_handcuffed()
else if (W == legcuffed)
legcuffed = null
success = 1
update_inv_legcuffed()
else if (W == r_hand)
r_hand = null
success = 1
update_inv_r_hand()
else if (W == l_hand)
l_hand = null
success = 1
update_inv_l_hand()
else
return 0
update_inv_s_store(0)
if(success)
if (W)
if (client)
client.screen -= W
W.loc = loc
W.dropped(src)
//if(W)
//W.layer = initial(W.layer)
update_action_buttons()
return 1
@@ -337,7 +290,7 @@
update_inv_s_store(redraw_mob)
if(slot_in_backpack)
if(src.get_active_hand() == W)
src.u_equip(W)
src.unEquip(W)
W.loc = src.back
if(slot_tie)
var/obj/item/clothing/under/uniform = src.w_uniform
@@ -454,7 +407,7 @@
if("mask")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Had their mask removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) mask</font>")
if(target.wear_mask && !target.wear_mask.canremove)
if(target.wear_mask && (target.wear_mask.flags & NODROP))
message = "\red <B>[source] fails to take off \a [target.wear_mask] from [target]'s head!</B>"
return
else if(target.wear_mask)
@@ -470,7 +423,7 @@
if("gloves")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their gloves ([target.gloves]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) gloves ([target.gloves])</font>")
if(target.gloves && !target.gloves.canremove)
if(target.gloves && (target.gloves.flags & NODROP))
message = "\red <B>[source] fails to take off \a [target.gloves] from [target]'s hands!</B>"
return
else if(target.gloves)
@@ -478,7 +431,7 @@
if("eyes")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their eyewear ([target.glasses]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) eyewear ([target.glasses])</font>")
if(target.glasses && !target.glasses.canremove)
if(target.glasses && (target.glasses.flags & NODROP))
message = "\red <B>[source] fails to take off \a [target.glasses] from [target]'s eyes!</B>"
return
else if(target.glasses)
@@ -486,7 +439,7 @@
if("l_ear")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their left ear item ([target.l_ear]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) left ear item ([target.l_ear])</font>")
if(target.l_ear && !target.l_ear.canremove)
if(target.l_ear && (target.l_ear.flags & NODROP))
message = "\red <B>[source] fails to take off \a [target.l_ear] from [target]'s left ear!</B>"
return
else if(target.l_ear)
@@ -494,7 +447,7 @@
if("r_ear")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their right ear item ([target.r_ear]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) right ear item ([target.r_ear])</font>")
if(target.r_ear && !target.r_ear.canremove)
if(target.r_ear && (target.r_ear.flags & NODROP))
message = "\red <B>[source] fails to take off \a [target.r_ear] from [target]'s right ear!</B>"
return
else if(target.r_ear)
@@ -502,7 +455,7 @@
if("head")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their hat ([target.head]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) hat ([target.head])</font>")
if(target.head && !target.head.canremove)
if(target.head && (target.head.flags & NODROP))
message = "\red <B>[source] fails to take off \a [target.head] from [target]'s head!</B>"
return
else if(target.head)
@@ -510,7 +463,7 @@
if("shoes")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their shoes ([target.shoes]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) shoes ([target.shoes])</font>")
if(target.shoes && !target.shoes.canremove)
if(target.shoes && (target.shoes.flags & NODROP))
message = "\red <B>[source] fails to take off \a [target.shoes] from [target]'s feet!</B>"
return
else if(target.shoes)
@@ -523,7 +476,7 @@
if("suit")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their suit ([target.wear_suit]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) suit ([target.wear_suit])</font>")
if(target.wear_suit && !target.wear_suit.canremove)
if(target.wear_suit && (target.wear_suit.flags & NODROP))
message = "\red <B>[source] fails to take off \a [target.wear_suit] from [target]'s body!</B>"
return
else if(target.wear_suit)
@@ -550,7 +503,7 @@
for(var/obj/item/I in list(target.l_store, target.r_store))
if(I.on_found(source))
return
if(target.w_uniform && !target.w_uniform.canremove)
if(target.w_uniform && (target.w_uniform.flags & NODROP))
message = "\red <B>[source] fails to take off \a [target.w_uniform] from [target]'s body!</B>"
return
else
@@ -633,7 +586,7 @@ It works in conjuction with the process() above.
This proc works for humans only. Aliens stripping humans and the like will all use this proc. Stripping monkeys or somesuch will use their version of this proc.
The first if statement for "mask" and such refers to items that are already equipped and un-equipping them.
The else statement is for equipping stuff to empty slots.
!canremove refers to variable of /obj/item/clothing which either allows or disallows that item to be removed.
The NODROP flag refers to variable of /obj/item/clothing which either allows or disallows that item to be removed.
It can still be worn/put on as normal.
*/
/obj/effect/equip_e/human/done() //TODO: And rewrite this :< ~Carn
@@ -652,11 +605,11 @@ It can still be worn/put on as normal.
switch(place) //here we go again...
if("mask")
slot_to_process = slot_wear_mask
if (target.wear_mask && target.wear_mask.canremove)
if (target.wear_mask && !(target.wear_mask.flags & NODROP))
strip_item = target.wear_mask
if("gloves")
slot_to_process = slot_gloves
if (target.gloves && target.gloves.canremove)
if (target.gloves && !(target.gloves.flags & NODROP))
strip_item = target.gloves
if("eyes")
slot_to_process = slot_glasses
@@ -672,7 +625,7 @@ It can still be worn/put on as normal.
strip_item = target.s_store
if("head")
slot_to_process = slot_head
if (target.head && target.head.canremove)
if (target.head && !(target.head.flags & NODROP))
strip_item = target.head
if("l_ear")
slot_to_process = slot_l_ear
@@ -684,7 +637,7 @@ It can still be worn/put on as normal.
strip_item = target.r_ear
if("shoes")
slot_to_process = slot_shoes
if (target.shoes && target.shoes.canremove)
if (target.shoes && !(target.shoes.flags & NODROP))
strip_item = target.shoes
if("l_hand")
if (istype(target, /obj/item/clothing/suit/straight_jacket))
@@ -700,11 +653,11 @@ It can still be worn/put on as normal.
strip_item = target.r_hand
if("uniform")
slot_to_process = slot_w_uniform
if(target.w_uniform && target.w_uniform.canremove)
if(target.w_uniform && !(target.w_uniform.flags & NODROP))
strip_item = target.w_uniform
if("suit")
slot_to_process = slot_wear_suit
if (target.wear_suit && target.wear_suit.canremove)
if (target.wear_suit && !(target.wear_suit.flags & NODROP))
strip_item = target.wear_suit
if("tie")
var/obj/item/clothing/under/suit = target.w_uniform
@@ -810,7 +763,9 @@ It can still be worn/put on as normal.
if(slot_to_process)
if(strip_item) //Stripping an item from the mob
var/obj/item/W = strip_item
target.u_equip(W)
if((W.flags & NODROP) || (W.flags & ABSTRACT)) //Just to be sure
return
target.unEquip(W)
if (target.client)
target.client.screen -= W
if (W)
@@ -820,11 +775,11 @@ It can still be worn/put on as normal.
W.add_fingerprint(source)
if(slot_to_process == slot_l_store) //pockets! Needs to process the other one too. Snowflake code, wooo! It's not like anyone will rewrite this anytime soon. If I'm wrong then... CONGRATULATIONS! ;)
if(target.r_store)
target.u_equip(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store.
target.unEquip(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store.
else
if(item && target.has_organ_for_slot(slot_to_process)) //Placing an item on the mob
if(item.mob_can_equip(target, slot_to_process, 0))
source.u_equip(item)
source.unEquip(item)
target.equip_to_slot_if_possible(item, slot_to_process, 0, 1, 1)
item.dropped(source)
source.update_icons()
@@ -843,7 +798,7 @@ It can still be worn/put on as normal.
if(slot_r_hand)
return r_hand
return null
/mob/living/carbon/get_item_by_slot(slot_id)
switch(slot_id)
if(slot_back)
+1 -1
View File
@@ -1537,7 +1537,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
// Not on the station or mining?
var/turf/temp_turf = get_turf(remoteview_target)
if((temp_turf.z != 1 && temp_turf.z != 5) || remoteview_target.stat!=CONSCIOUS)
if((!(temp_turf.z in config.contact_levels)) || remoteview_target.stat!=CONSCIOUS)
src << "\red Your psy-connection grows too faint to maintain!"
isRemoteObserve = 0
if(!isRemoteObserve && client && !client.adminobs)
@@ -24,10 +24,10 @@
H.fire_sprite = "Plasmaman"
// Unequip existing suits and hats.
H.u_equip(H.wear_suit)
H.u_equip(H.head)
H.unEquip(H.wear_suit)
H.unEquip(H.head)
if(H.mind.assigned_role!="Clown")
H.u_equip(H.wear_mask)
H.unEquip(H.wear_mask)
H.equip_or_collect(new /obj/item/clothing/mask/breath(H), slot_wear_mask)
var/suit=/obj/item/clothing/suit/space/plasmaman
@@ -598,7 +598,7 @@ proc/get_damage_icon_part(damage_state, body_part)
standing.icon = 'icons/mob/uniform_fat.dmi'
else
src << "\red You burst out of \the [w_uniform]!"
drop_from_inventory(w_uniform)
unEquip(w_uniform)
return
else
standing.icon = 'icons/mob/uniform.dmi'
@@ -626,7 +626,7 @@ proc/get_damage_icon_part(damage_state, body_part)
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
for( var/obj/item/thing in list(r_store, l_store, wear_id, wear_pda, belt) ) //
if(thing) //
u_equip(thing) //
unEquip(thing) //
if (client) //
client.screen -= thing //
//
@@ -819,14 +819,14 @@ proc/get_damage_icon_part(damage_state, body_part)
standing = image("icon" = 'icons/mob/suit_fat.dmi', "icon_state" = "[wear_suit.icon_state]")
else
src << "\red You burst out of \the [wear_suit]!"
drop_from_inventory(wear_suit)
unEquip(wear_suit)
return
else
standing = image("icon" = 'icons/mob/suit.dmi', "icon_state" = "[wear_suit.icon_state]")
if( istype(wear_suit, /obj/item/clothing/suit/straight_jacket) )
drop_from_inventory(handcuffed)
unEquip(handcuffed)
drop_l_hand()
drop_r_hand()
@@ -918,7 +918,7 @@ proc/get_damage_icon_part(damage_state, body_part)
var/obj/screen/inventory/L = hud_used.adding[8]
R.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="markus")
L.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="gabrielle")
if(istype(handcuffed, /obj/item/weapon/handcuffs/pinkcuffs))
if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/pinkcuffs))
overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1")
else
overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
@@ -230,7 +230,7 @@
return
/mob/living/carbon/slime/u_equip(obj/item/W as obj)
/mob/living/carbon/slime/unEquip(obj/item/W as obj)
return
/mob/living/carbon/slime/attack_ui(slot)
@@ -897,8 +897,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
item_state = "golem"
_color = "golem"
has_sensor = 0
flags = ABSTRACT | NODROP
armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
canremove = 0
/obj/item/clothing/suit/golem
name = "adamantine shell"
@@ -911,21 +911,19 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|HEAD
slowdown = 1.0
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
flags = FPRINT | TABLEPASS | ONESIZEFITSALL | STOPSPRESSUREDMAGE
flags = ONESIZEFITSALL | STOPSPRESSUREDMAGE | ABSTRACT | NODROP
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS | HEAD
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | HEAD
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
canremove = 0
armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/shoes/golem
name = "golem's feet"
desc = "sturdy adamantine feet"
icon_state = "golem"
item_state = null
canremove = 0
flags = NOSLIP
item_state = "golem"
flags = NOSLIP | ABSTRACT | MASKINTERNALS | MASKCOVERSMOUTH | NODROP
slowdown = SHOES_SLOWDOWN+1
@@ -934,18 +932,9 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
desc = "the imposing face of an adamantine golem"
icon_state = "golem"
item_state = "golem"
canremove = 0
siemens_coefficient = 0
unacidable = 1
/obj/item/clothing/mask/gas/golem
name = "golem's face"
desc = "the imposing face of an adamantine golem"
icon_state = "golem"
item_state = "golem"
canremove = 0
siemens_coefficient = 0
unacidable = 1
flags = ABSTRACT | NODROP
/obj/item/clothing/gloves/golem
@@ -954,7 +943,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
icon_state = "golem"
item_state = null
siemens_coefficient = 0
canremove = 0
flags = ABSTRACT | NODROP
/obj/item/clothing/head/space/golem
@@ -963,9 +952,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
_color = "dermal"
name = "golem's head"
desc = "a golem's head"
canremove = 0
unacidable = 1
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE
flags = STOPSPRESSUREDMAGE | ABSTRACT | NODROP
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0)
@@ -1142,7 +1130,6 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
desc = "Allows you to change your slimeperson color, once."
icon = 'icons/obj/device.dmi'
icon_state = "t-ray0"
flags = TABLEPASS
force = 1.0
w_class = 1.0
throwforce = 1.0
@@ -193,7 +193,7 @@
adult.rename_self("diona")
for (var/obj/item/W in src.contents)
src.drop_from_inventory(W)
src.unEquip(W)
del(src)
@@ -41,7 +41,7 @@
var/message = null
switch(place)
if("mask")
if(istype(target.wear_mask, /obj/item/clothing)&&!target.wear_mask:canremove)
if(istype(target.wear_mask, /obj/item/clothing)&&(target.wear_mask:flags & NODROP))
message = text("\red <B>[] fails to take off \a [] from []'s body!</B>", source, target.wear_mask, target)
else
message = text("\red <B>[] is trying to take off \a [] from []'s head!</B>", source, target.wear_mask, target)
@@ -76,10 +76,10 @@
switch(place)
if("mask")
if (target.wear_mask)
if(istype(target.wear_mask, /obj/item/clothing)&& !target.wear_mask:canremove)
if(istype(target.wear_mask, /obj/item/clothing)&& (target.wear_mask:flags & NODROP))
return
var/obj/item/W = target.wear_mask
target.u_equip(W)
target.unEquip(W)
if (target.client)
target.client.screen -= W
if (W)
@@ -97,7 +97,7 @@
if("l_hand")
if (target.l_hand)
var/obj/item/W = target.l_hand
target.u_equip(W)
target.unEquip(W)
if (target.client)
target.client.screen -= W
if (W)
@@ -117,7 +117,7 @@
if("r_hand")
if (target.r_hand)
var/obj/item/W = target.r_hand
target.u_equip(W)
target.unEquip(W)
if (target.client)
target.client.screen -= W
if (W)
@@ -137,7 +137,7 @@
if("back")
if (target.back)
var/obj/item/W = target.back
target.u_equip(W)
target.unEquip(W)
if (target.client)
target.client.screen -= W
if (W)
@@ -155,7 +155,7 @@
if("handcuff")
if (target.handcuffed)
var/obj/item/W = target.handcuffed
target.u_equip(W)
target.unEquip(W)
if (target.client)
target.client.screen -= W
if (W)
@@ -164,7 +164,7 @@
W.layer = initial(W.layer)
W.add_fingerprint(source)
else
if (istype(item, /obj/item/weapon/handcuffs))
if (istype(item, /obj/item/weapon/restraints/handcuffs))
source.drop_item()
target.handcuffed = item
item.loc = target
@@ -199,7 +199,7 @@
if(!istype(W)) return
if(W == get_active_hand())
u_equip(W)
unEquip(W)
switch(slot)
if(slot_back)
@@ -274,11 +274,11 @@
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has pushed down [name]!</B>", M), 1)
else
drop_item()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has disarmed [name]!</B>", M), 1)
if(drop_item())
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has disarmed [name]!</B>", M), 1)
return
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
@@ -344,10 +344,10 @@
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has tackled down [name]!</B>", M), 1)
else
drop_item()
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has disarmed [name]!</B>", M), 1)
if(drop_item())
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has disarmed [name]!</B>", M), 1)
adjustBruteLoss(damage)
updatehealth()
return
+8 -8
View File
@@ -286,11 +286,11 @@
var/mob/living/carbon/C = src
if (C.handcuffed && !initial(C.handcuffed))
C.drop_from_inventory(C.handcuffed)
C.unEquip(C.handcuffed)
C.handcuffed = initial(C.handcuffed)
if (C.legcuffed && !initial(C.legcuffed))
C.drop_from_inventory(C.legcuffed)
C.unEquip(C.legcuffed)
C.legcuffed = initial(C.legcuffed)
hud_updateflag |= 1 << HEALTH_HUD
hud_updateflag |= 1 << STATUS_HUD
@@ -466,7 +466,7 @@
var/mob/M = H.loc //Get our mob holder (if any).
if(istype(M))
M.drop_from_inventory(H)
M.unEquip(H)
M << "[H] wriggles out of your grip!"
src << "You wriggle out of [M]'s grip!"
else if(istype(H.loc,/obj/item))
@@ -658,8 +658,8 @@
CM.handcuffed = null
CM.update_inv_handcuffed()
else
var/obj/item/weapon/handcuffs/HC = CM.handcuffed
var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/handcuffs type
var/obj/item/weapon/restraints/handcuffs/HC = CM.handcuffed
var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/restraints/handcuffs type
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
if(istype(HC)) //If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future...
breakouttime = HC.breakouttime
@@ -674,7 +674,7 @@
for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
O.show_message("\red <B>[CM] manages to remove the handcuffs!</B>", 1)
CM << "\blue You successfully remove \the [CM.handcuffed]."
CM.drop_from_inventory(CM.handcuffed)
CM.unEquip(CM.handcuffed)
else if(CM.legcuffed && CM.canmove && (CM.last_special <= world.time))
CM.next_move = world.time + 100
@@ -695,7 +695,7 @@
CM.legcuffed = null
CM.update_inv_legcuffed()
else
var/obj/item/weapon/legcuffs/HC = CM.legcuffed
var/obj/item/weapon/restraints/legcuffs/HC = CM.legcuffed
var/breakouttime = 1200 //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
if(istype(HC)) //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future...
@@ -711,7 +711,7 @@
for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
O.show_message("\red <B>[CM] manages to remove the legcuffs!</B>", 1)
CM << "\blue You successfully remove \the [CM.legcuffed]."
CM.drop_from_inventory(CM.legcuffed)
CM.unEquip(CM.legcuffed)
CM.legcuffed = null
CM.update_inv_legcuffed()
+173 -52
View File
@@ -1,3 +1,6 @@
#define AI_CHECK_WIRELESS 1
#define AI_CHECK_RADIO 2
var/list/ai_list = list()
//Not sure why this is necessary...
@@ -63,7 +66,7 @@ var/list/ai_list = list()
var/obj/item/borg/sight/hud/sec/sechud = null
var/obj/item/borg/sight/hud/med/healthhud = null
var/arrivalmsg = "$name, $rank, has arrived on the station."
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
@@ -77,8 +80,8 @@ var/list/ai_list = list()
possibleNames -= pickedName
pickedName = null
real_name = pickedName
name = real_name
aiPDA = new/obj/item/device/pda/ai(src)
SetName(pickedName)
anchored = 1
canmove = 0
density = 1
@@ -96,11 +99,6 @@ var/list/ai_list = list()
verbs += /mob/living/silicon/ai/proc/show_laws_verb
aiPDA = new/obj/item/device/pda/ai(src)
aiPDA.owner = name
aiPDA.ownjob = "AI"
aiPDA.name = name + " (" + aiPDA.ownjob + ")"
aiMulti = new(src)
aiRadio = new(src)
aiRadio.myAi = src
@@ -112,7 +110,7 @@ var/list/ai_list = list()
if (istype(loc, /turf))
verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
/mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall, /mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message)
/mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall, /mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message, /mob/living/silicon/ai/proc/ai_store_location, /mob/living/silicon/ai/proc/ai_goto_location, /mob/living/silicon/ai/proc/ai_remove_location, /mob/living/silicon/ai/proc/nano_crew_monitor, /mob/living/silicon/ai/proc/ai_cancel_call)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.
@@ -127,7 +125,7 @@ var/list/ai_list = list()
verbs.Remove(,/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \
/mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
/mob/living/silicon/ai/proc/toggle_camera_light,/mob/living/silicon/ai/verb/pick_icon,/mob/living/silicon/ai/proc/control_hud)
/mob/living/silicon/ai/proc/toggle_camera_light,/mob/living/silicon/ai/verb/pick_icon,/mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message, /mob/living/silicon/ai/proc/ai_cancel_call)
laws = new /datum/ai_laws/alienmov
else
B.brainmob.mind.transfer_to(src)
@@ -155,11 +153,25 @@ var/list/ai_list = list()
hud_list[IMPCHEM_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
init_subsystems()
ai_list += src
..()
return
/mob/living/silicon/ai/proc/SetName(pickedName as text)
real_name = pickedName
name = pickedName
if(eyeobj)
eyeobj.name = "[pickedName] (AI Eye)"
// Set ai pda name
if(aiPDA)
aiPDA.ownjob = "AI"
aiPDA.owner = pickedName
aiPDA.name = pickedName + " (" + aiPDA.ownjob + ")"
/mob/living/silicon/ai/Destroy()
ai_list -= src
@@ -301,14 +313,15 @@ var/list/ai_list = list()
if(src.stat == 2)
src << "You can't call the shuttle because you are dead!"
return
if(istype(usr,/mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = src
if(AI.control_disabled)
usr << "Wireless control is disabled!"
return
if(check_unable(AI_CHECK_WIRELESS))
return
var/confirm = alert("Are you sure you want to call the shuttle?", "Confirm Shuttle Call", "Yes", "No")
if(check_unable(AI_CHECK_WIRELESS))
return
if(confirm == "Yes")
call_shuttle_proc(src)
@@ -317,38 +330,57 @@ var/list/ai_list = list()
var/obj/machinery/computer/communications/C = locate() in machines
if(C)
C.post_status("shuttle")
return
/mob/living/silicon/ai/proc/ai_cancel_call()
set name = "Recall Emergency Shuttle"
set category = "AI Commands"
if(src.stat == 2)
src << "You can't send the shuttle back because you are dead!"
return
if(check_unable(AI_CHECK_WIRELESS))
return
var/confirm = alert("Are you sure you want to recall the shuttle?", "Confirm Shuttle Recall", "Yes", "No")
if(check_unable(AI_CHECK_WIRELESS))
return
if(confirm == "Yes")
cancel_call_proc(src)
/mob/living/silicon/ai/cancel_camera()
src.view_core()
/mob/living/silicon/ai/verb/toggle_anchor()
set category = "AI Commands"
set name = "Toggle Floor Bolts"
if(!isturf(loc)) // if their location isn't a turf
return // stop
anchored = !anchored // Toggles the anchor
set category = "AI Commands"
set name = "Toggle Floor Bolts"
if(!isturf(loc)) // if their location isn't a turf
return // stop
anchored = !anchored // Toggles the anchor
src << "[anchored ? "<b>You are now anchored.</b>" : "<b>You are now unanchored.</b>"]"
// the message in the [] will change depending whether or not the AI is anchored
src << "[anchored ? "<b>You are now anchored.</b>" : "<b>You are now unanchored.</b>"]"
/mob/living/silicon/ai/update_canmove()
return 0
/mob/living/silicon/ai/proc/ai_cancel_call()
set category = "Malfunction"
/mob/living/silicon/ai/proc/announcement()
set name = "Announcement"
set desc = "Create a vocal announcement by typing in the available words to create a sentence."
set category = "AI Commands"
if(src.stat == 2)
src << "You can't send the shuttle back because you are dead!"
src << "You can't call make an announcement because you are dead!"
return
if(istype(usr,/mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = src
if(AI.control_disabled)
src << "Wireless control is disabled!"
return
cancel_call_proc(src)
return
if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO))
return
ai_announcement()
/mob/living/silicon/ai/check_eye(var/mob/user as mob)
if (!current)
@@ -406,7 +438,7 @@ var/list/ai_list = list()
unset_machine()
src << browse(null, t1)
if (href_list["switchcamera"])
switchCamera(locate(href_list["switchcamera"])) in cameranet.viewpoints
switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras
if (href_list["showalerts"])
ai_alerts()
//Carn: holopad requests
@@ -581,18 +613,17 @@ var/list/ai_list = list()
src << "<span class='danger'>Critical error. System offline.</span>"
return
if(control_disabled)
src << "Wireless communication is disabled."
if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO))
return
var/turf/ai_current_turf = get_turf(src)
var/ai_Zlevel = ai_current_turf.z
var/ai_allowed_Zlevel = list(1,3,5)
var/d
var/area/bot_area
d += "<A HREF=?src=\ref[src];botrefresh=\ref[Bot]>Query network status</A><br>"
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='20%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
for (Bot in aibots)
if(Bot.z == ai_Zlevel && !Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
if((Bot.z in ai_allowed_Zlevel) && !Bot.remote_disabled) //Only non-emagged bots on the allowed Z-level are detected!
bot_area = get_area(Bot)
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!) </span>[Bot.name]" : Bot.name] ([Bot.bot_type_name])</td>"
//If the bot is on, it will display the bot's current mode status. If the bot is not mode, it will just report "Idle". "Inactive if it is not on at all.
@@ -631,8 +662,6 @@ var/list/ai_list = list()
/mob/living/silicon/ai/proc/switchCamera(var/obj/machinery/camera/C)
src.cameraFollow = null
if (!C || stat == 2) //C.can_use())
return 0
@@ -706,8 +735,10 @@ var/list/ai_list = list()
set category = "AI Commands"
set name = "Jump To Network"
unset_machine()
src.cameraFollow = null
var/cameralist[0]
if(check_unable())
return
if(usr.stat == 2)
usr << "You can't change your camera network because you are dead!"
@@ -715,16 +746,19 @@ var/list/ai_list = list()
var/mob/living/silicon/ai/U = usr
for (var/obj/machinery/camera/C in cameranet.viewpoints)
for (var/obj/machinery/camera/C in cameranet.cameras)
if(!C.can_use())
continue
var/list/tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS,1)
var/list/tempnetwork = difflist(C.network,restricted_camera_networks,1)
if(tempnetwork.len)
for(var/i in tempnetwork)
cameralist[i] = i
var/old_network = network
network = input(U, "Which network would you like to view?") as null|anything in cameralist
if(check_unable())
return
if(!U.eyeobj)
U.view_core()
@@ -733,7 +767,7 @@ var/list/ai_list = list()
if(isnull(network))
network = old_network // If nothing is selected
else
for(var/obj/machinery/camera/C in cameranet.viewpoints)
for(var/obj/machinery/camera/C in cameranet.cameras)
if(!C.can_use())
continue
if(network in C.network)
@@ -756,8 +790,16 @@ var/list/ai_list = list()
if(usr.stat == 2)
usr <<"You cannot change your emotional status because you are dead!"
return
if(check_unable())
return
var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Sad", "BSOD", "Blank", "Problems?", "Awesome", "Facepalm", "Friend Computer")
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
if(check_unable())
return
for (var/obj/machinery/M in machines) //change status
if(istype(M, /obj/machinery/ai_status_display))
var/obj/machinery/ai_status_display/AISD = M
@@ -777,6 +819,9 @@ var/list/ai_list = list()
set name = "Change Hologram"
set desc = "Change the default hologram available to AI to something else."
set category = "AI Commands"
if(check_unable())
return
var/input
if(alert("Would you like to select a hologram based on a crew member or switch to unique avatar?",,"Crew Member","Unique")=="Crew Member")
@@ -831,6 +876,9 @@ var/list/ai_list = list()
if(stat != CONSCIOUS)
return
if(check_unable())
return
camera_light_on = !camera_light_on
src << "Camera lights [camera_light_on ? "activated" : "deactivated"]."
@@ -846,12 +894,12 @@ var/list/ai_list = list()
set desc = "Augment visual feed with internal sensor overlays."
set category = "AI Commands"
toggle_sensor_mode()
/mob/living/silicon/ai/proc/change_arrival_message()
set name = "Set Arrival Message"
set desc = "Change the message that's transmitted when a new crew member arrives on station."
set category = "AI Commands"
var/newmsg = input("What would you like the arrival message to be? Use $name to substitute the crew member's name, and use $rank to substitute the crew member's rank.", "Change Arrival Message", arrivalmsg) as text
if(newmsg != arrivalmsg)
arrivalmsg = newmsg
@@ -908,7 +956,80 @@ var/list/ai_list = list()
set name = "Radio Settings"
set desc = "Allows you to change settings of your radio."
set category = "AI Commands"
src << "Accessing Subspace Transceiver control..."
if(check_unable(AI_CHECK_RADIO))
return
src << "Accessing Subspace Transceiver control..."
if (src.aiRadio)
src.aiRadio.interact(src)
/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target as mob)
if(!istype(target)) return
spawn(0)
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
src << "Unable to locate an airlock"
return
if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
src << "Unable to locate an airlock"
return
if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP))
src << "Unable to locate an airlock"
return
if(H.digitalcamo)
src << "Unable to locate an airlock"
return
if (!near_camera(target))
src << "Target is not near any active cameras."
return
var/obj/machinery/door/airlock/tobeopened
var/dist = -1
for(var/obj/machinery/door/airlock/D in range(3,target))
if(!D.density) continue
if(dist < 0)
dist = get_dist(D, target)
//world << dist
tobeopened = D
else
if(dist > get_dist(D, target))
dist = get_dist(D, target)
//world << dist
tobeopened = D
//world << "found [tobeopened.name] closer"
else
//world << "[D.name] not close enough | [get_dist(D, target)] | [dist]"
if(tobeopened)
switch(alert(src, "Do you want to open \the [tobeopened] for [target]?","Doorknob_v2a.exe","Yes","No"))
if("Yes")
var/nhref = "src=\ref[tobeopened];aiEnable=7"
tobeopened.Topic(nhref, params2list(nhref), tobeopened, 1)
src << "\blue You've opened \the [tobeopened] for [target]."
if("No")
src << "\red You deny the request."
else
src << "\red You've failed to open an airlock for [target]"
return
/mob/living/silicon/ai/proc/check_unable(var/flags = 0)
if(stat == DEAD)
usr << "\red You are dead!"
return 1
if((flags & AI_CHECK_WIRELESS) && src.control_disabled)
usr << "\red Wireless control is disabled!"
return 1
if((flags & AI_CHECK_RADIO) && src.aiRadio.disabledAi)
src << "\red System Error - Transceiver Disabled!"
return 1
return 0
/mob/living/silicon/ai/proc/is_in_chassis()
return istype(loc, /turf)
#undef AI_CHECK_WIRELESS
#undef AI_CHECK_RADIO
+3 -3
View File
@@ -15,21 +15,21 @@
var/callshuttle = 0
for(var/obj/machinery/computer/communications/commconsole in world)
if(commconsole.z == 2)
if((commconsole.z in config.admin_levels))
continue
if(istype(commconsole.loc,/turf))
break
callshuttle++
for(var/obj/item/weapon/circuitboard/communications/commboard in world)
if(commboard.z == 2)
if((commboard.z in config.admin_levels))
continue
if(istype(commboard.loc,/turf) || istype(commboard.loc,/obj/item/weapon/storage))
break
callshuttle++
for(var/mob/living/silicon/ai/shuttlecaller in player_list)
if(shuttlecaller.z == 2)
if((shuttlecaller.z in config.admin_levels))
continue
if(!shuttlecaller.stat && shuttlecaller.client && istype(shuttlecaller.loc,/turf))
break
@@ -1,25 +1,156 @@
/datum/visibility_network/cameras
ChunkType = /datum/visibility_chunk/camera
// CAMERA NET
//
// The datum containing all the chunks.
/datum/visibility_network/cameras/getViewpointFromMob(var/mob/currentMob)
var/mob/living/silicon/robot/currentRobot=currentMob
if(currentRobot)
return currentRobot.camera
return FALSE
var/datum/cameranet/cameranet = new()
/datum/visibility_network/cameras/validViewpoint(var/viewpoint)
var/obj/machinery/camera/c = viewpoint
if (!c)
return FALSE
return c.can_use()
/datum/cameranet
// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del().
var/list/cameras = list()
var/cameras_unsorted = 1
// The chunks of the map, mapping the areas that the cameras can see.
var/list/chunks = list()
var/ready = 0
/datum/cameranet/proc/process_sort()
if(cameras_unsorted)
cameras = dd_sortedObjectList(cameras)
cameras_unsorted = 0
// adding some indirection so that I don't have to edit a ton of files
/datum/visibility_network/cameras/proc/addCamera(var/camera)
return addViewpoint(camera)
// Checks if a chunk has been Generated in x, y, z.
/datum/cameranet/proc/chunkGenerated(x, y, z)
x &= ~0xf
y &= ~0xf
var/key = "[x],[y],[z]"
return (chunks[key])
/datum/visibility_network/cameras/proc/removeCamera(var/camera)
return removeViewpoint(camera)
// Returns the chunk in the x, y, z.
// If there is no chunk, it creates a new chunk and returns that.
/datum/cameranet/proc/getCameraChunk(x, y, z)
x &= ~0xf
y &= ~0xf
var/key = "[x],[y],[z]"
if(!chunks[key])
chunks[key] = new /datum/camerachunk(null, x, y, z)
/datum/visibility_network/cameras/proc/checkCameraVis(var/atom/target)
return checkCanSee(target)
return chunks[key]
// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
/datum/cameranet/proc/visibility(mob/aiEye/ai)
// 0xf = 15
var/x1 = max(0, ai.x - 16) & ~0xf
var/y1 = max(0, ai.y - 16) & ~0xf
var/x2 = min(world.maxx, ai.x + 16) & ~0xf
var/y2 = min(world.maxy, ai.y + 16) & ~0xf
var/list/visibleChunks = list()
for(var/x = x1; x <= x2; x += 16)
for(var/y = y1; y <= y2; y += 16)
visibleChunks += getCameraChunk(x, y, ai.z)
var/list/remove = ai.visibleCameraChunks - visibleChunks
var/list/add = visibleChunks - ai.visibleCameraChunks
for(var/chunk in remove)
var/datum/camerachunk/c = chunk
c.remove(ai)
for(var/chunk in add)
var/datum/camerachunk/c = chunk
c.add(ai)
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
/datum/cameranet/proc/updateVisibility(atom/A, var/opacity_check = 1)
if(!ticker || (opacity_check && !A.opacity))
return
majorChunkChange(A, 2)
/datum/cameranet/proc/updateChunk(x, y, z)
// 0xf = 15
if(!chunkGenerated(x, y, z))
return
var/datum/camerachunk/chunk = getCameraChunk(x, y, z)
chunk.hasChanged()
// Removes a camera from a chunk.
/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
if(c.can_use())
majorChunkChange(c, 0)
// Add a camera to a chunk.
/datum/cameranet/proc/addCamera(obj/machinery/camera/c)
if(c.can_use())
majorChunkChange(c, 1)
// Used for Cyborg cameras. Since portable cameras can be in ANY chunk.
/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c)
if(c.can_use())
majorChunkChange(c, 1)
//else
// majorChunkChange(c, 0)
// Never access this proc directly!!!!
// This will update the chunk and all the surrounding chunks.
// It will also add the atom to the cameras list if you set the choice to 1.
// Setting the choice to 0 will remove the camera from the chunks.
// If you want to update the chunks around an object, without adding/removing a camera, use choice 2.
/datum/cameranet/proc/majorChunkChange(atom/c, var/choice)
// 0xf = 15
if(!c)
return
var/turf/T = get_turf(c)
if(T)
var/x1 = max(0, T.x - 8) & ~0xf
var/y1 = max(0, T.y - 8) & ~0xf
var/x2 = min(world.maxx, T.x + 8) & ~0xf
var/y2 = min(world.maxy, T.y + 8) & ~0xf
//world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]"
for(var/x = x1; x <= x2; x += 16)
for(var/y = y1; y <= y2; y += 16)
if(chunkGenerated(x, y, T.z))
var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z)
if(choice == 0)
// Remove the camera.
chunk.cameras -= c
else if(choice == 1)
// You can't have the same camera in the list twice.
chunk.cameras |= c
chunk.hasChanged()
// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
/datum/cameranet/proc/checkCameraVis(mob/living/target as mob)
// 0xf = 15
var/turf/position = get_turf(target)
return checkTurfVis(position)
/datum/cameranet/proc/checkTurfVis(var/turf/position)
var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z)
if(chunk)
if(chunk.changed)
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
if(chunk.visibleTurfs[position])
return 1
return 0
// Debug verb for VVing the chunk that the turf is in.
/*
/turf/verb/view_chunk()
set src in world
if(cameranet.chunkGenerated(x, y, z))
var/datum/camerachunk/chunk = cameranet.getCameraChunk(x, y, z)
usr.client.debug_variables(chunk)
*/
@@ -1,23 +1,168 @@
/datum/visibility_chunk/camera
#define UPDATE_BUFFER 25 // 2.5 seconds
/datum/visibility_chunk/camera/validViewpoint(var/viewpoint)
var/obj/machinery/camera/c = viewpoint
if(!c)
return FALSE
if(!c.can_use())
return FALSE
var/turf/point = locate(src.x + 8, src.y + 8, src.z)
if(get_dist(point, c) > 24)
return FALSE
return TRUE
// CAMERA CHUNK
//
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
// Allows the AI Eye to stream these chunks and know what it can and cannot see.
/datum/camerachunk
var/list/obscuredTurfs = list()
var/list/visibleTurfs = list()
var/list/obscured = list()
var/list/cameras = list()
var/list/turfs = list()
var/list/seenby = list()
var/visible = 0
var/changed = 0
var/updating = 0
var/x = 0
var/y = 0
var/z = 0
/datum/visibility_chunk/camera/getVisibleTurfsForViewpoint(var/viewpoint)
var/obj/machinery/camera/c = viewpoint
return c.can_see()
// Add an AI eye to the chunk, then update if changed.
/datum/camerachunk/proc/add(mob/aiEye/ai)
if(!ai.ai)
return
ai.visibleCameraChunks += src
if(ai.ai.client)
ai.ai.client.images += obscured
visible++
seenby += ai
if(changed && !updating)
update()
// Remove an AI eye from the chunk, then update if changed.
/datum/camerachunk/proc/remove(mob/aiEye/ai)
if(!ai.ai)
return
ai.visibleCameraChunks -= src
if(ai.ai.client)
ai.ai.client.images -= obscured
seenby -= ai
if(visible > 0)
visible--
// Called when a chunk has changed. I.E: A wall was deleted.
/datum/camerachunk/proc/visibilityChanged(turf/loc)
if(!visibleTurfs[loc])
return
hasChanged()
// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will
// instead be flagged to update the next time an AI Eye moves near it.
/datum/camerachunk/proc/hasChanged(var/update_now = 0)
if(visible || update_now)
if(!updating)
updating = 1
spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once
update()
updating = 0
else
changed = 1
// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
/datum/camerachunk/proc/update()
set background = 1
var/list/newVisibleTurfs = list()
for(var/camera in cameras)
var/obj/machinery/camera/c = camera
if(!c)
continue
if(!c.can_use())
continue
var/turf/point = locate(src.x + 8, src.y + 8, src.z)
if(get_dist(point, c) > 24)
continue
for(var/turf/t in c.can_see())
newVisibleTurfs[t] = t
// Removes turf that isn't in turfs.
newVisibleTurfs &= turfs
var/list/visAdded = newVisibleTurfs - visibleTurfs
var/list/visRemoved = visibleTurfs - newVisibleTurfs
visibleTurfs = newVisibleTurfs
obscuredTurfs = turfs - newVisibleTurfs
for(var/turf in visAdded)
var/turf/t = turf
if(t.obscured)
obscured -= t.obscured
for(var/eye in seenby)
var/mob/aiEye/m = eye
if(!m || !m.ai)
continue
if(m.ai.client)
m.ai.client.images -= t.obscured
for(var/turf in visRemoved)
var/turf/t = turf
if(obscuredTurfs[t])
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
obscured += t.obscured
for(var/eye in seenby)
var/mob/aiEye/m = eye
if(!m || !m.ai)
seenby -= m
continue
if(m.ai.client)
m.ai.client.images += t.obscured
// Create a new camera chunk, since the chunks are made as they are needed.
/datum/camerachunk/New(loc, x, y, z)
// 0xf = 15
x &= ~0xf
y &= ~0xf
src.x = x
src.y = y
src.z = z
/datum/visibility_chunk/camera/findNearbyViewpoints()
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
if(c.can_use())
viewpoints += c
cameras += c
for(var/turf/t in range(10, locate(x + 8, y + 8, z)))
if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
turfs[t] = t
for(var/camera in cameras)
var/obj/machinery/camera/c = camera
if(!c)
continue
if(!c.can_use())
continue
for(var/turf/t in c.can_see())
visibleTurfs[t] = t
// Removes turf that isn't in turfs.
visibleTurfs &= turfs
obscuredTurfs = turfs - visibleTurfs
for(var/turf in obscuredTurfs)
var/turf/t = turf
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
obscured += t.obscured
#undef UPDATE_BUFFER
@@ -1,13 +1,12 @@
// AI EYE
//
// A mob that the AI controls to look around the station with.
// An invisible (no icon) mob that the AI controls to look around the station with.
// It streams chunks as it moves around, which will show it what the AI can and cannot see.
/mob/aiEye
name = "Inactive AI Eye"
icon = 'icons/mob/AI.dmi'
icon_state = "eye"
alpha = 127
icon = 'icons/obj/status_display.dmi' // For AI friend secret shh :o
var/list/visibleCameraChunks = list()
var/mob/living/silicon/ai/ai = null
density = 0
status_flags = GODMODE // You can't damage it.
@@ -15,20 +14,16 @@
see_in_dark = 7
invisibility = INVISIBILITY_AI_EYE
/mob/aiEye/New()
..()
visibility_interface = new /datum/visibility_interface/ai_eye(src)
// Movement code. Returns 0 to stop air movement from moving it.
/mob/aiEye/Move()
return 0
// Hide popout menu verbs
/mob/aiEye/examine()
/mob/aiEye/examine(atom/A as mob|obj|turf in view())
set popup_menu = 0
set src = usr.contents
return 0
/mob/aiEye/pull()
set popup_menu = 0
set src = usr.contents
@@ -41,11 +36,15 @@
// Use this when setting the aiEye's location.
// It will also stream the chunk that the new loc is in.
/mob/aiEye/setLoc(var/T, var/cancel_tracking = 1)
/mob/aiEye/setLoc(var/T)
if(ai)
if(!isturf(ai.loc))
return
if(cancel_tracking)
ai.ai_cancel_tracking()
T = get_turf(T)
loc = T
cameranet.visibility(src)
@@ -55,9 +54,12 @@
if(ai.holo)
ai.holo.move_hologram()
/mob/aiEye/proc/getLoc()
/mob/aiEye/Move()
return 0
if(ai)
if(!isturf(ai.loc) || !ai.client)
return
return ai.eyeobj.loc
// AI MOVEMENT
@@ -70,7 +72,6 @@
var/acceleration = 1
var/obj/machinery/hologram/holopad/holo = null
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
/mob/living/silicon/ai/New()
..()
@@ -79,7 +80,7 @@
spawn(5)
eyeobj.loc = src.loc
/mob/living/silicon/ai/Destroy()
/mob/living/silicon/ai/Del()
eyeobj.ai = null
del(eyeobj) // No AI, no Eye
..()
@@ -88,9 +89,7 @@
if(istype(usr, /mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = usr
if(AI.eyeobj && AI.client.eye == AI.eyeobj)
AI.cameraFollow = null
if (isturf(src.loc) || isturf(src))
AI.eyeobj.setLoc(src)
AI.eyeobj.setLoc(src)
// This will move the AIEye. It will also cause lights near the eye to light up, if toggled.
// This is handled in the proc below this one.
@@ -114,35 +113,36 @@
else
user.sprint = initial
user.cameraFollow = null
//user.unset_machine() //Uncomment this if it causes problems.
//user.lightNearbyCamera()
// Return to the Core.
/mob/living/silicon/ai/proc/view_core()
/mob/living/silicon/ai/proc/core()
set category = "AI Commands"
set name = "AI Core"
view_core()
/mob/living/silicon/ai/proc/view_core()
current = null
cameraFollow = null
unset_machine()
if(src.eyeobj && src.loc)
src.eyeobj.z = src.z
src.eyeobj.loc = src.loc
else
if(!src.eyeobj)
src << "ERROR: Eyeobj not found. Creating new eye..."
src.eyeobj = new(src.loc)
src.eyeobj.ai = src
src.eyeobj.name = "[src.name] (AI Eye)" // Give it a name
src.SetName(src.name)
if(client && client.eye)
client.eye = src
for(var/datum/visibility_chunk/camera/c in eyeobj.visibility_interface.visible_chunks)
for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
c.remove(eyeobj)
src.eyeobj.setLoc(src)
/mob/living/silicon/ai/verb/toggle_acceleration()
/mob/living/silicon/ai/proc/toggle_acceleration()
set category = "AI Commands"
set name = "Toggle Camera Acceleration"
@@ -20,7 +20,7 @@
HOW IT WORKS
It works by first creating a camera network datum. Inside of this camera network are "chunks" (which will be
explained later) and "cameras". The cameras list is kept up to date by obj/machinery/camera/New() and Destroy().
explained later) and "cameras". The cameras list is kept up to date by obj/machinery/camera/New() and Del().
Next the camera network has chunks. These chunks are a 16x16 tile block of turfs and cameras contained inside the chunk.
These turfs are then sorted out based on what the cameras can and cannot see. If none of the cameras can see the turf, inside
@@ -43,7 +43,7 @@
WHERE IS EVERYTHING?
cameraNetwork.dm = Everything about the cameraNetwork datum.
cameranet.dm = Everything about the cameranet datum.
chunk.dm = Everything about the chunk datum.
eye.dm = Everything about the AI and the AIEye.
updating.dm = Everything about triggers that will update chunks.
@@ -1,3 +1,80 @@
#define BORG_CAMERA_BUFFER 30
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
// TURFS
/turf
var/image/obscured
/turf/proc/visibilityChanged()
if(ticker)
cameranet.updateVisibility(src)
/turf/simulated/Del()
visibilityChanged()
..()
/turf/simulated/New()
..()
visibilityChanged()
// STRUCTURES
/obj/structure/Del()
if(ticker)
cameranet.updateVisibility(src)
..()
/obj/structure/New()
..()
if(ticker)
cameranet.updateVisibility(src)
// EFFECTS
/obj/effect/Del()
if(ticker)
cameranet.updateVisibility(src)
..()
/obj/effect/New()
..()
if(ticker)
cameranet.updateVisibility(src)
// DOORS
// Simply updates the visibility of the area when it opens/closes/destroyed.
/obj/machinery/door/update_nearby_tiles(need_rebuild)
. = ..(need_rebuild)
// Glass door glass = 1
// don't check then?
if(!glass && cameranet)
cameranet.updateVisibility(src, 0)
// ROBOT MOVEMENT
// Update the portable camera everytime the Robot moves.
// This might be laggy, comment it out if there are problems.
/mob/living/silicon/robot/var/updating = 0
/mob/living/silicon/robot/Move()
var/oldLoc = src.loc
. = ..()
if(.)
if(src.camera && src.camera.network.len)
if(!updating)
updating = 1
spawn(BORG_CAMERA_BUFFER)
if(oldLoc != src.loc)
cameranet.updatePortableCamera(src.camera)
updating = 0
// CAMERA
// An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not.
@@ -5,23 +82,29 @@
/obj/machinery/camera/deactivate(user as mob, var/choice = 1)
..(user, choice)
if(src.can_use())
cameranet.addViewpoint(src)
cameranet.addCamera(src)
else
src.SetLuminosity(0)
cameranet.removeViewpoint(src)
cameranet.removeCamera(src)
/obj/machinery/camera/New()
..()
cameranet.viewpoints += src //Camera must be added to global list of all cameras no matter what...
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) //...but if all of camera's networks are restricted, it only works for specific camera consoles.
//Camera must be added to global list of all cameras no matter what...
if(cameranet.cameras_unsorted || !ticker)
cameranet.cameras += src
cameranet.cameras_unsorted = 1
else
dd_insertObjectList(cameranet.cameras, src)
var/list/open_networks = difflist(network,restricted_camera_networks) //...but if all of camera's networks are restricted, it only works for specific camera consoles.
if(open_networks.len) //If there is at least one open network, chunk is available for AI usage.
cameranet.addViewpoint(src)
cameranet.addCamera(src)
/obj/machinery/camera/Del()
cameranet.viewpoints -= src
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS)
cameranet.cameras -= src
var/list/open_networks = difflist(network,restricted_camera_networks)
if(open_networks.len)
cameranet.removeViewpoint(src)
cameranet.removeCamera(src)
..()
#undef BORG_CAMERA_BUFFER
@@ -1,10 +0,0 @@
/datum/visibility_interface/ai_eye
chunk_type = /datum/visibility_chunk/camera
/datum/visibility_interface/ai_eye/getClient()
var/mob/aiEye/eye = controller
if (!eye)
return FALSE
if (!eye.ai)
return FALSE
return eye.ai.client
@@ -23,6 +23,10 @@
/mob/living/silicon/ai/proc/set_zeroth_law(var/law, var/law_borg)
src.laws_sanity_check()
src.laws.set_zeroth_law(law, law_borg)
/mob/living/silicon/ai/proc/clear_zeroth_law(var/law_borg)
src.laws_sanity_check()
src.laws.clear_zeroth_law(law_borg)
/mob/living/silicon/ai/proc/add_inherent_law(var/law)
src.laws_sanity_check()
@@ -0,0 +1,10 @@
var/obj/nano_module/crew_monitor/crew_monitor
/mob/living/silicon/ai/proc/init_subsystems()
crew_monitor = new(src)
/mob/living/silicon/ai/proc/nano_crew_monitor()
set category = "AI Commands"
set name = "Crew Monitor"
crew_monitor.ui_interact(usr)
+59 -78
View File
@@ -1,32 +1,32 @@
/mob/living/silicon/ai/say(var/message)
if(parent && istype(parent) && parent.stat != 2)
parent.say(message)
return
//If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
..(message)
if(parent && istype(parent) && parent.stat != 2)
parent.say(message) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
return
..(message)
/mob/living/silicon/ai/say_understands(var/other)
if (istype(other, /mob/living/carbon/human))
return 1
if (istype(other, /mob/living/silicon/robot))
return 1
if (istype(other, /mob/living/silicon/decoy))
return 1
if (istype(other, /mob/living/carbon/brain))
return 1
if (istype(other, /mob/living/silicon/pai))
return 1
return ..()
if (istype(other, /mob/living/carbon/human))
return 1
if (istype(other, /mob/living/silicon/robot))
return 1
if (istype(other, /mob/living/silicon/decoy))
return 1
if (istype(other, /mob/living/carbon/brain))
return 1
if (istype(other, /mob/living/silicon/pai))
return 1
return ..()
/mob/living/silicon/ai/say_quote(var/text)
var/ending = copytext(text, length(text))
var/ending = copytext(text, length(text))
if (ending == "?")
return "queries, \"[text]\"";
else if (ending == "!")
return "declares, \"[text]\"";
if (ending == "?")
return "queries, \"[text]\"";
else if (ending == "!")
return "declares, \"[text]\"";
return "states, \"[text]\"";
return "states, \"[text]\"";
/mob/living/silicon/ai/proc/IsVocal()
@@ -36,44 +36,28 @@ var/const/VOX_DELAY = 100
var/const/VOX_PATH = "sound/vox_fem/"
/mob/living/silicon/ai/verb/announcement_help()
set name = "Announcement Help"
set desc = "Display a list of vocal words to announce to the crew."
set category = "AI Commands"
var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.<BR> \
<UL><LI>You can also click on the word to preview it.</LI>\
<LI>You can only say 30 words for every announcement.</LI>\
<LI>Do not use punctuation as you would normally, if you want a pause you can use the full stop and comma characters by separating them with spaces, like so: 'Alpha . Test , Bravo'.</LI></UL>\
<font class='bad'>WARNING:</font><BR>Misuse of the announcement system will get you job banned.<HR>"
var/index = 0
for(var/word in vox_sounds)
index++
dat += "<A href='?src=\ref[src];say_word=[word]'>[capitalize(word)]</A>"
if(index != vox_sounds.len)
dat += " / "
var/datum/browser/popup = new(src, "announce_help", "Announcement Help", 500, 400)
popup.set_content(dat)
popup.open()
/mob/living/silicon/ai/proc/announcement()
set name = "Announcement"
set desc = "Create a vocal announcement by typing in the available words to create a sentence."
set name = "Announcement Help"
set desc = "Display a list of vocal words to announce to the crew."
set category = "AI Commands"
if(src.stat == 2)
src << "You can't call the shuttle because you are dead!"
return
if(istype(usr,/mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = src
if(AI.control_disabled)
usr << "Wireless control is disabled!"
return
var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.<BR> \
<UL><LI>You can also click on the word to preview it.</LI>\
<LI>You can only say 30 words for every announcement.</LI>\
<LI>Do not use punctuation as you would normally, if you want a pause you can use the full stop and comma characters by separating them with spaces, like so: 'Alpha . Test , Bravo'.</LI></UL>\
<font class='bad'>WARNING:</font><BR>Misuse of the announcement system will get you job banned.<HR>"
var/index = 0
for(var/word in vox_sounds)
index++
dat += "<A href='?src=\ref[src];say_word=[word]'>[capitalize(word)]</A>"
if(index != vox_sounds.len)
dat += " / "
var/datum/browser/popup = new(src, "announce_help", "Announcement Help", 500, 400)
popup.set_content(dat)
popup.open()
/mob/living/silicon/ai/proc/ai_announcement()
if(announcing_vox > world.time)
src << "<span class='notice'>Please wait [round((announcing_vox - world.time) / 10)] seconds.</span>"
return
@@ -112,27 +96,24 @@ var/const/VOX_PATH = "sound/vox_fem/"
/proc/play_vox_word(var/word, var/z_level, var/mob/only_listener)
word = lowertext(word)
if(vox_sounds[word])
var/sound_file = vox_sounds[word]
var/sound/voice = sound(sound_file, wait = 1, channel = VOX_CHANNEL)
voice.status = SOUND_STREAM
word = lowertext(word)
if(vox_sounds[word])
var/sound_file = vox_sounds[word]
var/sound/voice = sound(sound_file, wait = 1, channel = VOX_CHANNEL)
voice.status = SOUND_STREAM
// If there is no single listener, broadcast to everyone in the same z level
if(!only_listener)
// Play voice for all mobs in the z level
for(var/mob/M in player_list)
if(M.client)
var/turf/T = get_turf(M)
if(T.z == z_level)
M << voice
else
only_listener << voice
return 1
return 0
// If there is no single listener, broadcast to everyone in the same z level
if(!only_listener)
// Play voice for all mobs in the z level
for(var/mob/M in player_list)
if(M.client)
var/turf/T = get_turf(M)
if(T.z == z_level && !isdeaf(M))
M << voice
else
only_listener << voice
return 1
return 0
// VOX sounds moved to /code/defines/vox_sounds.dm
+63 -63
View File
@@ -149,7 +149,7 @@ They can only use one tool at a time, they can't choose modules, and they have 1
name = real_name
/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
return
if (istype(W, /obj/item/weapon/weldingtool))
@@ -240,68 +240,6 @@ They can only use one tool at a time, they can't choose modules, and they have 1
else
user << "\red Access denied."
else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card
if(!opened)//Cover is closed
if(locked)
if(prob(90))
user << "You emag the cover lock."
locked = 0
else
user << "You fail to emag the cover lock."
if(prob(25))
src << "Hack attempt detected."
else
user << "The cover is already unlocked."
return
if(opened)//Cover is open
if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice
if(wiresexposed)
user << "You must close the panel first"
return
else
sleep(6)
if(prob(50))
emagged = 1
lawupdate = 0
connected_ai = null
user << "You emag [src]'s interface."
// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.")
src << "\red ALERT: Foreign software detected."
sleep(5)
src << "\red Initiating diagnostics..."
sleep(20)
src << "\red SynBorg v1.7 loaded."
sleep(5)
src << "\red LAW SYNCHRONISATION ERROR"
sleep(5)
src << "\red Would you like to send a report to NanoTraSoft? Y/N"
sleep(10)
src << "\red > N"
sleep(20)
src << "\red ERRORERRORERROR"
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands."
if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner))
for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules)
del(D)
src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module)
src.module.rebuild()
updateicon()
else
user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface."
if(prob(25))
src << "Hack attempt detected."
return
else if(istype(W, /obj/item/borg/upgrade/))
var/obj/item/borg/upgrade/U = W
if(!opened)
@@ -322,6 +260,68 @@ They can only use one tool at a time, they can't choose modules, and they have 1
else
spark_system.start()
return ..()
/mob/living/silicon/robot/mommi/emag_act(user as mob)
if(!opened)//Cover is closed
if(locked)
if(prob(90))
user << "You emag the cover lock."
locked = 0
else
user << "You fail to emag the cover lock."
if(prob(25))
src << "Hack attempt detected."
else
user << "The cover is already unlocked."
return
if(opened)//Cover is open
if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice
if(wiresexposed)
user << "You must close the panel first"
return
else
sleep(6)
if(prob(50))
emagged = 1
lawupdate = 0
connected_ai = null
user << "You emag [src]'s interface."
// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.")
src << "\red ALERT: Foreign software detected."
sleep(5)
src << "\red Initiating diagnostics..."
sleep(20)
src << "\red SynBorg v1.7 loaded."
sleep(5)
src << "\red LAW SYNCHRONISATION ERROR"
sleep(5)
src << "\red Would you like to send a report to NanoTraSoft? Y/N"
sleep(10)
src << "\red > N"
sleep(20)
src << "\red ERRORERRORERROR"
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands."
if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner))
for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules)
del(D)
src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module)
src.module.rebuild()
updateicon()
else
user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface."
if(prob(25))
src << "Hack attempt detected."
return
/mob/living/silicon/robot/mommi/attack_hand(mob/user)
add_fingerprint(user)
+1 -2
View File
@@ -334,7 +334,7 @@
//I'm not sure how much of this is necessary, but I would rather avoid issues.
if(istype(card.loc,/mob))
var/mob/holder = card.loc
holder.drop_from_inventory(card)
holder.unEquip(card)
else if(istype(card.loc,/obj/item/clothing/suit/space/space_ninja))
var/obj/item/clothing/suit/space/space_ninja/holder = card.loc
holder.pai = null
@@ -503,4 +503,3 @@
spawn(1)
close_up()
return 2
@@ -168,7 +168,7 @@
icon_state = "robotanalyzer"
item_state = "analyzer"
desc = "A hand-held scanner able to diagnose robotic injuries."
flags = FPRINT | TABLEPASS | CONDUCT
flags = CONDUCT
slot_flags = SLOT_BELT
throwforce = 3
w_class = 2.0
@@ -172,41 +172,6 @@
user << "The machine is hermetically sealed. You can't open the case."
return
else if (istype(W, /obj/item/weapon/card/emag))
if(!client || stat == 2)
user << "\red There's not much point subverting this heap of junk."
return
if(emagged)
src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt."
user << "\red You attempt to subvert [src], but the sequencer has no effect."
return
user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker."
src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script."
var/obj/item/weapon/card/emag/emag = W
emag.uses--
message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.")
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
emagged = 1
lawupdate = 0
connected_ai = null
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.")
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands."
return
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if(stat == 2)
@@ -242,6 +207,41 @@
return
..()
/mob/living/silicon/robot/drone/emag_act(user as mob)
if(!client || stat == 2)
user << "\red There's not much point subverting this heap of junk."
return
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(emagged)
src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt."
user << "\red You attempt to subvert [src], but the sequencer has no effect."
return
user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker."
src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script."
message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.")
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [H.name]([H.key]) emagged [name]([key])")
emagged = 1
lawupdate = 0
connected_ai = null
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
set_zeroth_law("Only [H.real_name] and people he designates as being such are Syndicate Agents.")
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "\red \b ALERT: [H.real_name] is your new master. Obey your new laws and his commands."
return
//DRONE LIFE/DEATH
@@ -77,6 +77,10 @@
laws_sanity_check()
laws.set_zeroth_law(law)
/mob/living/silicon/robot/proc/clear_zeroth_law()
laws_sanity_check()
laws.clear_zeroth_law()
/mob/living/silicon/robot/proc/add_inherent_law(var/law)
laws_sanity_check()
laws.add_inherent_law(law)
+72 -82
View File
@@ -188,12 +188,12 @@
/mob/living/silicon/robot/proc/pick_module()
if(module)
return
var/list/modules = list("Standard", "Engineering", "Surgeon", "Crisis", "Miner", "Janitor", "Service", "Security")
var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
if(security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis)
src << "\red Crisis mode active. Combat module available."
modules+="Combat"
if(mmi != null && mmi.alien)
modules="Hunter"
modules = "Hunter"
modtype = input("Please, select a module!", "Robot", null, null) in modules
designation = modtype
var/module_sprites[0] //Used to store the associations between sprite names and sprite index.
@@ -237,8 +237,8 @@
module_sprites["Advanced Droid"] = "droid-miner"
module_sprites["Treadhead"] = "Miner"
if("Crisis")
module = new /obj/item/weapon/robot_module/crisis(src)
if("Medical")
module = new /obj/item/weapon/robot_module/medical(src)
channels = list("Medical" = 1)
if(camera && "Robots" in camera.network)
camera.network.Add("Medical")
@@ -247,17 +247,6 @@
module_sprites["Advanced Droid"] = "droid-medical"
module_sprites["Needles"] = "medicalrobot"
if("Surgeon")
module = new /obj/item/weapon/robot_module/surgeon(src)
channels = list("Medical" = 1)
if(camera && "Robots" in camera.network)
camera.network.Add("Medical")
module_sprites["Basic"] = "Medbot"
module_sprites["Standard"] = "surgeon"
module_sprites["Advanced Droid"] = "droid-medical"
module_sprites["Needles"] = "medicalrobot"
if("Security")
module = new /obj/item/weapon/robot_module/security(src)
channels = list("Security" = 1)
@@ -643,7 +632,7 @@
/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
return
if(opened) // Are they trying to insert something?
@@ -808,72 +797,6 @@
else
user << "\red Access denied."
else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card
if(!opened)//Cover is closed
if(locked)
if(prob(90))
var/obj/item/weapon/card/emag/emag = W
emag.uses--
user << "You emag the cover lock."
locked = 0
else
user << "You fail to emag the cover lock."
if(prob(25))
src << "Hack attempt detected."
else
user << "The cover is already unlocked."
return
if(opened)//Cover is open
if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice
if(wiresexposed)
user << "You must close the panel first"
return
else
sleep(6)
if(prob(50))
emagged = 1
if(user.hud_used)
user.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open.
lawupdate = 0
connected_ai = null
user << "You emag [src]'s interface."
// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.")
src << "\red ALERT: Foreign software detected."
sleep(5)
src << "\red Initiating diagnostics..."
sleep(20)
src << "\red SynBorg v1.7 loaded."
sleep(5)
src << "\red LAW SYNCHRONISATION ERROR"
sleep(5)
src << "\red Would you like to send a report to NanoTraSoft? Y/N"
sleep(10)
src << "\red > N"
sleep(20)
src << "\red ERRORERRORERROR"
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands."
if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner))
for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules)
del(D)
src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module)
src.module.rebuild()
updateicon()
else
user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface."
if(prob(25))
src << "Hack attempt detected."
return
else if(istype(W, /obj/item/borg/upgrade/))
var/obj/item/borg/upgrade/U = W
if(!opened)
@@ -894,6 +817,73 @@
else
spark_system.start()
return ..()
/mob/living/silicon/robot/emag_act(user as mob)
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(!opened)//Cover is closed
if(locked)
if(prob(90))
user << "You emag the cover lock."
locked = 0
else
user << "You fail to emag the cover lock."
if(prob(25))
src << "Hack attempt detected."
else
user << "The cover is already unlocked."
return
if(opened)//Cover is open
if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice
if(wiresexposed)
user << "You must close the panel first"
return
else
sleep(6)
if(prob(50))
emagged = 1
if(H.hud_used)
H.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open.
lawupdate = 0
connected_ai = null
user << "You emag [src]'s interface."
// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [H.name]([H.key]) emagged [name]([key])")
set_zeroth_law("Only [H.real_name] and people he designates as being such are Syndicate Agents.")
src << "\red ALERT: Foreign software detected."
sleep(5)
src << "\red Initiating diagnostics..."
sleep(20)
src << "\red SynBorg v1.7 loaded."
sleep(5)
src << "\red LAW SYNCHRONISATION ERROR"
sleep(5)
src << "\red Would you like to send a report to NanoTraSoft? Y/N"
sleep(10)
src << "\red > N"
sleep(20)
src << "\red ERRORERRORERROR"
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "\red \b ALERT: [H.real_name] is your new master. Obey your new laws and his commands."
if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner))
for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules)
del(D)
src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module)
src.module.rebuild()
updateicon()
else
user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface."
if(prob(25))
src << "Hack attempt detected."
return
/mob/living/silicon/robot/verb/unlock_own_cover()
set category = "Robot Commands"
@@ -4,7 +4,7 @@
icon_state = "std_module"
w_class = 100.0
item_state = "electronic"
flags = FPRINT|TABLEPASS | CONDUCT
flags = CONDUCT
var/list/modules = list()
var/obj/item/emag = null
@@ -71,10 +71,12 @@
src.emag = new /obj/item/weapon/melee/energy/sword/cyborg(src)
return
/obj/item/weapon/robot_module/surgeon
name = "surgeon robot module"
/obj/item/weapon/robot_module/medical
name = "medical robot module"
stacktypes = list(
/obj/item/stack/medical/advanced/bruise_pack = 5,
/obj/item/stack/medical/advanced/ointment = 5,
/obj/item/stack/medical/splint = 5,
/obj/item/stack/nanopaste = 5
)
@@ -82,7 +84,18 @@
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash/cyborg(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src)
src.modules += new /obj/item/device/reagent_scanner/adv(src)
src.modules += new /obj/item/weapon/borg_defib(src)
src.modules += new /obj/item/roller_holder(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo(src)
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
src.modules += new /obj/item/weapon/reagent_containers/dropper(src)
src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
src.modules += new /obj/item/weapon/extinguisher/mini(src)
src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src)
src.modules += new /obj/item/stack/medical/advanced/ointment(src)
src.modules += new /obj/item/stack/medical/splint(src)
src.modules += new /obj/item/stack/nanopaste(src)
src.modules += new /obj/item/weapon/scalpel(src)
src.modules += new /obj/item/weapon/hemostat(src)
src.modules += new /obj/item/weapon/retractor(src)
@@ -92,9 +105,6 @@
src.modules += new /obj/item/weapon/bonesetter(src)
src.modules += new /obj/item/weapon/circular_saw(src)
src.modules += new /obj/item/weapon/surgicaldrill(src)
src.modules += new /obj/item/weapon/extinguisher/mini(src)
src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src)
src.modules += new /obj/item/stack/nanopaste(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
@@ -102,59 +112,12 @@
src.emag.name = "Polyacid spray"
return
/obj/item/weapon/robot_module/surgeon/respawn_consumable(var/mob/living/silicon/robot/R)
/obj/item/weapon/robot_module/medical/respawn_consumable(var/mob/living/silicon/robot/R)
if(src.emag)
var/obj/item/weapon/reagent_containers/spray/PS = src.emag
PS.reagents.add_reagent("pacid", 2)
..()
/obj/item/weapon/robot_module/crisis
name = "crisis robot module"
stacktypes = list(
/obj/item/stack/medical/advanced/ointment = 5,
/obj/item/stack/medical/advanced/bruise_pack = 5,
/obj/item/stack/medical/splint = 5
)
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash/cyborg(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/device/reagent_scanner/adv(src)
src.modules += new /obj/item/roller_holder(src)
src.modules += new /obj/item/stack/medical/advanced/ointment(src)
src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src)
src.modules += new /obj/item/stack/medical/splint(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/crisis(src)
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
src.modules += new /obj/item/weapon/extinguisher/mini(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("pacid", 250)
src.emag.name = "Polyacid spray"
var/obj/item/weapon/reagent_containers/spray/S = emag
S.banned_reagents = list()
return
/obj/item/weapon/robot_module/crisis/respawn_consumable(var/mob/living/silicon/robot/R)
var/obj/item/weapon/reagent_containers/syringe/S = locate() in src.modules
if(S.mode == 2)
S.reagents.clear_reagents()
S.mode = initial(S.mode)
S.desc = initial(S.desc)
S.update_icon()
if(src.emag)
var/obj/item/weapon/reagent_containers/spray/PS = src.emag
PS.reagents.add_reagent("pacid", 2)
..()
/obj/item/weapon/robot_module/engineering
name = "engineering robot module"
@@ -220,7 +183,7 @@
New()
src.modules += new /obj/item/device/flashlight/seclite(src)
src.modules += new /obj/item/device/flash/cyborg(src)
src.modules += new /obj/item/weapon/handcuffs/cyborg(src)
src.modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
src.modules += new /obj/item/weapon/melee/baton/robot(src)
src.modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src)
src.modules += new /obj/item/taperoll/police(src)
@@ -0,0 +1,21 @@
/mob/living/simple_animal/butterfly
name = "butterfly"
desc = "A colorful butterfly, how'd it get up here?"
icon_state = "butterfly"
icon_living = "butterfly"
icon_dead = "butterfly_dead"
turns_per_move = 1
emote_see = list("flutters")
response_help = "shoos"
response_disarm = "brushes aside"
response_harm = "aquashes"
speak_chance = 0
maxHealth = 2
health = 2
harm_intent_damage = 1
friendly = "nudges"
pass_flags = PASSTABLE
/mob/living/simple_animal/butterfly/New()
..()
color = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
@@ -25,7 +25,15 @@
var/obj/item/inventory_back
var/facehugger
/mob/living/simple_animal/corgi/Life()
/mob/living/simple_animal/corgi/New()
..()
regenerate_icons()
/mob/living/simple_animal/corgi/Die()
..()
regenerate_icons()
/mob/living/simple_animal/corgi/revive()
..()
regenerate_icons()
@@ -33,7 +41,7 @@
user.set_machine(src)
if(user.stat) return
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
var/dat = "<div align='center'><b>Inventory of [real_name]</b></div><p>"
if(inventory_head)
dat += "<br><b>Head:</b> [inventory_head] (<a href='?src=\ref[src];remove_inv=head'>Remove</a>)"
else
@@ -85,6 +93,7 @@
SetLuminosity(0)
inventory_head.loc = src.loc
inventory_head = null
regenerate_icons()
else
usr << "\red There is nothing to remove from its [remove_from]."
return
@@ -92,6 +101,7 @@
if(inventory_back)
inventory_back.loc = src.loc
inventory_back = null
regenerate_icons()
else
usr << "\red There is nothing to remove from its [remove_from]."
return
@@ -163,6 +173,7 @@
usr.drop_item()
place_on_head(item_to_add)
regenerate_icons()
if("back")
if(inventory_back)
@@ -383,7 +394,7 @@
..()
/mob/living/simple_animal/corgi/regenerate_icons()
overlays = list()
overlays.Cut()
if(inventory_head)
var/head_icon_state = inventory_head.icon_state
@@ -471,14 +482,12 @@
icon_living = "borgi"
var/emagged = 0
/mob/living/simple_animal/corgi/Ian/borgi/attackby(var/obj/item/O as obj, var/mob/user as mob)
if (istype(O, /obj/item/weapon/card/emag) && !emagged)
/mob/living/simple_animal/corgi/Ian/borgi/emag_act(user as mob)
if(!emagged)
emagged = 1
visible_message("<span class='warning'>[user] swipes a card through [src].</span>", "<span class='notice'>You overload [src]s internal reactor.</span>")
spawn (1000)
src.explode()
return
..()
/mob/living/simple_animal/corgi/Ian/borgi/proc/explode()
for(var/mob/M in viewers(src, null))
@@ -30,4 +30,4 @@
icon_living = "Syndifox"
icon_dead = "Syndifox_dead"
flags = IS_SYNTHETIC|NO_BREATHE
faction = list("syndicate")
faction = list("syndicate")
@@ -0,0 +1,42 @@
//Corgi //best comment 2014
/mob/living/simple_animal/pug
name = "\improper pug"
real_name = "pug"
desc = "It's a pug."
icon_state = "pug"
icon_living = "pug"
icon_dead = "pug_dead"
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
speak_emote = list("barks", "woofs")
emote_hear = list("barks!", "woofs!", "yaps.","pants.")
emote_see = list("shakes its head.", "chases its tail.","shivers.")
speak_chance = 1
turns_per_move = 10
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/pug
meat_amount = 3
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
see_in_dark = 5
/mob/living/simple_animal/pug/Life()
..()
if(!stat && !resting && !buckled)
if(prob(1))
emote("me", 1, pick("chases its tail."))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
dir = i
sleep(1)
/mob/living/simple_animal/pug/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/weapon/newspaper))
if(!stat)
user.visible_message("<span class='notice'>[user] baps [name] on the nose with the rolled up [O]</span>")
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2))
dir = i
sleep(1)
else
..()
@@ -125,18 +125,6 @@
else
user << "\red You swipe your card, with no effect."
return 0
else if (istype(O, /obj/item/weapon/card/emag))
if (emagged)
user << "\red [src] is already overloaded - better run."
return 0
else
var/obj/item/weapon/card/emag/emag = O
emag.uses--
emagged = 1
user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time."
spawn(100) src << "\red Your cell seems to be outputting a lot of power..."
spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!"
spawn(300) src.explode()
else
if(O.force)
@@ -152,6 +140,17 @@
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with the [O]. ")
/mob/living/simple_animal/spiderbot/emag_act(user as mob)
if (emagged)
user << "\red [src] is already overloaded - better run."
return 0
else
emagged = 1
user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time."
spawn(100) src << "\red Your cell seems to be outputting a lot of power..."
spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!"
spawn(300) src.explode()
/mob/living/simple_animal/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj)
@@ -625,7 +625,7 @@
stolen_item = C.r_hand
if(stolen_item)
C.u_equip(stolen_item)
C.unEquip(stolen_item)
held_item = stolen_item
stolen_item.loc = src
visible_message("[src] grabs the [held_item] out of [C]'s hand!", "\blue You snag the [held_item] out of [C]'s hand!", "You hear the sounds of wings flapping furiously.")
@@ -29,6 +29,7 @@
var/response_disarm = "shoves"
var/response_harm = "hits"
var/harm_intent_damage = 3
var/force_threshold = 0 //Minimum force required to deal any damage
//Temperature effect
var/minbodytemp = 250
@@ -372,7 +373,6 @@
/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/stack/medical))
if(stat != DEAD)
var/obj/item/stack/medical/MED = O
if(health < maxHealth)
@@ -399,20 +399,22 @@
if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
harvest()
else
var/damage = 0
if(O.force)
var/damage = O.force
if (O.damtype == STAMINA)
damage = 0
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b "+"[src] has been attacked with [O] by [user]. ")
if(O.force >= force_threshold)
damage = O.force
if (O.damtype == STAMINA)
damage = 0
visible_message("<span class='danger'>[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] [src] with [O]!</span>",\
"<span class='userdanger'>[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] you with [O]!</span>")
else
visible_message("<span class='danger'>[O] bounces harmlessly off of [src].</span>",\
"<span class='userdanger'>[O] bounces harmlessly off of [src].</span>")
playsound(loc, O.hitsound, 50, 1, -1)
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with [O]. ")
user.visible_message("<span class='warning'>[user] gently taps [src] with [O].</span>",\
"<span class='warning'>This weapon is ineffective, it does no damage.</span>")
adjustBruteLoss(damage)
/mob/living/simple_animal/movement_delay()
+20 -19
View File
@@ -246,7 +246,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & SLOT_BACK) )
return 0
if(H.back)
if(H.back.canremove)
if(!(H.back.flags & NODROP))
return 2
else
return 0
@@ -255,7 +255,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & SLOT_OCLOTHING) )
return 0
if(H.wear_suit)
if(H.wear_suit.canremove)
if(!(H.wear_suit.flags & NODROP))
return 2
else
return 0
@@ -264,7 +264,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & SLOT_GLOVES) )
return 0
if(H.gloves)
if(H.gloves.canremove)
if(!(H.gloves.flags & NODROP))
return 2
else
return 0
@@ -273,7 +273,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & SLOT_FEET) )
return 0
if(H.shoes)
if(H.shoes.canremove)
if(!(H.shoes.flags & NODROP))
return 2
else
return 0
@@ -286,7 +286,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & SLOT_BELT) )
return 0
if(H.belt)
if(H.belt.canremove)
if(!(H.belt.flags & NODROP))
return 2
else
return 0
@@ -295,7 +295,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & SLOT_EYES) )
return 0
if(H.glasses)
if(H.glasses.canremove)
if(!(H.glasses.flags & NODROP))
return 2
else
return 0
@@ -304,7 +304,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & SLOT_HEAD) )
return 0
if(H.head)
if(H.head.canremove)
if(!(H.head.flags & NODROP))
return 2
else
return 0
@@ -313,7 +313,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & slot_l_ear) )
return 0
if(H.l_ear)
if(H.l_ear.canremove)
if(!(H.l_ear.flags & NODROP))
return 2
else
return 0
@@ -322,7 +322,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & slot_r_ear) )
return 0
if(H.r_ear)
if(H.r_ear.canremove)
if(!(H.r_ear.flags & NODROP))
return 2
else
return 0
@@ -333,7 +333,7 @@ var/list/slot_equipment_priority = list( \
if((M_FAT in H.mutations) && !(flags & ONESIZEFITSALL))
return 0
if(H.w_uniform)
if(H.w_uniform.canremove)
if(!(H.w_uniform.flags & NODROP))
return 2
else
return 0
@@ -346,7 +346,7 @@ var/list/slot_equipment_priority = list( \
if( !(slot_flags & SLOT_ID) )
return 0
if(H.wear_id)
if(H.wear_id.canremove)
if(!(H.wear_id.flags & NODROP))
return 2
else
return 0
@@ -389,7 +389,7 @@ var/list/slot_equipment_priority = list( \
return 0
if( istype(src, /obj/item/device/pda) || istype(src, /obj/item/weapon/pen) || is_type_in_list(src, H.wear_suit.allowed) )
if(H.s_store)
if(H.s_store.canremove)
if(!(H.s_store.flags & NODROP))
return 2
else
return 0
@@ -399,13 +399,13 @@ var/list/slot_equipment_priority = list( \
if(slot_handcuffed)
if(H.handcuffed)
return 0
if(!istype(src, /obj/item/weapon/handcuffs))
if(!istype(src, /obj/item/weapon/restraints/handcuffs))
return 0
return 1
if(slot_legcuffed)
if(H.legcuffed)
return 0
if(!istype(src, /obj/item/weapon/legcuffs))
if(!istype(src, /obj/item/weapon/restraints/legcuffs))
return 0
return 1
if(slot_in_backpack)
@@ -438,9 +438,9 @@ var/list/slot_equipment_priority = list( \
<B><HR><FONT size=3>[name]</FONT></B>
<BR><HR>
<BR><B>Head(Mask):</B> <A href='?src=\ref[src];item=mask'>[(wear_mask ? wear_mask : "Nothing")]</A>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand ? l_hand : "Nothing")]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand ? r_hand : "Nothing")]</A>
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back ? back : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand && !(l_hand.flags & ABSTRACT)) ? l_hand : "Nothing"]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand && !(r_hand.flags & ABSTRACT)) ? r_hand : "Nothing"]</A>
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back && !(back.flags & ABSTRACT)) ? back : "Nothing"]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
<BR><A href='?src=\ref[src];item=pockets'>Empty Pockets</A>
<BR><A href='?src=\ref[user];refresh=1'>Refresh</A>
@@ -881,8 +881,9 @@ var/list/slot_equipment_priority = list( \
stat(null, "Bots-[master_controller.aibots_cost]\t#[aibots.len]")
stat(null, "Obj-[master_controller.objects_cost]\t#[processing_objects.len]")
stat(null, "PiNet-[master_controller.networks_cost]\t#[pipe_networks.len]")
stat(null, "Ponet-[master_controller.powernets_cost]\t#[powernets.len]")
stat(null, "PoNet-[master_controller.powernets_cost]\t#[powernets.len]")
stat(null, "NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]")
stat(null,"Events-[master_controller.events_cost]\t#[event_manager.active_events.len]")
// stat(null, "GC-[master_controller.gc_cost]\t#[garbage.queue.len]")
stat(null, "Tick-[master_controller.ticker_cost]")
stat(null, "ALL-[master_controller.total_cost]")
@@ -1235,7 +1236,7 @@ mob/proc/yank_out_object()
if(jobban_isbanned(usr, "NPC"))
usr << "<span class='warning'>You are banned from playing as NPC's.</span>"
return
if((usr in respawnable_list) && (stat==2 || istype(usr,/mob/dead/observer)))
var/list/creatures = list("Mouse")
for(var/mob/living/L in living_mob_list)
+1 -2
View File
@@ -3,7 +3,7 @@
/obj/item/weapon/grab
name = "grab"
flags = NOBLUDGEON
flags = NOBLUDGEON | ABSTRACT
var/obj/screen/grab/hud = null
var/mob/affecting = null
var/mob/assailant = null
@@ -12,7 +12,6 @@
var/last_upgrade = 0
layer = 21
abstract = 1
item_state = "nothing"
w_class = 5.0
+17 -3
View File
@@ -150,7 +150,7 @@ proc/isorgan(A)
if(L && L.implanted)
return 1
return 0
proc/isnewplayer(A)
if(istype(A, /mob/new_player))
return 1
@@ -159,9 +159,23 @@ proc/isnewplayer(A)
proc/hasorgans(A)
return ishuman(A)
proc/isdeaf(A)
if(istype(A, /mob))
var/mob/M = A
return (M.sdisabilities & DEAF) || M.ear_deaf
return 0
/proc/hsl2rgb(h, s, l)
return
proc/hassensorlevel(A, var/level)
var/mob/living/carbon/human/H = A
if(istype(H) && istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = H.w_uniform
return U.sensor_mode >= level
return 0
/proc/check_zone(zone)
if(!zone) return "chest"
@@ -344,10 +358,10 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
/mob/proc/abiotic(var/full_body = 0)
if(full_body && ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask)))
if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask)))
return 1
if((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )))
if((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)))
return 1
return 0
@@ -30,7 +30,7 @@
if(!M || !ismob(M))
usr << "Type path is not a mob (new_type = [new_type]) in change_mob_type(). Contact a coder."
del(M)
qdel(M)
return
if( istext(new_name) )
@@ -43,12 +43,12 @@
if(src.dna)
M.dna = src.dna.Clone()
if(mind)
if(mind && istype(M, /mob/living))
mind.transfer_to(M)
else
M.key = key
if(delete_old_mob)
spawn(1)
del(src)
qdel(src)
return M
-48
View File
@@ -19,54 +19,6 @@ It reuses a lot of code from the AIEye cameraNetwork. In order to work properly,
if (vp)
return TRUE
return FALSE
/datum/visibility_chunk/cult/validViewpoint(var/atom/viewpoint)
var/turf/point = locate(src.x + 8, src.y + 8, src.z)
if(get_dist(point, viewpoint) > 24)
return FALSE
if (isCultRune(viewpoint) || isCultViewpoint(viewpoint))
return viewpoint:can_use()
return FALSE
/datum/visibility_chunk/cult/getVisibleTurfsForViewpoint(var/viewpoint)
var/obj/effect/rune/rune = viewpoint
if (rune)
return rune.can_see()
var/obj/cult_viewpoint/cvp = viewpoint
if (cvp)
return cvp.can_see()
return null
/datum/visibility_chunk/cult/findNearbyViewpoints()
for(var/obj/cult_viewpoint/vp in range(16, locate(x + 8, y + 8, z)))
if(vp.can_use())
viewpoints += vp
for(var/obj/effect/rune/rune in range(16, locate(x + 8, y + 8, z)))
viewpoints += rune
/datum/visibility_network/cult
ChunkType = /datum/visibility_chunk/cult
/datum/visibility_network/cult/validViewpoint(var/viewpoint)
if (isCultRune(viewpoint) || isCultViewpoint(viewpoint))
return viewpoint:can_use()
return FALSE
/datum/visibility_network/cult/getViewpointFromMob(var/mob/currentMob)
for(var/obj/cult_viewpoint/currentView in currentMob)
return currentView
return FALSE
/datum/visibility_interface/cult
chunk_type = /datum/visibility_chunk/cult
/*
RUNE JUNK
-1
View File
@@ -52,7 +52,6 @@ mob/spirit/proc/Spirit_Move(direct)
mob/spirit/setLoc(var/T)
T = get_turf(T)
loc = T
cultNetwork.visibility(src)
mob/spirit/verb/toggle_acceleration()
set category = "Spirit"
-3
View File
@@ -38,9 +38,6 @@ mob/spirit/New()
loc = pick(latejoin)
// hook them to the cult visibility network
visibility_interface = new /datum/visibility_interface/cult(src)
// no nameless spirits
if (!name)
name = "Boogyman"
+2 -6
View File
@@ -18,9 +18,6 @@ var/obj/cult_viewpoint/list/cult_viewpoints = list()
/obj/cult_viewpoint/New(var/mob/target)
owner = target
//src.loc = owner
owner.addToVisibilityNetwork(cultNetwork)
cultNetwork.viewpoints+=src
cultNetwork.addViewpoint(src)
cult_viewpoints+=src
//handle_missing_mask()
..()
@@ -28,10 +25,7 @@ var/obj/cult_viewpoint/list/cult_viewpoints = list()
/obj/cult_viewpoint/Del()
processing_objects.Remove(src)
cultNetwork.viewpoints-=src
cultNetwork.removeViewpoint(src)
cult_viewpoints-=src
owner.removeFromVisibilityNetwork(cultNetwork)
..()
return
@@ -134,6 +128,8 @@ var/obj/cult_viewpoint/list/cult_viewpoints = list()
/obj/cult_viewpoint/proc/get_display_name()
if(istype(src,/obj/effect/rune))
return name
if (!owner)
return
if (cult_name)
+10 -10
View File
@@ -10,7 +10,7 @@
for(var/obj/item/W in src)
if (W==w_uniform) // will be torn
continue
drop_from_inventory(W)
unEquip(W)
regenerate_icons()
monkeyizing = 1
canmove = 0
@@ -73,7 +73,7 @@
if (monkeyizing)
return
for(var/obj/item/W in src)
drop_from_inventory(W)
unEquip(W)
monkeyizing = 1
canmove = 0
icon = null
@@ -150,7 +150,7 @@
if(!should_remove_items)
for(var/obj/item/W in src)
drop_from_inventory(W)
unEquip(W)
var/mob/spirit/mask/new_spirit = new()
@@ -193,7 +193,7 @@
if (monkeyizing)
return
for(var/obj/item/W in src)
drop_from_inventory(W)
unEquip(W)
regenerate_icons()
monkeyizing = 1
canmove = 0
@@ -249,7 +249,7 @@
if (monkeyizing)
return
for(var/obj/item/W in src)
drop_from_inventory(W)
unEquip(W)
regenerate_icons()
monkeyizing = 1
canmove = 0
@@ -280,7 +280,7 @@
if (monkeyizing)
return
for(var/obj/item/W in src)
drop_from_inventory(W)
unEquip(W)
regenerate_icons()
monkeyizing = 1
canmove = 0
@@ -315,7 +315,7 @@
if (monkeyizing)
return
for(var/obj/item/W in src)
drop_from_inventory(W)
unEquip(W)
regenerate_icons()
monkeyizing = 1
canmove = 0
@@ -345,7 +345,7 @@
if(monkeyizing)
return
for(var/obj/item/W in src)
drop_from_inventory(W)
unEquip(W)
regenerate_icons()
monkeyizing = 1
@@ -434,7 +434,7 @@
if(ispath(MP, /mob/living/simple_animal/pony))
return 1 // ZOMG PONIES WHEEE
if(ispath(MP, /mob/living/simple_animal/fox))
return 1
return 1
//Not in here? Must be untested!
return 0
@@ -459,7 +459,7 @@
if(ispath(MP, /mob/living/simple_animal/pony))
return 1
if(ispath(MP, /mob/living/simple_animal/fox))
return 1
return 1
//Antag Creatures!
/* if(ispath(MP, /mob/living/simple_animal/hostile/carp) && !jobban_isbanned(src, "Syndicate"))