Merge remote-tracking branch 'upstream/master' into fix-cqc

# Conflicts:
#	code/game/objects/items.dm
This commit is contained in:
Fox McCloud
2019-04-07 19:54:14 -04:00
1409 changed files with 1712308 additions and 63928 deletions
+9 -5
View File
@@ -70,6 +70,10 @@
changeNext_click(1)
var/list/modifiers = params2list(params)
var/dragged = modifiers["drag"]
if(dragged && !modifiers[dragged])
return
if(modifiers["middle"] && modifiers["shift"] && modifiers["ctrl"])
MiddleShiftControlClickOn(A)
return
@@ -285,12 +289,12 @@
/mob/proc/CtrlClickOn(var/atom/A)
A.CtrlClick(src)
return
/atom/proc/CtrlClick(var/mob/user)
return
/atom/movable/CtrlClick(var/mob/user)
if(Adjacent(user))
user.start_pulling(src)
/atom/proc/CtrlClick(mob/user)
SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user)
var/mob/living/ML = user
if(istype(ML))
ML.pulled(src)
/*
Alt click
+40 -16
View File
@@ -43,26 +43,50 @@
..()
/datum/middleClickOverride/power_gloves
var/last_shocked = 0
var/shock_delay = 120
/datum/middleClickOverride/power_gloves/onClick(var/atom/A, var/mob/living/user)
/datum/middleClickOverride/power_gloves/onClick(atom/A, mob/living/carbon/human/user)
if(A == user || user.a_intent == INTENT_HELP || user.a_intent == INTENT_GRAB)
return
if(user.incapacitated())
return
if(world.time < last_shocked + shock_delay)
var/obj/item/clothing/gloves/color/yellow/power/P = user.gloves
if(world.time < P.last_shocked + P.shock_delay)
to_chat(user, "<span class='warning'>The gloves are still recharging.</span>")
return
if(!isliving(A))
to_chat(user, "<span class='warning'>Shocking an inanimate object would be pointless.</span>")
return
var/mob/living/L = A
var/turf/T = get_turf(user)
var/obj/structure/cable/C = locate() in T
if(!C || !istype(C))
to_chat(user, "<span class='warning'>There is no cable here to power the gloves.</span>")
return
user.visible_message("<span class='warning'>[user.name] fires an arc of electricity at [L]!</span>", "<span class='warning'>You fire an arc of electricity at [L]!</span>", "You hear the loud crackle of electricity!")
playsound(user.loc, 'sound/effects/eleczap.ogg', 75, 1)
user.Beam(L,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5)
electrocute_mob(L, C, user)
last_shocked = world.time
if(!P.unlimited_power)
if(!C || !istype(C))
to_chat(user, "<span class='warning'>There is no cable here to power the gloves.</span>")
return
var/turf/target_turf = get_turf(A)
target_turf.hotspot_expose(2000, 400)
playsound(user.loc, 'sound/effects/eleczap.ogg', 40, 1)
var/atom/beam_from = user
var/atom/target_atom = A
for(var/i in 0 to 3)
beam_from.Beam(target_atom, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 6)
if(isliving(target_atom))
var/mob/living/L = target_atom
if(user.a_intent == INTENT_DISARM)
L.Weaken(3)
else
if(P.unlimited_power)
L.electrocute_act(1000, P, 0) //Just kill them
else
electrocute_mob(L, C, P)
break
var/list/next_shocked = list()
for(var/atom/movable/AM in orange(3, target_atom))
if(AM == user || istype(AM, /obj/effect) || isobserver(AM))
continue
next_shocked.Add(AM)
beam_from = target_atom
target_atom = pick(next_shocked)
A = target_atom
next_shocked.Cut()
P.last_shocked = world.time
+1
View File
@@ -22,6 +22,7 @@
//Middle left indicators
#define ui_lingchemdisplay "WEST:6,CENTER-1:15"
#define ui_lingstingdisplay "WEST:6,CENTER-3:11"
#define ui_devilsouldisplay "WEST:6,CENTER-1:15"
//Lower center, persistant menu
#define ui_sstore1 "CENTER-5:10,SOUTH:5"
+21 -1
View File
@@ -322,7 +322,7 @@ Recharging stations are available in robotics, the dormitory bathrooms, and the
/obj/screen/alert/nymph/Click()
if(!usr || !usr.client)
return
return
if(isnymph(usr))
var/mob/living/simple_animal/diona/D = usr
return D.resist()
@@ -412,6 +412,26 @@ so as to remain in compliance with the most up-to-date laws."
else
to_chat(usr, "<span class='notice'>[M] is not connected to a port at the moment.</span>")
/obj/screen/alert/mech_nocell
name = "Missing Power Cell"
desc = "Mech has no power cell."
icon_state = "nocell"
/obj/screen/alert/mech_emptycell
name = "Out of Power"
desc = "Mech is out of power."
icon_state = "emptycell"
/obj/screen/alert/mech_lowcell
name = "Low Charge"
desc = "Mech is running out of power."
icon_state = "lowcell"
/obj/screen/alert/mech_maintenance
name = "Maintenance Protocols"
desc = "Maintenance protocols are currently in effect, most actions disabled."
icon_state = "locked"
//GUARDIANS
/obj/screen/alert/cancharge
name = "Charge Ready"
+1 -1
View File
@@ -136,7 +136,7 @@
inv_slots[inv.slot_id] = inv
inv.update_icon()
/datum/hud/alien/persistant_inventory_update()
/datum/hud/alien/persistent_inventory_update()
if(!mymob)
return
var/mob/living/carbon/alien/humanoid/H = mymob
+196
View File
@@ -0,0 +1,196 @@
/mob/camera/blob/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/blob_overmind(src)
/obj/screen/blob
icon = 'icons/mob/blob.dmi'
/obj/screen/blob/MouseEntered(location,control,params)
openToolTip(usr,src,params,title = name,content = desc, theme = "blob")
/obj/screen/blob/MouseExited()
closeToolTip(usr)
/obj/screen/blob/BlobHelp
icon_state = "ui_help"
name = "Blob Help"
desc = "Help on playing blob!"
/obj/screen/blob/BlobHelp/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.blob_help()
/obj/screen/blob/JumpToNode
icon_state = "ui_tonode"
name = "Jump to Node"
desc = "Moves your camera to a selected blob node."
/obj/screen/blob/JumpToNode/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.jump_to_node()
/obj/screen/blob/JumpToCore
icon_state = "ui_tocore"
name = "Jump to Core"
desc = "Moves your camera to your blob core."
/obj/screen/blob/JumpToCore/MouseEntered(location,control,params)
if(hud && hud.mymob && isovermind(hud.mymob))
name = initial(name)
desc = initial(desc)
..()
/obj/screen/blob/JumpToCore/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.transport_core()
/obj/screen/blob/Blobbernaut
icon_state = "ui_blobbernaut"
name = "Produce Blobbernaut (20)"
desc = "Produces a strong, but dumb blobbernaut from a factory blob for 20 resources.<br>The factory blob will be destroyed in the process."
/obj/screen/blob/Blobbernaut/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.create_blobbernaut()
/obj/screen/blob/StorageBlob
icon_state = "ui_storage"
name = "Produce Storage Blob (40)"
desc = "Produces a storage blob for 40 resources.<br>Storage blobs will raise your max resource cap by 50."
/obj/screen/blob/StorageBlob/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.create_storage()
/obj/screen/blob/ResourceBlob
icon_state = "ui_resource"
name = "Produce Resource Blob (40)"
desc = "Produces a resource blob for 40 resources.<br>Resource blobs will give you resources every few seconds."
/obj/screen/blob/ResourceBlob/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.create_resource()
/obj/screen/blob/NodeBlob
icon_state = "ui_node"
name = "Produce Node Blob (60)"
desc = "Produces a node blob for 60 resources.<br>Node blobs will expand and activate nearby resource and factory blobs."
/obj/screen/blob/NodeBlob/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.create_node()
/obj/screen/blob/FactoryBlob
icon_state = "ui_factory"
name = "Produce Factory Blob (60)"
desc = "Produces a factory blob for 60 resources.<br>Factory blobs will produce spores every few seconds."
/obj/screen/blob/FactoryBlob/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.create_factory()
/obj/screen/blob/ReadaptChemical
icon_state = "ui_chemswap"
name = "Readapt Chemical (50)"
desc = "Randomly rerolls your chemical for 50 resources."
/obj/screen/blob/ReadaptChemical/MouseEntered(location,control,params)
if(hud && hud.mymob && isovermind(hud.mymob))
name = initial(name)
desc = initial(desc)
..()
/obj/screen/blob/ReadaptChemical/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.chemical_reroll()
/obj/screen/blob/RelocateCore
icon_state = "ui_swap"
name = "Relocate Core (80)"
desc = "Swaps a node and your core for 80 resources."
/obj/screen/blob/RelocateCore/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.relocate_core()
/obj/screen/blob/Split
icon_state = "ui_split"
name = "Split consciousness (100)"
desc = "Creates another Blob Overmind at the nearest node. One use only.<br>Offsprings are be unable to use this ability."
/obj/screen/blob/Split/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.split_consciousness()
/datum/hud/blob_overmind/New(mob/user)
..()
var/obj/screen/using
blobpwrdisplay = new /obj/screen()
blobpwrdisplay.name = "blob power"
blobpwrdisplay.icon_state = "block"
blobpwrdisplay.screen_loc = ui_health
static_inventory += blobpwrdisplay
blobhealthdisplay = new /obj/screen()
blobhealthdisplay.name = "blob health"
blobhealthdisplay.icon_state = "block"
blobhealthdisplay.screen_loc = ui_internal
static_inventory += blobhealthdisplay
using = new /obj/screen/blob/BlobHelp()
using.screen_loc = "WEST:6,NORTH:-3"
static_inventory += using
using = new /obj/screen/blob/JumpToNode()
using.screen_loc = ui_inventory
static_inventory += using
using = new /obj/screen/blob/JumpToCore()
using.screen_loc = ui_zonesel
using.hud = src
static_inventory += using
using = new /obj/screen/blob/Blobbernaut()
using.screen_loc = ui_id
static_inventory += using
using = new /obj/screen/blob/StorageBlob()
using.screen_loc = ui_belt
static_inventory += using
using = new /obj/screen/blob/ResourceBlob()
using.screen_loc = ui_back
static_inventory += using
using = new /obj/screen/blob/NodeBlob()
using.screen_loc = using.screen_loc = ui_rhand
static_inventory += using
using = new /obj/screen/blob/FactoryBlob()
using.screen_loc = using.screen_loc = ui_lhand
static_inventory += using
using = new /obj/screen/blob/ReadaptChemical()
using.screen_loc = ui_storage1
using.hud = src
static_inventory += using
using = new /obj/screen/blob/RelocateCore()
using.screen_loc = ui_storage2
static_inventory += using
using = new /obj/screen/blob/Split()
using.screen_loc = ui_acti
static_inventory += using
+89
View File
@@ -0,0 +1,89 @@
//Soul counter is stored with the humans, it does weird when you place it here apparently...
/datum/hud/devil/New(mob/owner, ui_style = 'icons/mob/screen_midnight.dmi')
..()
var/obj/screen/using
var/obj/screen/inventory/inv_box
using = new /obj/screen/drop()
using.icon = ui_style
using.screen_loc = ui_drop_throw
static_inventory += using
mymob.pullin = new /obj/screen/pull()
mymob.pullin.icon = ui_style
mymob.pullin.update_icon(mymob)
mymob.pullin.screen_loc = ui_pull_resist
static_inventory += mymob.pullin
inv_box = new /obj/screen/inventory/hand()
inv_box.name = "right hand"
inv_box.icon = ui_style
inv_box.icon_state = "hand_r"
inv_box.screen_loc = ui_rhand
inv_box.slot_id = slot_r_hand
static_inventory += inv_box
inv_box = new /obj/screen/inventory/hand()
inv_box.name = "left hand"
inv_box.icon = ui_style
inv_box.icon_state = "hand_l"
inv_box.screen_loc = ui_lhand
inv_box.slot_id = slot_l_hand
static_inventory += inv_box
using = new /obj/screen/swap_hand()
using.name = "hand"
using.icon = ui_style
using.icon_state = "swap_1"
using.screen_loc = ui_swaphand1
using.layer = 19
static_inventory += using
using = new /obj/screen/swap_hand()
using.name = "hand"
using.icon = ui_style
using.icon_state = "swap_2"
using.screen_loc = ui_swaphand2
using.layer = 19
static_inventory += using
mymob.zone_sel = new /obj/screen/zone_sel()
mymob.zone_sel.icon = ui_style
mymob.zone_sel.update_icon(mymob)
lingchemdisplay = new /obj/screen/ling/chems()
devilsouldisplay = new /obj/screen/devil/soul_counter
infodisplay += devilsouldisplay
for(var/obj/screen/inventory/inv in static_inventory)
if(inv.slot_id)
inv.hud = src
inv_slots[inv.slot_id] = inv
inv.update_icon()
/datum/hud/devil/persistent_inventory_update()
if(!mymob)
return
var/mob/living/carbon/true_devil/D = mymob
if(hud_version != HUD_STYLE_NOHUD)
if(D.r_hand)
D.r_hand.screen_loc = ui_rhand
D.client.screen += D.r_hand
if(D.l_hand)
D.l_hand.screen_loc = ui_lhand
D.client.screen += D.l_hand
else
if(D.r_hand)
D.r_hand.screen_loc = null
if(D.l_hand)
D.l_hand.screen_loc = null
/mob/living/carbon/true_devil/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/devil(src, ui_style2icon(client.prefs.UI_style))
+5
View File
@@ -9,6 +9,11 @@
guardianhealthdisplay = new /obj/screen/healths/guardian()
infodisplay += guardianhealthdisplay
using = new /obj/screen/act_intent/guardian()
using.icon_state = mymob.a_intent
static_inventory += using
action_intent = using
using = new /obj/screen/guardian/Manifest()
using.screen_loc = ui_rhand
static_inventory += using
+5 -2
View File
@@ -27,6 +27,8 @@
var/obj/screen/move_intent
var/obj/screen/module_store_icon
var/obj/screen/devil/soul_counter/devilsouldisplay
var/list/static_inventory = list() //the screen objects which are static
var/list/toggleable_inventory = list() //the screen objects which can be hidden
var/list/hotkeybuttons = list() //the buttons that can be used via hotkeys
@@ -79,6 +81,7 @@
alien_plasma_display = null
vampire_blood_display = null
nightvisionicon = null
devilsouldisplay = null
mymob = null
return ..()
@@ -155,7 +158,7 @@
mymob.client.screen -= infodisplay
hud_version = display_hud_version
persistant_inventory_update()
persistent_inventory_update()
mymob.update_action_buttons(1)
reorganize_alerts()
reload_fullscreen()
@@ -171,7 +174,7 @@
/datum/hud/proc/hidden_inventory_update()
return
/datum/hud/proc/persistant_inventory_update()
/datum/hud/proc/persistent_inventory_update()
return
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
+33 -1
View File
@@ -36,6 +36,35 @@
var/mob/living/carbon/U = usr
U.unset_sting()
/obj/screen/devil
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/devil/soul_counter
icon = 'icons/mob/screen_gen.dmi'
name = "souls owned"
icon_state = "Devil-6"
screen_loc = ui_devilsouldisplay
/obj/screen/devil/soul_counter/proc/update_counter(souls = 0)
invisibility = 0
maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#FF0000'>[souls]</font></div>"
switch(souls)
if(0,null)
icon_state = "Devil-1"
if(1,2)
icon_state = "Devil-2"
if(3 to 5)
icon_state = "Devil-3"
if(6 to 8)
icon_state = "Devil-4"
if(9 to INFINITY)
icon_state = "Devil-5"
else
icon_state = "Devil-6"
/obj/screen/devil/soul_counter/proc/clear()
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/ling/chems
name = "chemical storage"
icon_state = "power_display"
@@ -337,6 +366,9 @@
lingstingdisplay = new /obj/screen/ling/sting()
infodisplay += lingstingdisplay
devilsouldisplay = new /obj/screen/devil/soul_counter
infodisplay += devilsouldisplay
mymob.zone_sel = new /obj/screen/zone_sel()
mymob.zone_sel.icon = ui_style
mymob.zone_sel.update_icon(mymob)
@@ -393,7 +425,7 @@
if(H.wear_mask) H.wear_mask.screen_loc = null
if(H.head) H.head.screen_loc = null
/datum/hud/human/persistant_inventory_update()
/datum/hud/human/persistent_inventory_update()
if(!mymob)
return
var/mob/living/carbon/human/H = mymob
+1 -21
View File
@@ -24,24 +24,4 @@
mymob.pullin.icon = 'icons/mob/screen_corgi.dmi'
mymob.pullin.update_icon(mymob)
mymob.pullin.screen_loc = ui_construct_pull
static_inventory += mymob.pullin
/mob/camera/blob/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/blob_overmind(src)
/datum/hud/blob_overmind/New(mob/user)
..()
blobpwrdisplay = new /obj/screen()
blobpwrdisplay.name = "blob power"
blobpwrdisplay.icon_state = "block"
blobpwrdisplay.screen_loc = ui_health
static_inventory += blobpwrdisplay
blobhealthdisplay = new /obj/screen()
blobhealthdisplay.name = "blob health"
blobhealthdisplay.icon_state = "block"
blobhealthdisplay.screen_loc = ui_internal
static_inventory += blobhealthdisplay
static_inventory += mymob.pullin
+13 -10
View File
@@ -66,7 +66,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
var/max_elements
var/pages = 1
var/current_page = 1
var/hudfix_method = TRUE //TRUE to change anchor to user, FALSE to shift by py_shift
var/py_shift = 0
var/entry_animation = TRUE
@@ -74,9 +74,12 @@ GLOBAL_LIST_EMPTY(radial_menus)
//If we swap to vis_contens inventory these will need a redo
/datum/radial_menu/proc/check_screen_border(mob/user)
var/atom/movable/AM = anchor
if(!istype(AM) || !AM.screen_loc)
if(!istype(AM))
return
if(AM in user.client.screen)
var/mob/living/carbon/H
if(ishuman(user))
H = user
if((AM in user.client.screen) || (H && (AM in H.internal_organs)))
if(hudfix_method)
anchor = user
else
@@ -84,7 +87,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
restrict_to_dir(NORTH) //I was going to parse screen loc here but that's more effort than it's worth.
//Sets defaults
//These assume 45 deg min_angle
//These assume 45 deg min_angle
/datum/radial_menu/proc/restrict_to_dir(dir)
switch(dir)
if(NORTH)
@@ -105,7 +108,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
zone = ending_angle - starting_angle
else
zone = 360 - starting_angle + ending_angle
max_elements = round(zone / min_angle)
var/paged = max_elements < choices.len
if(elements.len < max_elements)
@@ -172,7 +175,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
else
E.pixel_y = py
E.pixel_x = px
//Visuals
E.alpha = 255
E.mouse_opacity = MOUSE_OPACITY_ICON
@@ -192,7 +195,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
E.next_page = FALSE
if(choices_icons[choice_id])
E.add_overlay(choices_icons[choice_id])
/datum/radial_menu/New()
close_button = new
close_button.parent = src
@@ -230,7 +233,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
MA.layer = ABOVE_HUD_LAYER
MA.appearance_flags |= RESET_TRANSFORM
return MA
/datum/radial_menu/proc/next_page()
if(pages > 1)
@@ -268,7 +271,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
. = ..()
/*
Presents radial menu to user anchored to anchor (or user if the anchor is currently in users screen)
Presents radial menu to user anchored to anchor (or user if the anchor is currently in users screen)
Choices should be a list where list keys are movables or text used for element names and return value
and list values are movables/icons/images used for element icons
*/
@@ -297,4 +300,4 @@ GLOBAL_LIST_EMPTY(radial_menus)
GLOB.radial_menus -= uniqueid
return answer
#undef ANIM_SPEED
#undef ANIM_SPEED
+4 -1
View File
@@ -97,11 +97,14 @@
name = "run/walk toggle"
icon_state = "running"
/obj/screen/act_intent/simple_animal
icon = 'icons/mob/screen_simplemob.dmi'
screen_loc = ui_acti
/obj/screen/act_intent/guardian
icon = 'icons/mob/guardian.dmi'
screen_loc = ui_acti
/obj/screen/mov_intent/Click()
if(iscarbon(usr))
var/mob/living/carbon/C = usr
+10 -5
View File
@@ -12,6 +12,9 @@
return
/obj/item/proc/pre_attackby(atom/A, mob/living/user, params) //do stuff before attackby!
if(is_hot(src) && A.reagents && !ismob(A))
to_chat(user, "<span class='notice'>You heat [A] with [src].</span>")
A.reagents.temperature_reagents(is_hot(src))
return TRUE //return FALSE to avoid calling attackby after this proc does stuff
// No comment
@@ -48,12 +51,12 @@
else
return 1
if(isscrewdriver(src) && ismachine(M))
if(isscrewdriver(src) && ismachine(M) && user.a_intent == INTENT_HELP)
if(!attempt_initiate_surgery(src, M, user))
return 0
else
return 1
if(is_sharp(src))
if(is_sharp(src) && user.a_intent == INTENT_HELP)
if(!attempt_initiate_surgery(src, M, user))
return 0
else
@@ -61,14 +64,16 @@
if(!force)
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1)
else if(hitsound)
playsound(loc, hitsound, get_clamped_volume(), 1, -1)
else
SEND_SIGNAL(M, COMSIG_ITEM_ATTACK)
if(hitsound)
playsound(loc, hitsound, get_clamped_volume(), 1, -1)
user.lastattacked = M
M.lastattacker = user
user.do_attack_animation(M)
M.attacked_by(src, user, def_zone)
. = M.attacked_by(src, user, def_zone)
add_attack_logs(user, M, "Attacked with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])", (M.ckey && force > 0 && damtype != STAMINA) ? null : ATKLOG_ALMOSTALL)
+22 -4
View File
@@ -1,17 +1,35 @@
// Blob Overmind Controls
/mob/camera/blob/CtrlClickOn(var/atom/A) // Expand blob
/mob/camera/blob/ClickOn(var/atom/A, var/params) //Expand blob
var/list/modifiers = params2list(params)
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"])
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
var/turf/T = get_turf(A)
if(T)
expand_blob(T)
/mob/camera/blob/MiddleClickOn(var/atom/A) // Rally spores
/mob/camera/blob/MiddleClickOn(atom/A) //Rally spores
var/turf/T = get_turf(A)
if(T)
rally_spores(T)
/mob/camera/blob/AltClickOn(var/atom/A) // Create a shield
/mob/camera/blob/CtrlClickOn(atom/A) //Create a shield
var/turf/T = get_turf(A)
if(T)
create_shield(T)
create_shield(T)
/mob/camera/blob/AltClickOn(atom/A) //Remove a blob
var/turf/T = get_turf(A)
if(T)
remove_blob(T)