diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm
new file mode 100644
index 00000000000..ea94aa6407b
--- /dev/null
+++ b/code/datums/mutable_appearance.dm
@@ -0,0 +1,13 @@
+// Mutable appearances are an inbuilt byond datastructure. Read the documentation on them by hitting F1 in DM.
+// Basically use them instead of images for overlays/underlays and when changing an object's appearance if you're doing so with any regularity.
+// Unless you need the overlay/underlay to have a different direction than the base object. Then you have to use an image due to a bug.
+
+// Mutable appearances are children of images, just so you know.
+
+// Helper similar to image()
+/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER)
+ var/mutable_appearance/MA = new()
+ MA.icon = icon
+ MA.icon_state = icon_state
+ MA.layer = layer
+ return MA
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm
index 13b0f0b8140..fb10c7cedc2 100644
--- a/code/game/objects/items/weapons/grenades/ghettobomb.dm
+++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm
@@ -1,70 +1,6 @@
//improvised explosives//
-//iedcasing assembly crafting//
-/obj/item/weapon/reagent_containers/food/drinks/cans/attackby(var/obj/item/I, mob/user as mob)
- if(istype(I, /obj/item/device/assembly/igniter))
- var/obj/item/device/assembly/igniter/G = I
- var/obj/item/weapon/grenade/iedcasing/W = new /obj/item/weapon/grenade/iedcasing
- user.unEquip(G)
- user.unEquip(src)
- user.put_in_hands(W)
- to_chat(user, "You stuff the [I] in the [src], emptying the contents beforehand.")
- W.underlays += image(src.icon, icon_state = src.icon_state)
- qdel(I)
- qdel(src)
-
-
/obj/item/weapon/grenade/iedcasing
- name = "improvised explosive assembly"
- desc = "An igniter stuffed into an aluminum shell."
- w_class = WEIGHT_CLASS_SMALL
- icon = 'icons/obj/grenade.dmi'
- icon_state = "improvised_grenade"
- item_state = "flashbang"
- throw_speed = 3
- throw_range = 7
- flags = CONDUCT
- slot_flags = SLOT_BELT
- var/assembled = 0
- active = 1
- det_time = 50
- display_timer = 0
- var/range = 3
- var/times = list()
-
-
-
-/obj/item/weapon/grenade/iedcasing/afterattack(atom/target, mob/user , flag) //Filling up the can
- if(assembled == 0)
- if( istype(target, /obj/structure/reagent_dispensers/fueltank))
- if(target.reagents.total_volume < 50)
- to_chat(user, "There's not enough fuel left to work with.")
- return
- var/obj/structure/reagent_dispensers/fueltank/F = target
- F.reagents.remove_reagent("fuel", 50, 1)//Deleting 50 fuel from the welding fuel tank,
- assembled = 1
- to_chat(user, "You've filled the makeshift explosive with welding fuel.")
- playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
- desc = "An improvised explosive assembly. Filled to the brim with 'Explosive flavor'"
- overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
- return
-
-
-/obj/item/weapon/grenade/iedcasing/attackby(var/obj/item/I, mob/user as mob) //Wiring the can for ignition
- if(istype(I, /obj/item/stack/cable_coil))
- if(assembled == 1)
- var/obj/item/stack/cable_coil/C = I
- C.use(1)
- assembled = 2
- to_chat(user, "You wire the igniter to detonate the fuel.")
- desc = "A weak, improvised explosive."
- overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_wired")
- name = "improvised explosive"
- active = 0
- det_time = rand(30,80)
-
-
-/obj/item/weapon/grenade/iedcasing/filled
name = "improvised firebomb"
desc = "A weak, improvised incendiary device."
w_class = WEIGHT_CLASS_SMALL
@@ -77,53 +13,53 @@
slot_flags = SLOT_BELT
active = 0
det_time = 50
- assembled = 2
+ display_timer = 0
+ var/list/times
-
-
-/obj/item/weapon/grenade/iedcasing/filled/New(loc)
+/obj/item/weapon/grenade/iedcasing/New()
..()
- overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
- overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_wired")
- times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value]
+ overlays += "improvised_grenade_filled"
+ overlays += "improvised_grenade_wired"
+ times = list("5" = 10, "-1" = 20, "[rand(30, 80)]" = 50, "[rand(65, 180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value]
det_time = text2num(pickweight(times))
if(det_time < 0) //checking for 'duds'
- range = 1
det_time = rand(30,80)
- else
- range = pick(2,2,2,3,3,3,4)
/obj/item/weapon/grenade/iedcasing/CheckParts(list/parts_list)
..()
var/obj/item/weapon/reagent_containers/food/drinks/cans/can = locate() in contents
if(can)
- underlays += can
+ can.pixel_x = 0 //Reset the sprite's position to make it consistent with the rest of the IED
+ can.pixel_y = 0
+ var/mutable_appearance/can_underlay = new(can)
+ can_underlay.layer = FLOAT_LAYER
+ can_underlay.plane = FLOAT_PLANE
+ underlays += can_underlay
-/obj/item/weapon/grenade/iedcasing/attack_self(mob/user as mob) //
+/obj/item/weapon/grenade/iedcasing/attack_self(mob/user) //
if(!active)
if(clown_check(user))
to_chat(user, "You light the [name]!")
- active = 1
- overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
+ active = TRUE
+ overlays -= "improvised_grenade_filled"
icon_state = initial(icon_state) + "_active"
add_fingerprint(user)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
- message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP)")
- log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])")
+ message_admins("[ADMIN_LOOKUPFLW(user)] has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)].")
+ log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
- spawn(det_time)
- prime()
+ addtimer(src, "prime", det_time)
/obj/item/weapon/grenade/iedcasing/prime() //Blowing that can up
update_mob()
- explosion(src.loc,-1,-1,-1, flame_range = range) // no explosive damage, only a large fireball.
+ explosion(loc, -1, -1, 2, flame_range = 4) // small explosion, plus a very large fireball.
qdel(src)
/obj/item/weapon/grenade/iedcasing/examine(mob/user)
- ..(user)
+ ..()
to_chat(user, "You can't tell when it will explode!")
diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm
index 1dce8088158..21d8828310f 100644
--- a/code/game/objects/items/weapons/legcuffs.dm
+++ b/code/game/objects/items/weapons/legcuffs.dm
@@ -52,23 +52,12 @@
if(sig)
to_chat(user, "This beartrap already has a signaler hooked up to it!")
return
- IED = I
- switch(IED.assembled)
- if(0,1) //if it's not fueled/hooked up
- to_chat(user, "You haven't prepared this IED yet!")
- IED = null
- return
- if(2,3)
- user.drop_item()
- I.forceMove(src)
- message_admins("[key_name_admin(user)] has rigged a beartrap with an IED.")
- log_game("[key_name(user)] has rigged a beartrap with an IED.")
- to_chat(user, "You sneak the [IED] underneath the pressure plate and connect the trigger wire.")
- desc = "A trap used to catch bears and other legged creatures. There is an IED hooked up to it."
- else
- to_chat(user, "You shouldn't be reading this message! Contact a coder or someone, something broke!")
- IED = null
- return
+ user.drop_item()
+ I.forceMove(src)
+ message_admins("[key_name_admin(user)] has rigged a beartrap with an IED.")
+ log_game("[key_name(user)] has rigged a beartrap with an IED.")
+ to_chat(user, "You sneak [IED] underneath the pressure plate and connect the trigger wire.")
+ desc = "A trap used to catch bears and other legged creatures. There is an IED hooked up to it."
if(istype(I, /obj/item/device/assembly/signaler))
if(IED)
to_chat(user, "This beartrap already has an IED hooked up to it!")
@@ -110,9 +99,6 @@
if(IED && isturf(src.loc))
IED.active = 1
- IED.overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
- IED.icon_state = initial(icon_state) + "_active"
- IED.assembled = 3
message_admins("[key_name_admin(usr)] has triggered an IED-rigged [name].")
log_game("[key_name(usr)] has triggered an IED-rigged [name].")
spawn(IED.det_time)
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index 3fbcf39ed08..4e7093bf5cf 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -16,7 +16,7 @@
/datum/crafting_recipe/IED
name = "IED"
- result = /obj/item/weapon/grenade/iedcasing/filled
+ result = /obj/item/weapon/grenade/iedcasing
reqs = list(/datum/reagent/fuel = 50,
/obj/item/stack/cable_coil = 1,
/obj/item/device/assembly/igniter = 1,
diff --git a/paradise.dme b/paradise.dme
index a0438a3be1b..ec8aa0280d7 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -215,6 +215,7 @@
#include "code\datums\mind.dm"
#include "code\datums\mixed.dm"
#include "code\datums\modules.dm"
+#include "code\datums\mutable_appearance.dm"
#include "code\datums\periodic_news.dm"
#include "code\datums\progressbar.dm"
#include "code\datums\recipe.dm"