"
if(uplinkholder)
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, uplinkholder)
+ var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
dat += "[hidden_uplink.telecrystals] telecrystals remain in this uplink. "
if(linkedboss)
dat += "Donate TC: 1 | 5 | All"
@@ -170,7 +170,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
dat += "[A.name] | "
if(A.uplinkholder)
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, A.uplinkholder)
+ var/datum/component/uplink/hidden_uplink = A.uplinkholder.GetComponent(/datum/component/uplink)
dat += "[hidden_uplink.telecrystals] telecrystals."
if(storedcrystals)
dat+= " Add TC: 1 | 5 | 10 | All"
diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm
index e50eeb8619..f4f20aecc9 100644
--- a/code/game/machinery/computer/teleporter.dm
+++ b/code/game/machinery/computer/teleporter.dm
@@ -10,6 +10,7 @@
var/obj/machinery/teleport/station/power_station
var/calibrating
var/turf/target
+ var/obj/item/implant/imp_t
/obj/machinery/computer/teleporter/Initialize()
. = ..()
@@ -109,6 +110,9 @@
/obj/machinery/computer/teleporter/proc/reset_regime()
target = null
+ if(imp_t)
+ UnregisterSignal(imp_t, COMSIG_IMPLANT_REMOVING)
+ imp_t = null
if(regime_set == "Teleporter")
regime_set = "Gate"
else
@@ -132,10 +136,24 @@
if(M.timeofdeath + 6000 < world.time)
continue
if(is_eligible(M))
- L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = I
+ L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = M
var/desc = input("Please select a location to lock in.", "Locking Computer") as null|anything in L
+ if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //check if we are still around
+ return
target = L[desc]
+ if(imp_t)
+ UnregisterSignal(imp_t, COMSIG_IMPLANT_REMOVING)
+ imp_t = null
+ if(isliving(target)) //make sure the living mob is still implanted to be a valid target
+ var/mob/living/M = target
+ var/obj/item/implant/tracking/I = locate() in M.implants
+ if(I)
+ RegisterSignal(I, COMSIG_IMPLANT_REMOVING, .proc/untarget_implant)
+ imp_t = I
+ else
+ target = null
+ return
var/turf/T = get_turf(target)
log_game("[key_name(user)] has set the teleporter target to [target] at [AREACOORD(T)]")
@@ -149,6 +167,8 @@
to_chat(user, "No active connected stations located.")
return
var/desc = input("Please select a station to lock in.", "Locking Computer") as null|anything in L
+ if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //again, check if we are still around
+ return
var/obj/machinery/teleport/station/target_station = L[desc]
if(!target_station || !target_station.teleporter_hub)
return
@@ -164,6 +184,14 @@
target_station.teleporter_console.stat &= ~NOPOWER
target_station.teleporter_console.update_icon()
+/obj/machinery/computer/teleporter/proc/untarget_implant() //untargets from mob the racker was once implanted in to prevent issues.
+ target = null
+ if(power_station)
+ power_station.engaged = FALSE
+ power_station.teleporter_hub?.update_icon()
+ UnregisterSignal(imp_t, COMSIG_IMPLANT_REMOVING)
+ imp_t = null
+
/obj/machinery/computer/teleporter/proc/is_eligible(atom/movable/AM)
var/turf/T = get_turf(AM)
if(!T)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index a2da7de29a..3ac386e1fb 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -326,7 +326,7 @@
else //for simple_animals & borgs
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
var/turf/location = get_turf(src)
- //add_blood doesn't work for borgs/xenos, but add_blood_floor does.
+ //add_blood_DNA doesn't work for borgs/xenos, but add_blood_floor does.
if(iscarbon(L))
var/mob/living/carbon/C = L
C.bleed(DOOR_CRUSH_DAMAGE)
diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm
index 7c92c158b3..b121057315 100644
--- a/code/game/machinery/droneDispenser.dm
+++ b/code/game/machinery/droneDispenser.dm
@@ -146,7 +146,7 @@
if((stat & (NOPOWER|BROKEN)) || !anchored)
return
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(!materials.has_materials(using_materials))
return // We require more minerals
@@ -211,7 +211,7 @@
/obj/machinery/droneDispenser/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/crowbar))
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
I.play_tool_sound(src)
to_chat(user, "You retrieve the materials from [src].")
diff --git a/code/game/machinery/exp_cloner.dm b/code/game/machinery/exp_cloner.dm
index b594991a7d..25e5948b51 100644
--- a/code/game/machinery/exp_cloner.dm
+++ b/code/game/machinery/exp_cloner.dm
@@ -42,11 +42,12 @@
icon_state = "pod_1"
//Get the clone body ready
maim_clone(H)
- ADD_TRAIT(H, TRAIT_STABLEHEART, "cloning")
- ADD_TRAIT(H, TRAIT_EMOTEMUTE, "cloning")
- ADD_TRAIT(H, TRAIT_MUTE, "cloning")
- ADD_TRAIT(H, TRAIT_NOBREATH, "cloning")
- ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, "cloning")
+ ADD_TRAIT(H, TRAIT_STABLEHEART, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_STABLELIVER, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_MUTE, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_NOBREATH, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT)
H.Unconscious(80)
var/list/candidates = pollCandidatesForMob("Do you want and agree to play as a [clonename]'s defective clone, respect their character and not engage in ERP without permission from the original?", null, null, null, 100, H, POLL_IGNORE_CLONE)
diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm
index 6b944f762d..a2d0460d25 100644
--- a/code/game/machinery/gulag_teleporter.dm
+++ b/code/game/machinery/gulag_teleporter.dm
@@ -135,18 +135,19 @@ The console is located at computer/gulag_teleporter.dm
if(linked_reclaimer)
linked_reclaimer.stored_items[occupant] = list()
var/mob/living/mob_occupant = occupant
- for(var/obj/item/W in mob_occupant)
- if(!is_type_in_typecache(W, telegulag_required_items))
- if(mob_occupant.temporarilyRemoveItemFromInventory(W))
- if(istype(W, /obj/item/restraints/handcuffs))
- W.forceMove(get_turf(src))
- continue
- if(linked_reclaimer)
- linked_reclaimer.stored_items[mob_occupant] += W
- linked_reclaimer.contents += W
- W.forceMove(linked_reclaimer)
- else
- W.forceMove(src)
+ for(var/A in mob_occupant.get_equipped_items(TRUE))
+ var/obj/item/I = A
+ if(is_type_in_typecache(I, telegulag_required_items) || !mob_occupant.temporarilyRemoveItemFromInventory(I))
+ continue
+ if(istype(I, /obj/item/restraints/handcuffs))
+ I.forceMove(get_turf(src))
+ continue
+ if(linked_reclaimer)
+ linked_reclaimer.stored_items[mob_occupant] += I
+ linked_reclaimer.contents += I
+ I.forceMove(linked_reclaimer)
+ else
+ I.forceMove(src)
/obj/machinery/gulag_teleporter/proc/handle_prisoner(obj/item/id, datum/data/record/R)
if(!ishuman(occupant))
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index b217c14e53..621ca266bb 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -8,14 +8,14 @@
icon_state = "iv_drip"
anchored = FALSE
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
- var/mob/living/carbon/attached = null
+ var/mob/living/carbon/attached
var/mode = IV_INJECTING
- var/obj/item/reagent_containers/beaker = null
+ var/obj/item/reagent_containers/beaker
var/static/list/drip_containers = typecacheof(list(/obj/item/reagent_containers/blood,
/obj/item/reagent_containers/food,
/obj/item/reagent_containers/glass))
-/obj/machinery/iv_drip/Initialize()
+/obj/machinery/iv_drip/Initialize(mapload)
. = ..()
update_icon()
@@ -84,6 +84,8 @@
if(Adjacent(target) && usr.Adjacent(target))
if(beaker)
usr.visible_message("[usr] attaches [src] to [target].", "You attach [src] to [target].")
+ log_combat(usr, target, "attached", src, "containing: [beaker.name] - ([beaker.reagents.log_list()])")
+ add_fingerprint(usr)
attached = target
START_PROCESSING(SSmachines, src)
update_icon()
@@ -100,6 +102,8 @@
return
beaker = W
to_chat(user, "You attach [W] to [src].")
+ user.log_message("attached a [W] to [src] at [AREACOORD(src)] containing ([beaker.reagents.log_list()])", LOG_ATTACK)
+ add_fingerprint(user)
update_icon()
return
else
@@ -142,10 +146,11 @@
if(!amount)
if(prob(5))
visible_message("[src] pings.")
+ playsound(loc, 'sound/machines/beep.ogg', 50, 1)
return
// If the human is losing too much blood, beep.
- if(attached.blood_volume < ( (BLOOD_VOLUME_SAFE*attached.blood_ratio) && prob(5) ) )
+ if(attached.blood_volume < ((BLOOD_VOLUME_SAFE*attached.blood_ratio) && prob(5) && ishuman(attached))) //really couldn't care less about monkeys
visible_message("[src] beeps loudly.")
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
attached.transfer_blood_to(beaker, amount)
@@ -178,9 +183,10 @@
if(usr.incapacitated())
return
-
if(beaker)
- beaker.forceMove(drop_location())
+ if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
+ if(!usr.put_in_hands(beaker))
+ beaker.forceMove(drop_location())
beaker = null
update_icon()
@@ -195,27 +201,27 @@
if(usr.incapacitated())
return
-
mode = !mode
to_chat(usr, "The IV drip is now [mode ? "injecting" : "taking blood"].")
update_icon()
/obj/machinery/iv_drip/examine(mob/user)
- ..()
+ . = ..()
if(get_dist(user, src) > 2)
return
- to_chat(user, "The IV drip is [mode ? "injecting" : "taking blood"].")
+ . += "[src] is [mode ? "injecting" : "taking blood"].\n"
if(beaker)
if(beaker.reagents && beaker.reagents.reagent_list.len)
- to_chat(user, "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.")
+ . += "\tAttached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.\n"
else
- to_chat(user, "Attached is an empty [beaker.name].")
+ . += "\tAttached is an empty [beaker.name].\n"
else
- to_chat(user, "No chemicals are attached.")
+ . += "\tNo chemicals are attached.\n"
- to_chat(user, "[attached ? attached : "No one"] is attached.")
+ . += "\t[attached ? attached : "No one"] is attached."
+ to_chat(user,.)
#undef IV_TAKING
-#undef IV_INJECTING
+#undef IV_INJECTING
\ No newline at end of file
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index b0a75c99dc..165170cf0f 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -40,6 +40,8 @@
var/stun_projectile = null //stun mode projectile type
var/stun_projectile_sound
+ var/nonlethal_projectile //projectile to use in stun mode when the target is resting, if any
+ var/nonlethal_projectile_sound
var/lethal_projectile = null //lethal mode projectile type
var/lethal_projectile_sound
@@ -535,13 +537,22 @@
T = closer
break
+ var/mob/living/carbon/C
+ if(iscarbon(target))
+ C = target
+
update_icon()
var/obj/item/projectile/A
//any emagged turrets drains 2x power and uses a different projectile?
if(mode == TURRET_STUN)
- use_power(reqpower)
- A = new stun_projectile(T)
- playsound(loc, stun_projectile_sound, 75, 1)
+ if(nonlethal_projectile && C && C.resting)
+ use_power(reqpower*0.5)
+ A = new nonlethal_projectile(T)
+ playsound(loc, nonlethal_projectile_sound, 75, 1)
+ else
+ use_power(reqpower)
+ A = new stun_projectile(T)
+ playsound(loc, stun_projectile_sound, 75, 1)
else
use_power(reqpower * 2)
A = new lethal_projectile(T)
@@ -653,6 +664,8 @@
base_icon_state = "standard"
stun_projectile = /obj/item/projectile/energy/electrode
stun_projectile_sound = 'sound/weapons/taser.ogg'
+ nonlethal_projectile = /obj/item/projectile/beam/disabler
+ nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
lethal_projectile = /obj/item/projectile/beam/laser
lethal_projectile_sound = 'sound/weapons/laser.ogg'
desc = "An energy blaster auto-turret."
@@ -662,6 +675,8 @@
base_icon_state = "standard"
stun_projectile = /obj/item/projectile/energy/electrode
stun_projectile_sound = 'sound/weapons/taser.ogg'
+ nonlethal_projectile = /obj/item/projectile/beam/disabler
+ nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
lethal_projectile = /obj/item/projectile/beam/laser/heavylaser
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
desc = "An energy blaster auto-turret."
@@ -681,6 +696,8 @@
/obj/machinery/porta_turret/ai
faction = list("silicon")
+ nonlethal_projectile = /obj/item/projectile/beam/disabler
+ nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
/obj/machinery/porta_turret/ai/assess_perp(mob/living/carbon/human/perp)
return 10 //AI turrets shoot at everything not in their faction
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 9d431487e0..1a8bc7ece4 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -32,10 +32,10 @@
mat_mod *= 50000
for(var/obj/item/stock_parts/manipulator/M in component_parts)
amt_made = 12.5 * M.rating //% of materials salvaged
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.max_amount = mat_mod
amount_produced = min(50, amt_made) + 50
- GET_COMPONENT(butchering, /datum/component/butchering)
+ var/datum/component/butchering/butchering = GetComponent(/datum/component/butchering)
butchering.effectiveness = amount_produced
butchering.bonus_modifier = amount_produced/5
@@ -99,7 +99,7 @@
/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE)
var/list/to_eat
if(isitem(AM0))
- to_eat = AM0.GetAllContents()
+ to_eat = AM0.GetAllContentsIgnoring(GLOB.typecache_mob)
else
to_eat = list(AM0)
@@ -144,7 +144,7 @@
qdel(L)
return
else
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/material_amount = materials.get_item_material_amount(I)
if(!material_amount)
qdel(I)
@@ -195,7 +195,7 @@
L.Unconscious(100)
L.adjustBruteLoss(crush_damage)
if(L.stat == DEAD && (L.butcher_results || L.guaranteed_butcher_results))
- GET_COMPONENT(butchering, /datum/component/butchering)
+ var/datum/component/butchering/butchering = GetComponent(/datum/component/butchering)
butchering.Butcher(src,L)
/obj/machinery/recycler/deathtrap
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index d308d180d0..f35caf514c 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -265,6 +265,8 @@
things_to_clear += occupant.GetAllContents()
for(var/atom/movable/AM in things_to_clear) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
+ AM.clean_blood()
+ AM.fingerprints = list()
var/datum/component/radioactive/contamination = AM.GetComponent(/datum/component/radioactive)
if(contamination)
qdel(contamination)
@@ -435,4 +437,4 @@
if(I)
I.forceMove(loc)
. = TRUE
- update_icon()
+ update_icon()
\ No newline at end of file
diff --git a/code/game/machinery/turnstile.dm b/code/game/machinery/turnstile.dm
new file mode 100644
index 0000000000..1fd78056d4
--- /dev/null
+++ b/code/game/machinery/turnstile.dm
@@ -0,0 +1,84 @@
+/obj/machinery/turnstile
+ name = "turnstile"
+ desc = "A mechanical door that permits one-way access and prevents tailgating."
+ icon = 'icons/obj/turnstile.dmi'
+ icon_state = "turnstile_map"
+ density = FALSE
+ armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 10, bio = 100, rad = 100, fire = 90, acid = 70)
+ anchored = TRUE
+ use_power = FALSE
+ idle_power_usage = 2
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ layer = OPEN_DOOR_LAYER
+
+/obj/machinery/turnstile/Initialize()
+ . = ..()
+ icon_state = "turnstile"
+
+/obj/machinery/turnstile/CanAtmosPass(turf/T)
+ return TRUE
+
+/obj/machinery/turnstile/bullet_act(obj/item/projectile/P, def_zone)
+ return -1 //Pass through!
+
+/obj/machinery/turnstile/proc/allowed_access(var/mob/B)
+ if(B.pulledby && ismob(B.pulledby))
+ return allowed(B.pulledby) | allowed(B)
+ else
+ return allowed(B)
+
+/obj/machinery/turnstile/CanPass(atom/movable/AM, turf/T)
+ if(ismob(AM))
+ var/mob/B = AM
+ if(isliving(AM))
+ var/mob/living/M = AM
+
+ if(world.time - M.last_bumped <= 5)
+ return FALSE
+ M.last_bumped = world.time
+
+ var/allowed_access = FALSE
+ var/turf/behind = get_step(src, dir)
+
+ if(B in behind.contents)
+ allowed_access = allowed_access(B)
+ else
+ to_chat(usr, "\the [src] resists your efforts.")
+ return FALSE
+
+ if(allowed_access)
+ flick("operate", src)
+ playsound(src,'sound/items/ratchet.ogg',50,0,3)
+ return TRUE
+ else
+ flick("deny", src)
+ playsound(src,'sound/machines/deniedbeep.ogg',50,0,3)
+ return FALSE
+ if(ispath(AM, /obj/item/))
+ return TRUE
+ else
+ return FALSE
+
+/obj/machinery/turnstile/CheckExit(atom/movable/AM as mob|obj, target)
+ if(isliving(AM))
+ var/mob/living/M = AM
+ var/outdir = dir
+ if(allowed_access(M))
+ switch(dir)
+ if(NORTH)
+ outdir = SOUTH
+ if(SOUTH)
+ outdir = NORTH
+ if(EAST)
+ outdir = WEST
+ if(WEST)
+ outdir = EAST
+ var/turf/outturf = get_step(src, outdir)
+ var/canexit = (target == src.loc) | (target == outturf)
+
+ if(!canexit && world.time - M.last_bumped <= 5)
+ to_chat(usr, "\the [src] resists your efforts.")
+ M.last_bumped = world.time
+ return canexit
+ else
+ return TRUE
\ No newline at end of file
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index 5e8515d3d5..8be079656b 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -11,10 +11,6 @@
var/obj/item/color_source
var/max_wash_capacity = 5
-/obj/machinery/washing_machine/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
-
/obj/machinery/washing_machine/examine(mob/user)
..()
to_chat(user, "Alt-click it to start a wash cycle.")
@@ -59,7 +55,8 @@
M.Translate(rand(-3, 3), rand(-1, 3))
animate(src, transform=M, time=2)
-/obj/machinery/washing_machine/proc/clean_blood()
+/obj/machinery/washing_machine/clean_blood()
+ ..()
if(!busy)
bloody_mess = FALSE
update_icon()
@@ -67,7 +64,8 @@
/obj/machinery/washing_machine/proc/wash_cycle()
for(var/X in contents)
var/atom/movable/AM = X
- SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ AM.clean_blood()
AM.machine_wash(src)
busy = FALSE
diff --git a/code/game/mecha/combat/neovgre.dm b/code/game/mecha/combat/neovgre.dm
new file mode 100644
index 0000000000..2b2ed150e2
--- /dev/null
+++ b/code/game/mecha/combat/neovgre.dm
@@ -0,0 +1,96 @@
+/obj/mecha/combat/neovgre
+ name = "Neovgre, the Anima Bulwark"
+ desc = "Nezbere's most powerful creation, a mighty war machine of unmatched power said to have ended wars in a single night."
+ icon = 'icons/mecha/neovgre.dmi'
+ icon_state = "neovgre"
+ max_integrity = 500 //This is THE ratvarian superweaon, its deployment is an investment
+ armor = list("melee" = 50, "bullet" = 40, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) //Its similar to the clockwork armour albeit with a few buffs becuase RATVARIAN SUPERWEAPON!!
+ force = 50 //SMASHY SMASHY!!
+ internal_damage_threshold = 0
+ step_in = 3
+ pixel_x = -16
+ layer = ABOVE_MOB_LAYER
+ breach_time = 100 //ten seconds till all goes to shit
+ recharge_rate = 100
+ wreckage = /obj/structure/mecha_wreckage/durand/neovgre
+
+/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar!
+ internals_action.Grant(user, src)
+ cycle_action.Grant(user, src)
+ lights_action.Grant(user, src)
+ stats_action.Grant(user, src)
+ strafing_action.Grant(user, src)
+
+/obj/mecha/combat/neovgre/RemoveActions(mob/living/user, human_occupant = 0)
+ internals_action.Remove(user)
+ cycle_action.Remove(user)
+ lights_action.Remove(user)
+ stats_action.Remove(user)
+ strafing_action.Remove(user)
+
+/obj/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user)
+ if(!is_servant_of_ratvar(user))
+ to_chat(user, "BEGONE HERETIC!")
+ return
+ else
+ ..()
+
+/obj/mecha/combat/neovgre/moved_inside(mob/living/carbon/human/H)
+ var/list/Itemlist = H.get_contents()
+ for(var/obj/item/clockwork/slab/W in Itemlist)
+ to_chat(H, "You safely store [W] inside [src].")
+ qdel(W)
+ . = ..()
+
+/obj/mecha/combat/neovgre/obj_destruction()
+ for(var/mob/M in src)
+ to_chat(M, "You are consumed by the fires raging within Neovgre...")
+ M.dust()
+ playsound(src, 'sound/magic/lightning_chargeup.ogg', 100, 0)
+ src.visible_message("The reactor has gone critical, its going to blow!")
+ addtimer(CALLBACK(src,.proc/go_critical),breach_time)
+
+/obj/mecha/combat/neovgre/proc/go_critical()
+ explosion(get_turf(loc), 3, 5, 10, 20, 30)
+ Destroy(src)
+
+/obj/mecha/combat/neovgre/container_resist(mob/living/user)
+ to_chat(user, "Neovgre requires a lifetime commitment friend, no backing out now!")
+ return
+
+/obj/mecha/combat/neovgre/process()
+ ..()
+ if(GLOB.ratvar_awakens) // At this point only timley intervention by lord singulo could hople to stop the superweapon
+ cell.charge = INFINITY
+ max_integrity = INFINITY
+ obj_integrity = max_integrity
+ CHECK_TICK //Just to be on the safe side lag wise
+ else if(cell.charge < cell.maxcharge)
+ for(var/obj/effect/clockwork/sigil/transmission/T in range(SIGIL_ACCESS_RANGE, src))
+ var/delta = min(recharge_rate, cell.maxcharge - cell.charge)
+ if (get_clockwork_power() <= delta)
+ cell.charge += delta
+ adjust_clockwork_power(-delta)
+ CHECK_TICK
+
+/obj/mecha/combat/neovgre/Initialize()
+ .=..()
+ GLOB.neovgre_exists ++
+ var/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/N = new
+ N.attach(src)
+
+/obj/structure/mecha_wreckage/durand/neovgre
+ name = "\improper Neovgre wreckage?"
+ desc = "On closer inspection this looks like the wreck of a durand with some spraypainted cardboard duct taped to it!"
+
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre
+ equip_cooldown = 8 //Rapid fire heavy laser cannon, simple yet elegant
+ energy_drain = 30
+ name = "Aribter Laser Cannon"
+ desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere"
+ fire_sound = "sound/weapons/neovgre_laser.ogg"
+
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/mecha/combat/neovgre/M)
+ if(istype(M))
+ return 1
+ return 0
diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm
index eb3261bb27..4044951c42 100644
--- a/code/game/mecha/equipment/tools/mining_tools.dm
+++ b/code/game/mecha/equipment/tools/mining_tools.dm
@@ -100,12 +100,12 @@
/obj/item/mecha_parts/mecha_equipment/drill/attach(obj/mecha/M)
..()
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = TRUE
/obj/item/mecha_parts/mecha_equipment/drill/detach(atom/moveto)
..()
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = FALSE
/obj/item/mecha_parts/mecha_equipment/drill/proc/drill_mob(mob/living/target, mob/user)
@@ -115,7 +115,7 @@
if(target.stat == DEAD && target.getBruteLoss() >= 200)
log_combat(user, target, "gibbed", name)
if(LAZYLEN(target.butcher_results) || LAZYLEN(target.guaranteed_butcher_results))
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.Butcher(chassis, target)
else
target.gib()
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index e1dc80911f..4acf7981bc 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -47,7 +47,7 @@
//maximum stocking amount (default 300000, 600000 at T4)
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
T += M.rating
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.max_amount = (200000 + (T*50000))
//resources adjustment coefficient (1 -> 0.85 -> 0.7 -> 0.55)
@@ -109,7 +109,7 @@
/obj/machinery/mecha_part_fabricator/proc/output_available_resources()
var/output
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
output += "[M.name]: [M.amount] cm³"
@@ -130,7 +130,7 @@
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
if(D.reagents_list.len) // No reagents storage - no reagent designs.
return FALSE
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(materials.has_materials(get_resources_w_coeff(D)))
return TRUE
return FALSE
@@ -140,7 +140,7 @@
desc = "It's building \a [initial(D.name)]."
var/list/res_coef = get_resources_w_coeff(D)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.use_amount(res_coef)
add_overlay("fab-active")
use_power = ACTIVE_POWER_USE
@@ -384,14 +384,14 @@
break
if(href_list["remove_mat"] && href_list["material"])
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_sheets(text2num(href_list["remove_mat"]), href_list["material"])
updateUsrDialog()
return
/obj/machinery/mecha_part_fabricator/on_deconstruction()
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
..()
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 22aac63d2b..7348c8a575 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -49,6 +49,8 @@
var/lights = FALSE
var/lights_power = 6
var/last_user_hud = 1 // used to show/hide the mecha hud while preserving previous preference
+ var/breach_time = 0
+ var/recharge_rate = 0
var/bumpsmash = 0 //Whether or not the mech destroys walls by running into it.
//inner atmos
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index ef3ba969e9..19656f2d7d 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -47,7 +47,7 @@
/obj/mecha/working/ripley/update_icon()
..()
- GET_COMPONENT(C,/datum/component/armor_plate)
+ var/datum/component/armor_plate/C = GetComponent(/datum/component/armor_plate)
if (C.amount)
cut_overlays()
if(C.amount < 3)
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index d5aff99f32..2eb4a6aa0c 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -8,6 +8,7 @@
/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
. = ..()
+ LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
create_reagents(300)
@@ -27,7 +28,7 @@
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
if(mergeable_decal)
- return TRUE
+ qdel(C)
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
@@ -81,7 +82,9 @@
add_blood = bloodiness
bloodiness -= add_blood
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood)
- S.add_blood_DNA(return_blood_DNA())
+ if(blood_DNA && blood_DNA.len)
+ S.add_blood_DNA(blood_DNA)
+ S.add_blood_overlay()
S.blood_state = blood_state
update_icon()
H.update_inv_shoes()
@@ -90,4 +93,4 @@
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
return bloodiness
else
- return 0
+ return FALSE
diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm
index ca2a8ccaff..a4d0da1bbe 100644
--- a/code/game/objects/effects/decals/cleanable/aliens.dm
+++ b/code/game/objects/effects/decals/cleanable/aliens.dm
@@ -1,71 +1,70 @@
-// Note: BYOND is object oriented. There is no reason for this to be copy/pasted blood code.
-/obj/effect/decal/cleanable/xenoblood
+/obj/effect/decal/cleanable/blood/xeno
name = "xeno blood"
desc = "It's green and acidic. It looks like... blood?"
- icon = 'icons/effects/blood.dmi'
- icon_state = "xfloor1"
- random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
- bloodiness = BLOOD_AMOUNT_PER_DECAL
- blood_state = BLOOD_STATE_XENO
+ color = BLOOD_COLOR_XENO
-/obj/effect/decal/cleanable/xenoblood/Initialize()
+/obj/effect/decal/cleanable/blood/splatter/xeno
+ color = BLOOD_COLOR_XENO
+
+/obj/effect/decal/cleanable/blood/gibs/xeno
+ color = BLOOD_COLOR_XENO
+ gibs_reagent_id = "liquidxenogibs"
+ gibs_bloodtype = "X*"
+
+/obj/effect/decal/cleanable/blood/gibs/xeno/Initialize(mapload, list/datum/disease/diseases)
. = ..()
- add_blood_DNA(list("UNKNOWN DNA" = "X*"))
+ update_icon()
-/obj/effect/decal/cleanable/xenoblood/xsplatter
- random_icon_states = list("xgibbl1", "xgibbl2", "xgibbl3", "xgibbl4", "xgibbl5")
+/obj/effect/decal/cleanable/blood/gibs/xeno/update_icon()
+ add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
+ cut_overlays()
+ var/mutable_appearance/flesh = mutable_appearance(icon, "[icon_state]x_flesh")
+ flesh.appearance_flags = RESET_COLOR
+ flesh.color = body_colors
+ add_overlay(flesh)
-/obj/effect/decal/cleanable/xenoblood/xgibs
- name = "xeno gibs"
- desc = "Gnarly..."
- icon = 'icons/effects/blood.dmi'
- icon_state = "xgib1"
- layer = LOW_OBJ_LAYER
- random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6")
- mergeable_decal = FALSE
-
-/obj/effect/decal/cleanable/xenoblood/xgibs/proc/streak(list/directions)
- set waitfor = 0
+/obj/effect/decal/cleanable/blood/gibs/xeno/streak(list/directions)
+ set waitfor = FALSE
+ var/list/diseases = list()
+ SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
- for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
+ for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
- new /obj/effect/decal/cleanable/xenoblood/xsplatter(loc)
+ var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases)
+ splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
-/obj/effect/decal/cleanable/xenoblood/xgibs/ex_act()
- return
+/obj/effect/decal/cleanable/blood/gibs/xeno/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
-/obj/effect/decal/cleanable/xenoblood/xgibs/up
- random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibup1","xgibup1","xgibup1")
+/obj/effect/decal/cleanable/blood/gibs/xeno/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
-/obj/effect/decal/cleanable/xenoblood/xgibs/down
- random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibdown1","xgibdown1","xgibdown1")
+/obj/effect/decal/cleanable/blood/gibs/xeno/body
+ random_icon_states = list("gibhead", "gibtorso")
-/obj/effect/decal/cleanable/xenoblood/xgibs/body
- random_icon_states = list("xgibhead", "xgibtorso")
+/obj/effect/decal/cleanable/blood/gibs/xeno/torso
+ random_icon_states = list("gibtorso")
-/obj/effect/decal/cleanable/xenoblood/xgibs/torso
- random_icon_states = list("xgibtorso")
+/obj/effect/decal/cleanable/blood/gibs/xeno/limb
+ random_icon_states = list("gibleg", "gibarm")
-/obj/effect/decal/cleanable/xenoblood/xgibs/limb
- random_icon_states = list("xgibleg", "xgibarm")
+/obj/effect/decal/cleanable/blood/gibs/xeno/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
-/obj/effect/decal/cleanable/xenoblood/xgibs/core
- random_icon_states = list("xgibmid1", "xgibmid2", "xgibmid3")
-
-/obj/effect/decal/cleanable/xenoblood/xgibs/larva
+/obj/effect/decal/cleanable/blood/gibs/xeno/larva
random_icon_states = list("xgiblarva1", "xgiblarva2")
-/obj/effect/decal/cleanable/xenoblood/xgibs/larva/body
+/obj/effect/decal/cleanable/blood/gibs/xeno/larva/body
random_icon_states = list("xgiblarvahead", "xgiblarvatorso")
/obj/effect/decal/cleanable/blood/xtracks
- icon_state = "xtracks"
+ icon_state = "tracks"
random_icon_states = null
/obj/effect/decal/cleanable/blood/xtracks/Initialize()
- . = ..()
- add_blood_DNA(list("Unknown DNA" = "X*"))
+ add_blood_DNA(list("UNKNOWN DNA" = "X*"))
+ . = ..()
\ No newline at end of file
diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm
new file mode 100644
index 0000000000..03eeca7d0b
--- /dev/null
+++ b/code/game/objects/effects/decals/cleanable/gibs.dm
@@ -0,0 +1,231 @@
+/obj/effect/decal/cleanable/blood/gibs
+ name = "gibs"
+ desc = "They look bloody and gruesome."
+ icon_state = "gibbl5"
+ layer = LOW_OBJ_LAYER
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
+ mergeable_decal = FALSE
+ var/body_colors = "#e3ba84" //a default color just in case.
+ var/gibs_reagent_id = "liquidgibs"
+ var/gibs_bloodtype = "A+"
+
+/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ if(random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
+ icon_state = pick(random_icon_states)
+ if(gibs_reagent_id)
+ reagents.add_reagent(gibs_reagent_id, 5)
+ if(gibs_bloodtype)
+ add_blood_DNA(list("Non-human DNA" = gibs_bloodtype, diseases))
+ update_icon()
+
+
+/obj/effect/decal/cleanable/blood/gibs/update_icon()
+ add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
+ cut_overlays()
+ var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]_guts")
+ guts.appearance_flags = RESET_COLOR
+ add_overlay(guts)
+ var/mutable_appearance/flesh = mutable_appearance(icon, "[icon_state]_flesh")
+ flesh.appearance_flags = RESET_COLOR
+ flesh.color = body_colors
+ add_overlay(flesh)
+
+/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
+ return
+
+/obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L)
+ if(istype(L) && has_gravity(loc))
+ playsound(loc, 'sound/effects/gib_step.ogg', !HAS_TRAIT(L,TRAIT_LIGHT_STEP) ? 20 : 50, 1)
+ . = ..()
+
+/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
+ set waitfor = FALSE
+ var/list/diseases = list()
+ SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
+ var/direction = pick(directions)
+ for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
+ sleep(2)
+ if(i > 0)
+ var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
+ splat.transfer_blood_dna(blood_DNA, diseases)
+ if(!step_to(src, get_step(src, direction), 0))
+ break
+
+/obj/effect/decal/cleanable/blood/gibs/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
+
+/obj/effect/decal/cleanable/blood/gibs/old
+ name = "old rotting gibs"
+ desc = "Space Jesus, why didn't anyone clean this up? It smells terrible."
+ bloodiness = 0
+
+/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ setDir(pick(GLOB.cardinals))
+ icon_state += "-old"
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/drip
+ name = "drips of blood"
+ desc = "It's gooey."
+ icon_state = "1"
+ random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
+ bloodiness = 0
+ var/drips = 1
+
+/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
+ return TRUE
+
+/obj/effect/decal/cleanable/blood/gibs/human
+
+/obj/effect/decal/cleanable/blood/gibs/human/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/gibs/human/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/human/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/human/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/human/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/human/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/human/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
+
+
+//Lizards
+/obj/effect/decal/cleanable/blood/gibs/human/lizard
+ body_colors = "117720"
+ gibs_reagent_id = "liquidgibs"
+ gibs_bloodtype = "L"
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
+
+// Slime Gibs
+/obj/effect/decal/cleanable/blood/gibs/slime
+ desc = "They look gooey and gruesome."
+ gibs_reagent_id = "liquidslimegibs"
+ gibs_bloodtype = "GEL"
+
+/obj/effect/decal/cleanable/blood/gibs/slime/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/gibs/slime/update_icon()
+ add_atom_colour(body_colors, FIXED_COLOUR_PRIORITY)
+ cut_overlays()
+ var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]s_guts")
+ guts.appearance_flags = RESET_COLOR
+ guts.color = body_colors
+ add_overlay(guts)
+ var/mutable_appearance/flesh = mutable_appearance(icon, "[icon_state]_flesh")
+ flesh.appearance_flags = RESET_COLOR
+ flesh.color = body_colors
+ add_overlay(flesh)
+
+/obj/effect/decal/cleanable/blood/gibs/slime/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
+
+/obj/effect/decal/cleanable/blood/gibs/synth
+ desc = "They look sludgy and disgusting."
+ gibs_reagent_id = "liquidsyntheticgibs"
+ gibs_bloodtype = "SY"
+
+/obj/effect/decal/cleanable/blood/gibs/synth/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+//IPCs
+/obj/effect/decal/cleanable/blood/gibs/ipc
+ desc = "They look sharp yet oozing."
+ body_colors = "00ff00"
+ gibs_reagent_id = "liquidoilgibs"
+ gibs_bloodtype = "HF"
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/update_icon()
+ add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
+ cut_overlays()
+ var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]r-overlay")
+ guts.appearance_flags = RESET_COLOR
+ add_overlay(guts)
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index 35f06c2768..842b230b53 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -1,31 +1,45 @@
/obj/effect/decal/cleanable/blood
name = "blood"
- desc = "It's red and gooey. Perhaps it's the chef's cooking?"
+ desc = "It's gooey. Perhaps it's the chef's cooking?"
icon = 'icons/effects/blood.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
- blood_state = BLOOD_STATE_HUMAN
- bloodiness = BLOOD_AMOUNT_PER_DECAL
+ blood_state = BLOOD_STATE_BLOOD
+ bloodiness = MAX_SHOE_BLOODINESS
+ color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
- C.add_blood_DNA(return_blood_DNA())
- if (bloodiness)
- if (C.bloodiness < MAX_SHOE_BLOODINESS)
- C.bloodiness += bloodiness
- return ..()
+ if (C.blood_DNA)
+ blood_DNA |= C.blood_DNA.Copy()
+ update_icon()
+ ..()
+
+/obj/effect/decal/cleanable/blood/transfer_blood_dna()
+ ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/transfer_mob_blood_dna()
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/update_icon()
+ color = blood_DNA_to_color()
/obj/effect/decal/cleanable/blood/old
name = "dried blood"
- desc = "Looks like it's been here a while. Eew."
+ desc = "Looks like it's been here a while. Eew."
bloodiness = 0
/obj/effect/decal/cleanable/blood/old/Initialize(mapload, list/datum/disease/diseases)
- icon_state += "-old" //This IS necessary because the parent /blood type uses icon randomization.
- add_blood_DNA(list("Non-human DNA" = "A+")) // Needs to happen before ..()
- return ..()
+ ..()
+ icon_state += "-old"
+ add_blood_DNA(list("Non-human DNA" = "A+"))
+
+/obj/effect/decal/cleanable/blood/splats
+ random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
/obj/effect/decal/cleanable/blood/splatter
- random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
+ random_icon_states = list("splatter1", "splatter2", "splatter3", "splatter4", "splatter5")
/obj/effect/decal/cleanable/blood/tracks
icon_state = "tracks"
@@ -39,84 +53,23 @@
random_icon_states = null
var/list/existing_dirs = list()
+/obj/effect/decal/cleanable/trail_holder/update_icon()
+ color = blood_DNA_to_color()
+
+/obj/effect/cleanable/trail_holder/Initialize()
+ . = ..()
+ update_icon()
+
/obj/effect/decal/cleanable/trail_holder/can_bloodcrawl_in()
return TRUE
-/obj/effect/decal/cleanable/blood/gibs
- name = "gibs"
- desc = "They look bloody and gruesome."
- icon = 'icons/effects/blood.dmi'
- icon_state = "gibbl5"
- layer = LOW_OBJ_LAYER
- random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
- mergeable_decal = FALSE
+/obj/effect/decal/cleanable/trail_holder/transfer_blood_dna()
+ ..()
+ update_icon()
-/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
+/obj/effect/decal/cleanable/trail_holder/transfer_mob_blood_dna()
. = ..()
- reagents.add_reagent("liquidgibs", 5)
-
-/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
- return
-
-/obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L)
- if(istype(L) && has_gravity(loc))
- playsound(loc, 'sound/effects/gib_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 20 : 50, 1)
- . = ..()
-
-/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
- set waitfor = 0
- var/direction = pick(directions)
- for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
- sleep(2)
- if(i > 0)
- var/list/datum/disease/diseases
- GET_COMPONENT(infective, /datum/component/infective)
- if(infective)
- diseases = infective.diseases
- new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
- if(!step_to(src, get_step(src, direction), 0))
- break
-
-/obj/effect/decal/cleanable/blood/gibs/up
- random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
-
-/obj/effect/decal/cleanable/blood/gibs/down
- random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
-
-/obj/effect/decal/cleanable/blood/gibs/body
- random_icon_states = list("gibhead", "gibtorso")
-
-/obj/effect/decal/cleanable/blood/gibs/torso
- random_icon_states = list("gibtorso")
-
-/obj/effect/decal/cleanable/blood/gibs/limb
- random_icon_states = list("gibleg", "gibarm")
-
-/obj/effect/decal/cleanable/blood/gibs/core
- random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
-
-/obj/effect/decal/cleanable/blood/gibs/old
- name = "old rotting gibs"
- desc = "Space Jesus, why didn't anyone clean this up? It smells terrible."
- bloodiness = 0
-
-/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload, list/datum/disease/diseases)
- . = ..()
- setDir(pick(1,2,4,8))
- icon_state += "-old"
- add_blood_DNA(list("Non-human DNA" = "A+"))
-
-/obj/effect/decal/cleanable/blood/drip
- name = "drips of blood"
- desc = "It's red."
- icon_state = "1"
- random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
- bloodiness = 0
- var/drips = 1
-
-/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
- return TRUE
-
+ update_icon()
//BLOODY FOOTPRINTS
/obj/effect/decal/cleanable/blood/footprints
@@ -127,15 +80,16 @@
random_icon_states = null
var/entered_dirs = 0
var/exited_dirs = 0
- blood_state = BLOOD_STATE_HUMAN //the icon state to load images from
+ blood_state = BLOOD_STATE_BLOOD //the icon state to load images from
var/list/shoe_types = list()
/obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O)
- ..()
if(ishuman(O))
var/mob/living/carbon/human/H = O
var/obj/item/clothing/shoes/S = H.shoes
if(S && S.bloody_shoes[blood_state])
+ if(color != bloodtype_to_color(S.last_bloodtype))
+ return
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
shoe_types |= S.type
if (!(entered_dirs & H.dir))
@@ -143,21 +97,21 @@
update_icon()
/obj/effect/decal/cleanable/blood/footprints/Uncrossed(atom/movable/O)
- ..()
if(ishuman(O))
var/mob/living/carbon/human/H = O
var/obj/item/clothing/shoes/S = H.shoes
if(S && S.bloody_shoes[blood_state])
+ if(color != bloodtype_to_color(S.last_bloodtype))//last entry - we check its color
+ return
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
shoe_types |= S.type
if (!(exited_dirs & H.dir))
exited_dirs |= H.dir
update_icon()
-
/obj/effect/decal/cleanable/blood/footprints/update_icon()
+ ..()
cut_overlays()
-
for(var/Ddir in GLOB.cardinals)
if(entered_dirs & Ddir)
var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"]
@@ -170,7 +124,7 @@
GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]2", dir = Ddir)
add_overlay(bloodstep_overlay)
- alpha = BLOODY_FOOTPRINT_BASE_ALPHA+bloodiness
+ alpha = BLOODY_FOOTPRINT_BASE_ALPHA + bloodiness
/obj/effect/decal/cleanable/blood/footprints/examine(mob/user)
@@ -179,16 +133,62 @@
. += "You recognise the footprints as belonging to:\n"
for(var/shoe in shoe_types)
var/obj/item/clothing/shoes/S = shoe
- . += "[icon2html(initial(S.icon), user)] Some [initial(S.name)].\n"
+ . += "some [initial(S.name)] [icon2html(initial(S.icon), user)]\n"
to_chat(user, .)
/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/C)
if(blood_state != C.blood_state) //We only replace footprints of the same type as us
return
+ if(color != C.color)
+ return
..()
/obj/effect/decal/cleanable/blood/footprints/can_bloodcrawl_in()
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
- return 1
- return 0
+ return TRUE
+ return FALSE
+
+/* Eventually TODO: make snowflake trails like baycode's
+/obj/effect/decal/cleanable/blood/footprints/tracks/shoe
+ name = "footprints"
+ desc = "They look like tracks left by footwear."
+ icon_state = FOOTPRINT_SHOE
+ print_state = FOOTPRINT_SHOE
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/foot
+ name = "footprints"
+ desc = "They look like tracks left by a bare foot."
+ icon_state = FOOTPRINT_FOOT
+ print_state = FOOTPRINT_FOOT
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/snake
+ name = "tracks"
+ desc = "They look like tracks left by a giant snake."
+ icon_state = FOOTPRINT_SNAKE
+ print_state = FOOTPRINT_SNAKE
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/paw
+ name = "footprints"
+ desc = "They look like tracks left by paws."
+ icon_state = FOOTPRINT_PAW
+ print_state = FOOTPRINT_PAW
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/claw
+ name = "footprints"
+ desc = "They look like tracks left by claws."
+ icon_state = FOOTPRINT_CLAW
+ print_state = FOOTPRINT_CLAW
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/wheels
+ name = "tracks"
+ desc = "They look like tracks left by wheels."
+ gender = PLURAL
+ icon_state = FOOTPRINT_WHEEL
+ print_state = FOOTPRINT_WHEEL
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/body
+ name = "trails"
+ desc = "A trail left by something being dragged."
+ icon_state = FOOTPRINT_DRAG
+ print_state = FOOTPRINT_DRAG */
diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm
index 484e0438e2..02bf51bdd9 100644
--- a/code/game/objects/effects/decals/cleanable/robots.dm
+++ b/code/game/objects/effects/decals/cleanable/robots.dm
@@ -11,6 +11,10 @@
bloodiness = BLOOD_AMOUNT_PER_DECAL
mergeable_decal = FALSE
+/obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ reagents.add_reagent("liquidoilgibs", 5)
+
/obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
@@ -50,6 +54,7 @@
/obj/effect/decal/cleanable/oil/Initialize()
. = ..()
reagents.add_reagent("oil", 30)
+ reagents.add_reagent("liquidoilgibs", 5)
/obj/effect/decal/cleanable/oil/streak
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
diff --git a/code/game/objects/effects/proximity.dm b/code/game/objects/effects/proximity.dm
index de17582f27..6c9525008d 100644
--- a/code/game/objects/effects/proximity.dm
+++ b/code/game/objects/effects/proximity.dm
@@ -5,7 +5,6 @@
var/list/checkers //list of /obj/effect/abstract/proximity_checkers
var/current_range
var/ignore_if_not_on_turf //don't check turfs in range if the host's loc isn't a turf
- var/datum/component/movement_tracker
/datum/proximity_monitor/New(atom/_host, range, _ignore_if_not_on_turf = TRUE)
checkers = list()
@@ -15,15 +14,17 @@
SetHost(_host)
/datum/proximity_monitor/proc/SetHost(atom/H,atom/R)
+ if(H == host)
+ return
+ if(host)
+ UnregisterSignal(host, COMSIG_MOVABLE_MOVED)
if(R)
hasprox_receiver = R
else if(hasprox_receiver == host) //Default case
hasprox_receiver = H
host = H
+ RegisterSignal(host, COMSIG_MOVABLE_MOVED, .proc/HandleMove)
last_host_loc = host.loc
- if(movement_tracker)
- QDEL_NULL(movement_tracker)
- movement_tracker = host.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/HandleMove)))
SetRange(current_range,TRUE)
/datum/proximity_monitor/Destroy()
@@ -31,7 +32,6 @@
last_host_loc = null
hasprox_receiver = null
QDEL_LIST(checkers)
- QDEL_NULL(movement_tracker)
return ..()
/datum/proximity_monitor/proc/HandleMove()
diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm
index e99a2fcbc6..dd39bc567a 100644
--- a/code/game/objects/effects/spawners/gibspawner.dm
+++ b/code/game/objects/effects/spawners/gibspawner.dm
@@ -1,25 +1,69 @@
/obj/effect/gibspawner
- var/sparks = 0 //whether sparks spread
+ var/sparks = FALSE //whether sparks spread
var/virusProb = 20 //the chance for viruses to spread on the gibs
+ var/gib_mob_type //generate a fake mob to transfer DNA from if we weren't passed a mob.
+ var/gib_mob_species //We'll want to nip-pick their species for blood type stuff
+ var/sound_to_play = 'sound/effects/blobattack.ogg'
+ var/sound_vol = 60
var/list/gibtypes = list() //typepaths of the gib decals to spawn
var/list/gibamounts = list() //amount to spawn for each gib decal type we'll spawn.
var/list/gibdirections = list() //of lists of possible directions to spread each gib decal type towards.
-/obj/effect/gibspawner/Initialize(mapload, datum/dna/MobDNA, list/datum/disease/diseases)
+/obj/effect/gibspawner/Initialize(mapload, mob/living/source_mob, list/datum/disease/diseases)
. = ..()
-
- if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
- to_chat(world, "Gib list length mismatch!")
+ if(gibtypes.len != gibamounts.len)
+ stack_trace("Gib list amount length mismatch!")
+ return
+ if(gibamounts.len != gibdirections.len)
+ stack_trace("Gib list dir length mismatch!")
return
var/obj/effect/decal/cleanable/blood/gibs/gib = null
+ if(sound_to_play && isnum(sound_vol))
+ playsound(src, sound_to_play, sound_vol, TRUE)
+
if(sparks)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(2, 1, loc)
s.start()
+ var/list/dna_to_add //find the dna to pass to the spawned gibs. do note this can be null if the mob doesn't have blood. add_blood_DNA() has built in null handling.
+ var/body_coloring = ""
+ if(source_mob)
+ dna_to_add = source_mob.get_blood_dna_list() //ez pz
+ if(ishuman(source_mob))
+ var/mob/living/carbon/human/H = source_mob
+ if(H.dna.species.use_skintones)
+ body_coloring = "#[skintone2hex(H.skin_tone)]"
+ else
+ body_coloring = "#[H.dna.features["mcolor"]]"
+
+ else if(gib_mob_type)
+ var/mob/living/temp_mob = new gib_mob_type(src) //generate a fake mob so that we pull the right type of DNA for the gibs.
+ if(gib_mob_species)
+ if(ishuman(temp_mob))
+ var/mob/living/carbon/human/H = temp_mob
+ H.set_species(gib_mob_species)
+ dna_to_add = temp_mob.get_blood_dna_list()
+ if(H.dna.species.use_skintones)
+ body_coloring = "#[skintone2hex(H.skin_tone)]"
+ else
+ body_coloring = "#[H.dna.features["mcolor"]]"
+ qdel(H)
+ else
+ dna_to_add = temp_mob.get_blood_dna_list()
+ qdel(temp_mob)
+ else if(!issilicon(temp_mob))
+ dna_to_add = temp_mob.get_blood_dna_list()
+ qdel(temp_mob)
+ else
+ qdel(temp_mob)
+ else
+ dna_to_add = list("Non-human DNA" = random_blood_type()) //else, generate a random bloodtype for it.
+
+
for(var/i = 1, i<= gibtypes.len, i++)
if(gibamounts[i])
for(var/j = 1, j<= gibamounts[i], j++)
@@ -29,10 +73,11 @@
var/mob/living/carbon/digester = loc
digester.stomach_contents += gib
- if(MobDNA)
+ if(dna_to_add && dna_to_add.len)
+ gib.add_blood_DNA(dna_to_add)
+ gib.body_colors = body_coloring
+ gib.update_icon()
- else if(istype(src, /obj/effect/gibspawner/generic)) // Probably a monkey
- gib.add_blood_DNA(list("Non-human DNA" = "A+"))
var/list/directions = gibdirections[i]
if(isturf(loc))
if(directions.len)
@@ -41,80 +86,158 @@
return INITIALIZE_HINT_QDEL
-
/obj/effect/gibspawner/generic
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core)
- gibamounts = list(2,2,1)
+ gibamounts = list(2, 2, 1)
+ sound_vol = 40
/obj/effect/gibspawner/generic/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 40, 1)
- gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
+ return ..()
+
+/obj/effect/gibspawner/generic/animal
+ gib_mob_type = /mob/living/simple_animal/pet
/obj/effect/gibspawner/human
- gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/up, /obj/effect/decal/cleanable/blood/gibs/down, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/body, /obj/effect/decal/cleanable/blood/gibs/limb, /obj/effect/decal/cleanable/blood/gibs/core)
- gibamounts = list(1,1,1,1,1,1,1)
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/up, /obj/effect/decal/cleanable/blood/gibs/human/down, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/body, /obj/effect/decal/cleanable/blood/gibs/human/limb, /obj/effect/decal/cleanable/blood/gibs/human/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/human
+ gib_mob_species = /datum/species/human
+ sound_vol = 50
/obj/effect/gibspawner/human/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 50, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
-
-/obj/effect/gibspawner/humanbodypartless //only the gibs that don't look like actual full bodyparts (except torso).
- gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/torso)
+/obj/effect/gibspawner/human/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/core, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/core, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
-/obj/effect/gibspawner/humanbodypartless/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 50, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
- . = ..()
+/obj/effect/gibspawner/human/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
+/obj/effect/gibspawner/lizard
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/lizard/up, /obj/effect/decal/cleanable/blood/gibs/human/lizard/down, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/body, /obj/effect/decal/cleanable/blood/gibs/human/lizard/limb, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/human/species/lizard
+ gib_mob_species = /datum/species/lizard
+ sound_vol = 50
+
+/obj/effect/gibspawner/lizard/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/lizard/bodypartless
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/torso)
+ gibamounts = list(1, 1, 1, 1, 1, 1)
+
+/obj/effect/gibspawner/lizard/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/slime
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/slime/up, /obj/effect/decal/cleanable/blood/gibs/slime/down, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/body, /obj/effect/decal/cleanable/blood/gibs/slime/limb, /obj/effect/decal/cleanable/blood/gibs/slime/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/human/species/roundstartslime
+ gib_mob_species = /datum/species/jelly/roundstartslime
+ sound_vol = 50
+
+/obj/effect/gibspawner/slime/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/slime/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/core, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/core, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/torso)
+ gibamounts = list(1, 1, 1, 1, 1, 1)
+
+/obj/effect/gibspawner/slime/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/ipc
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/ipc/up, /obj/effect/decal/cleanable/blood/gibs/ipc/down, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/body, /obj/effect/decal/cleanable/blood/gibs/ipc/limb, /obj/effect/decal/cleanable/blood/gibs/ipc/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/human/species/ipc
+ gib_mob_species = /datum/species/ipc
+ sound_vol = 50
+ sparks = TRUE
+ sound_to_play = 'sound/effects/bang.ogg'
+
+/obj/effect/gibspawner/ipc/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/ipc/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/core, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/core, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/torso)
+ gibamounts = list(1, 1, 1, 1, 1, 1)
+
+/obj/effect/gibspawner/ipc/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
/obj/effect/gibspawner/xeno
- gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/up, /obj/effect/decal/cleanable/xenoblood/xgibs/down, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/body, /obj/effect/decal/cleanable/xenoblood/xgibs/limb, /obj/effect/decal/cleanable/xenoblood/xgibs/core)
- gibamounts = list(1,1,1,1,1,1,1)
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/up, /obj/effect/decal/cleanable/blood/gibs/xeno/down, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/body, /obj/effect/decal/cleanable/blood/gibs/xeno/limb, /obj/effect/decal/cleanable/blood/gibs/xeno/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/alien
/obj/effect/gibspawner/xeno/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
-
-/obj/effect/gibspawner/xenobodypartless //only the gibs that don't look like actual full bodyparts (except torso).
- gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/torso)
+/obj/effect/gibspawner/xeno/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
+/obj/effect/gibspawner/xeno/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
-/obj/effect/gibspawner/xenobodypartless/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
- . = ..()
+/obj/effect/gibspawner/xeno/xenoperson
+ gib_mob_type = /mob/living/carbon/human/species/xeno
+ gib_mob_species = /datum/species/xeno
+
+/obj/effect/gibspawner/xeno/xenoperson/bodypartless
/obj/effect/gibspawner/larva
- gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva/body, /obj/effect/decal/cleanable/xenoblood/xgibs/larva/body)
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva/body, /obj/effect/decal/cleanable/blood/gibs/xeno/larva/body)
gibamounts = list(1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/alien/larva
/obj/effect/gibspawner/larva/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list(), GLOB.alldirs)
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list(), GLOB.alldirs)
+ return ..()
-/obj/effect/gibspawner/larvabodypartless
- gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva)
+/obj/effect/gibspawner/larva/bodypartless
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva)
gibamounts = list(1, 1, 1)
-/obj/effect/gibspawner/larvabodypartless/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list())
- . = ..()
+/obj/effect/gibspawner/larva/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list())
+ return ..()
/obj/effect/gibspawner/robot
- sparks = 1
+ sparks = TRUE
gibtypes = list(/obj/effect/decal/cleanable/robot_debris/up, /obj/effect/decal/cleanable/robot_debris/down, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris/limb)
- gibamounts = list(1,1,1,1,1,1)
+ gibamounts = list(1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/silicon/robot
/obj/effect/gibspawner/robot/Initialize()
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs)
- gibamounts[6] = pick(0,1,2)
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs)
+ gibamounts[6] = pick(0, 1, 2)
+ return ..()
+
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 7d02d9d383..fbad000098 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -6,7 +6,9 @@
layer = BELOW_MOB_LAYER
var/splatter_type = "splatter"
-/obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, set_dir)
+/obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, set_dir, new_color)
+ if(new_color)
+ color = new_color
if(set_dir in GLOB.diagonals)
icon_state = "[splatter_type][pick(1, 2, 6)]"
else
@@ -41,7 +43,7 @@
animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
/obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter
- splatter_type = "xsplatter"
+ color = BLOOD_COLOR_XENO
/obj/effect/temp_visual/dir_setting/speedbike_trail
name = "speedbike trails"
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 6a706fede9..9ce2e66abf 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -111,7 +111,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder!
-
/obj/item/Initialize()
materials = typelist("materials", materials)
@@ -408,12 +407,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
for(var/X in actions)
var/datum/action/A = X
- if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot.
+ if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot.
A.Grant(user)
item_flags |= IN_INVENTORY
//sometimes we only want to grant the item's action if it's equipped in a specific slot.
-/obj/item/proc/item_action_slot_check(slot, mob/user)
+/obj/item/proc/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_IN_BACKPACK || slot == SLOT_LEGCUFFED) //these aren't true slots, so avoid granting actions there
return FALSE
return TRUE
@@ -537,6 +536,17 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.become_blind(EYE_DAMAGE)
to_chat(M, "You go blind!")
+/obj/item/clean_blood()
+ . = ..()
+ if(.)
+ if(blood_splatter_icon)
+ cut_overlay(blood_splatter_icon)
+
+/obj/item/clothing/gloves/clean_blood()
+ . = ..()
+ if(.)
+ transfer_blood = 0
+
/obj/item/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FOUR)
diff --git a/code/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm
index 63f460f9aa..93293155a3 100644
--- a/code/game/objects/items/RCL.dm
+++ b/code/game/objects/items/RCL.dm
@@ -20,8 +20,8 @@
var/ghetto = FALSE
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
- var/datum/component/mobhook
var/datum/radial_menu/persistent/wiring_gui_menu
+ var/mob/listeningTo
/obj/item/twohanded/rcl/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/cable_coil))
@@ -86,7 +86,7 @@
/obj/item/twohanded/rcl/Destroy()
QDEL_NULL(loaded)
last = null
- QDEL_NULL(mobhook)
+ listeningTo = null
QDEL_NULL(wiring_gui_menu)
return ..()
@@ -141,9 +141,8 @@
/obj/item/twohanded/rcl/dropped(mob/wearer)
..()
- if(mobhook)
- active = FALSE
- QDEL_NULL(mobhook)
+ UnregisterSignal(wearer, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
last = null
/obj/item/twohanded/rcl/attack_self(mob/user)
@@ -158,13 +157,12 @@
break
obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
- if(to_hook)
- if(mobhook && mobhook.parent != to_hook)
- QDEL_NULL(mobhook)
- if (!mobhook)
- mobhook = to_hook.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/trigger)))
- else
- QDEL_NULL(mobhook)
+ if(listeningTo == to_hook)
+ return
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ RegisterSignal(to_hook, COMSIG_MOVABLE_MOVED, .proc/trigger)
+ listeningTo = to_hook
/obj/item/twohanded/rcl/proc/trigger(mob/user)
if(active)
diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm
index 699efaac2e..10fbab56be 100644
--- a/code/game/objects/items/blueprints.dm
+++ b/code/game/objects/items/blueprints.dm
@@ -153,7 +153,9 @@
/area/centcom,
/area/asteroid,
/area/tdome,
- /area/wizard_station
+ /area/wizard_station,
+ /area/hilbertshotel,
+ /area/hilbertshotelstorage
)
for (var/type in SPECIALS)
if ( istype(A,type) )
diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm
index ea72197cf0..f0d20afbbd 100644
--- a/code/game/objects/items/body_egg.dm
+++ b/code/game/objects/items/body_egg.dm
@@ -45,8 +45,8 @@
RemoveInfectionImages()
AddInfectionImages()
-/obj/item/organ/body_egg/proc/AddInfectionImages()
+/obj/item/organ/body_egg/proc/AddInfectionImages(mob/living/carbon/C)
return
-/obj/item/organ/body_egg/proc/RemoveInfectionImages()
+/obj/item/organ/body_egg/proc/RemoveInfectionImages(mob/living/carbon/C)
return
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index 05ffcbf2fd..0e422a3fe9 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -80,6 +80,7 @@
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
item_flags = NO_MAT_REDEMPTION | NOBLUDGEON
var/prox_check = TRUE //If the emag requires you to be in range
+ var/uses = 15
/obj/item/card/emag/bluespace
name = "bluespace cryptographic sequencer"
@@ -110,6 +111,37 @@
user.visible_message("[src] fizzles and sparks. It seems like it's out of charges.")
playsound(src, 'sound/effects/light_flicker.ogg', 100, 1)
+/obj/item/card/emag/examine(mob/user)
+ . = ..()
+ to_chat(user, "It has [uses ? uses : "no"] charges left.")
+
+/obj/item/card/emag/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/emagrecharge))
+ var/obj/item/emagrecharge/ER = W
+ if(ER.uses)
+ uses += ER.uses
+ to_chat(user, "You have added [ER.uses] charges to [src]. It now has [uses] charges.")
+ playsound(src, "sparks", 100, 1)
+ ER.uses = 0
+ else
+ to_chat(user, "[ER] has no charges left.")
+ return
+ . = ..()
+
+/obj/item/emagrecharge
+ name = "electromagnet charging device"
+ desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices, sadly this can't be recharged like a normal cell."
+ icon = 'icons/obj/module.dmi'
+ icon_state = "cell_mini"
+ item_flags = NOBLUDGEON
+ var/uses = 5 //Dictates how many charges the device adds to compatible items
+
+/obj/item/emagrecharge/examine(mob/user)
+ . = ..()
+ if(uses)
+ to_chat(user, "It can add up to [uses] charges to compatible devices")
+ else
+ to_chat(user, "It has a small, red, blinking light coming from inside of it. It's spent.")
/obj/item/card/emagfake
desc = "It's a card with a magnetic strip attached to some circuitry. Closer inspection shows that this card is a poorly made replica, with a \"DonkCo\" logo stamped on the back."
@@ -342,12 +374,41 @@ update_label("John Doe", "Clowny")
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
assignment = "Prisoner"
- registered_name = "Scum"
+ access = list(ACCESS_ENTER_GENPOP)
+
+ //Lavaland labor camp
var/goal = 0 //How far from freedom?
var/points = 0
+ //Genpop
+ var/sentence = 0 //When world.time is greater than this number, the card will have its ACCESS_ENTER_GENPOP access replaced with ACCESS_LEAVE_GENPOP the next time it's checked, unless this value is 0/null
+ var/crime= "\[REDACTED\]"
-/obj/item/card/id/prisoner/attack_self(mob/user)
- to_chat(usr, "You have accumulated [points] out of the [goal] points you need for freedom.")
+/obj/item/card/id/prisoner/GetAccess()
+ if((sentence && world.time >= sentence) || (goal && points >= goal))
+ access = list(ACCESS_LEAVE_GENPOP)
+ return ..()
+
+/obj/item/card/id/prisoner/process()
+ if(!sentence)
+ STOP_PROCESSING(SSobj, src)
+ return
+ if(world.time >= sentence)
+ playsound(loc, 'sound/machines/ping.ogg', 50, 1)
+ if(isliving(loc))
+ to_chat(loc, "[src] buzzes: You have served your sentence! You may now exit prison through the turnstiles and collect your belongings.")
+ STOP_PROCESSING(SSobj, src)
+ return
+
+/obj/item/card/id/prisoner/examine(mob/user)
+ . = ..()
+ if(sentence && world.time < sentence)
+ to_chat(user, "You're currently serving a sentence for [crime]. [DisplayTimeText(sentence - world.time)] left.")
+ else if(goal)
+ to_chat(user, "You have accumulated [points] out of the [goal] points you need for freedom.")
+ else if(!sentence)
+ to_chat(user, "You are currently serving a permanent sentence for [crime].")
+ else
+ to_chat(user, "Your sentence is up! You're free!")
/obj/item/card/id/prisoner/one
name = "Prisoner #13-001"
@@ -422,3 +483,58 @@ update_label("John Doe", "Clowny")
name = "APC Access ID"
desc = "A special ID card that allows access to APC terminals."
access = list(ACCESS_ENGINE_EQUIP)
+
+//Polychromatic Knight Badge
+
+/obj/item/card/id/knight
+ var/id_color = "#00FF00" //defaults to green
+ name = "knight badge"
+ icon_state = "knight"
+ desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID"
+
+/obj/item/card/id/knight/update_label(newname, newjob)
+ if(newname || newjob)
+ name = "[(!newname) ? "knight badge" : "[newname]'s Knight Badge"][(!newjob) ? "" : " ([newjob])"]"
+ return
+
+ name = "[(!registered_name) ? "knight badge" : "[registered_name]'s Knight Badge"][(!assignment) ? "" : " ([assignment])"]"
+
+/obj/item/card/id/knight/update_icon()
+ var/mutable_appearance/id_overlay = mutable_appearance(icon, "knight_overlay")
+
+ if(id_color)
+ id_overlay.color = id_color
+ cut_overlays()
+
+ add_overlay(id_overlay)
+
+/obj/item/card/id/knight/AltClick(mob/living/user)
+ . = ..()
+ if(!in_range(src, user)) //Basic checks to prevent abuse
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now!")
+ return
+ if(alert("Are you sure you want to recolor your id?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"","Choose Energy Color",id_color) as color|null
+ if(!in_range(src, user) || !energy_color_input)
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now!")
+ return
+ id_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+/obj/item/card/id/knight/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/item/card/id/knight/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to recolor it.")
+
+/obj/item/card/id/knight/blue
+ id_color = "#0000FF"
+
+/obj/item/card/id/knight/captain
+ id_color = "#FFD700"
\ No newline at end of file
diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm
index 5db5aa416e..911a07c288 100644
--- a/code/game/objects/items/chrono_eraser.dm
+++ b/code/game/objects/items/chrono_eraser.dm
@@ -37,7 +37,7 @@
PA = new(src)
user.put_in_hands(PA)
-/obj/item/chrono_eraser/item_action_slot_check(slot, mob/user)
+/obj/item/chrono_eraser/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_BACK)
return 1
diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm
index 639d570462..1059a310eb 100644
--- a/code/game/objects/items/circuitboards/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm
@@ -31,6 +31,15 @@
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/sheet/glass = 1)
+/obj/item/circuitboard/machine/bloodbankgen
+ name = "Blood Bank Generator (Machine Board)"
+ build_path = /obj/machinery/bloodbankgen
+ req_components = list(
+ /obj/item/stock_parts/matter_bin = 1,
+ /obj/item/stock_parts/manipulator = 1,
+ /obj/item/stack/cable_coil = 5,
+ /obj/item/stack/sheet/glass = 1)
+
/obj/item/circuitboard/machine/clonepod
name = "Clone Pod (Machine Board)"
build_path = /obj/machinery/clonepod
diff --git a/code/game/objects/items/control_wand.dm b/code/game/objects/items/control_wand.dm
index fa4524528b..c98484b81e 100644
--- a/code/game/objects/items/control_wand.dm
+++ b/code/game/objects/items/control_wand.dm
@@ -33,7 +33,7 @@
// Airlock remote works by sending NTNet packets to whatever it's pointed at.
/obj/item/door_remote/afterattack(atom/A, mob/user)
. = ..()
- GET_COMPONENT_FROM(target_interface, /datum/component/ntnet_interface, A)
+ var/datum/component/ntnet_interface/target_interface = A.GetComponent(/datum/component/ntnet_interface)
if(!target_interface)
return
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 102c6a8eed..d014f70315 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -561,7 +561,7 @@
/obj/item/storage/crayons/Initialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 7
STR.can_hold = typecacheof(list(/obj/item/toy/crayon))
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index a4f286bf88..f5799e1a22 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -39,7 +39,6 @@
/obj/item/defibrillator/loaded/Initialize() //starts with hicap
. = ..()
- paddles = make_paddles()
cell = new(src)
update_icon()
return
@@ -193,7 +192,7 @@
remove_paddles(user)
update_icon()
-/obj/item/defibrillator/item_action_slot_check(slot, mob/user)
+/obj/item/defibrillator/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == user.getBackSlot())
return 1
@@ -208,8 +207,8 @@
var/M = get(paddles, /mob)
remove_paddles(M)
QDEL_NULL(paddles)
- . = ..()
- update_icon()
+ QDEL_NULL(cell)
+ return ..()
/obj/item/defibrillator/proc/deductcharge(chrgdeductamt)
if(cell)
@@ -244,13 +243,12 @@
w_class = WEIGHT_CLASS_NORMAL
slot_flags = ITEM_SLOT_BELT
-/obj/item/defibrillator/compact/item_action_slot_check(slot, mob/user)
+/obj/item/defibrillator/compact/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == user.getBeltSlot())
return TRUE
/obj/item/defibrillator/compact/loaded/Initialize()
. = ..()
- paddles = make_paddles()
cell = new(src)
update_icon()
@@ -262,7 +260,6 @@
/obj/item/defibrillator/compact/combat/loaded/Initialize()
. = ..()
- paddles = make_paddles()
cell = new /obj/item/stock_parts/cell/infinite(src)
update_icon()
@@ -297,31 +294,28 @@
var/grab_ghost = FALSE
var/tlimit = DEFIB_TIME_LIMIT * 10
- var/datum/component/mobhook
+ var/mob/listeningTo
/obj/item/twohanded/shockpaddles/equipped(mob/user, slot)
. = ..()
- if(req_defib)
- if (mobhook && mobhook.parent != user)
- QDEL_NULL(mobhook)
- if (!mobhook)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/check_range)))
+ if(!req_defib)
+ return
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/check_range)
/obj/item/twohanded/shockpaddles/Moved()
. = ..()
check_range()
/obj/item/twohanded/shockpaddles/proc/check_range()
- if(!req_defib)
+ if(!req_defib || !defib)
return
if(!in_range(src,defib))
var/mob/living/L = loc
if(istype(L))
to_chat(L, "[defib]'s paddles overextend and come out of your hands!")
- L.temporarilyRemoveItemFromInventory(src,TRUE)
else
visible_message("[src] snap back into [defib].")
- snap_back()
+ snap_back()
/obj/item/twohanded/shockpaddles/proc/recharge(var/time)
if(req_defib || !time)
@@ -362,14 +356,14 @@
/obj/item/twohanded/shockpaddles/dropped(mob/user)
if(!req_defib)
return ..()
- if (mobhook)
- QDEL_NULL(mobhook)
if(user)
+ UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
var/obj/item/twohanded/offhand/O = user.get_inactive_held_item()
if(istype(O))
O.unwield()
- to_chat(user, "The paddles snap back into the main unit.")
- snap_back()
+ if(user != loc)
+ to_chat(user, "The paddles snap back into the main unit.")
+ snap_back()
return unwield(user)
/obj/item/twohanded/shockpaddles/proc/snap_back()
diff --git a/code/game/objects/items/devices/PDA/virus_cart.dm b/code/game/objects/items/devices/PDA/virus_cart.dm
index d85c5d72d8..28bc559b93 100644
--- a/code/game/objects/items/devices/PDA/virus_cart.dm
+++ b/code/game/objects/items/devices/PDA/virus_cart.dm
@@ -70,7 +70,7 @@
difficulty++ //if cartridge has manifest access it has extra snowflake difficulty
else
difficulty += 2
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, target)
+ var/datum/component/uplink/hidden_uplink = target.GetComponent(/datum/component/uplink)
if(!target.detonatable || prob(difficulty * 15) || (hidden_uplink))
U.show_message("An error flashes on your [src].", 1)
else
@@ -95,7 +95,7 @@
charges--
var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
to_chat(U, "Virus Sent! The unlock code to the target is: [lock_code]")
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, target)
+ var/datum/component/uplink/hidden_uplink = target.GetComponent(/datum/component/uplink)
if(!hidden_uplink)
hidden_uplink = target.AddComponent(/datum/component/uplink)
hidden_uplink.unlock_code = lock_code
diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm
index f39d2ba0d6..dffbb46cbb 100644
--- a/code/game/objects/items/devices/chameleonproj.dm
+++ b/code/game/objects/items/devices/chameleonproj.dm
@@ -116,7 +116,7 @@
appearance = saved_appearance
if(istype(M.buckled, /obj/vehicle))
var/obj/vehicle/V = M.buckled
- GET_COMPONENT_FROM(VRD, /datum/component/riding, V)
+ var/datum/component/riding/VRD = V.GetComponent(/datum/component/riding)
if(VRD)
VRD.force_dismount(M)
else
diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm
index 90cdd0386c..110676de1b 100644
--- a/code/game/objects/items/devices/geiger_counter.dm
+++ b/code/game/objects/items/devices/geiger_counter.dm
@@ -203,21 +203,25 @@
return TRUE
/obj/item/geiger_counter/cyborg
- var/datum/component/mobhook
+ var/mob/listeningTo
/obj/item/geiger_counter/cyborg/equipped(mob/user)
. = ..()
- if (mobhook && mobhook.parent != user)
- QDEL_NULL(mobhook)
- if (!mobhook)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_ATOM_RAD_ACT = CALLBACK(src, .proc/redirect_rad_act)))
+ if(listeningTo == user)
+ return
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT)
+ RegisterSignal(user, COMSIG_ATOM_RAD_ACT, .proc/redirect_rad_act)
+ listeningTo = user
/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount)
rad_act(amount)
/obj/item/geiger_counter/cyborg/dropped()
. = ..()
- QDEL_NULL(mobhook)
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT)
+ listeningTo = null
#undef RAD_LEVEL_NORMAL
#undef RAD_LEVEL_MODERATE
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 7655654f78..d644e0637e 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -410,7 +410,7 @@ SLIME SCANNER
msg += "Subject is bleeding!\n"
var/blood_percent = round((C.blood_volume / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100)
var/blood_type = C.dna.blood_type
- if(blood_id != "blood")//special blood substance
+ if(blood_id != ("blood" || "jellyblood"))//special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm
index 2c234a59ba..fc768cd38e 100644
--- a/code/game/objects/items/devices/traitordevices.dm
+++ b/code/game/objects/items/devices/traitordevices.dm
@@ -195,7 +195,7 @@ effective or pretty fucking useless.
Deactivate()
return
-/obj/item/shadowcloak/item_action_slot_check(slot, mob/user)
+/obj/item/shadowcloak/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_BELT)
return 1
diff --git a/code/game/objects/items/eightball.dm b/code/game/objects/items/eightball.dm
index bdaa716075..9dc3e421fd 100644
--- a/code/game/objects/items/eightball.dm
+++ b/code/game/objects/items/eightball.dm
@@ -206,7 +206,7 @@
switch(action)
if("vote")
var/selected_answer = params["answer"]
- if(!selected_answer in possible_answers)
+ if(!(selected_answer in possible_answers))
return
else
votes[user.ckey] = selected_answer
diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm
index fdb016df38..6ea68bf548 100644
--- a/code/game/objects/items/granters.dm
+++ b/code/game/objects/items/granters.dm
@@ -432,6 +432,14 @@
user.mind.teach_crafting_recipe(crafting_recipe_type)
to_chat(user,"You learned how to make [initial(R.name)].")
+/obj/item/book/granter/crafting_recipe/threads //Durathread crafting book
+ name = "Credible Threads"
+ desc = "A simple book about sewing and usefull clothing crafting with cloth and durathreads."
+ crafting_recipe_types = list(/datum/crafting_recipe/durathread_duffelbag, /datum/crafting_recipe/durathread_toolbelt, /datum/crafting_recipe/durathread_bandolier, /datum/crafting_recipe/durathread_helmet, /datum/crafting_recipe/durathread_vest)
+ icon_state = "tailers_art1"
+ oneuse = FALSE
+ remarks = list("Durathread is cloth thats also fire-resistant?", "Strong threads that can be used with leather for some light weight storage!", "The cloth can withstand a beating it said but not that much...")
+
/obj/item/book/granter/crafting_recipe/cooking_sweets_101 //We start at 101 for 103 and 105
name = "Cooking Desserts 101"
desc = "A cook book that teaches you some more of the newest desserts. AI approved, and a best seller on Honkplanet."
diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm
index 709fedbe5a..1956a1f317 100644
--- a/code/game/objects/items/grenades/plastic.dm
+++ b/code/game/objects/items/grenades/plastic.dm
@@ -174,6 +174,7 @@
gender = PLURAL
var/open_panel = 0
can_attach_mob = TRUE
+ full_damage_on_mobs = TRUE
/obj/item/grenade/plastic/c4/New()
wires = new /datum/wires/explosive/c4(src)
diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm
index 3be57d23f1..7e7dddefb6 100644
--- a/code/game/objects/items/his_grace.dm
+++ b/code/game/objects/items/his_grace.dm
@@ -29,7 +29,7 @@
. = ..()
START_PROCESSING(SSprocessing, src)
GLOB.poi_list += src
- AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_POST_THROW = CALLBACK(src, .proc/move_gracefully)))
+ RegisterSignal(src, COMSIG_MOVABLE_POST_THROW, .proc/move_gracefully)
/obj/item/his_grace/Destroy()
STOP_PROCESSING(SSprocessing, src)
diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm
index e7b55d53f5..0786172f25 100644
--- a/code/game/objects/items/implants/implant.dm
+++ b/code/game/objects/items/implants/implant.dm
@@ -89,11 +89,12 @@
return TRUE
/obj/item/implant/proc/removed(mob/living/source, silent = FALSE, special = 0)
+ SEND_SIGNAL(src, COMSIG_IMPLANT_REMOVING, args)
imp_in = null
source.implants -= src
for(var/X in actions)
var/datum/action/A = X
- A.Grant(source)
+ A.Remove(source)
if(ishuman(source))
var/mob/living/carbon/human/H = source
H.sec_hud_set_implants()
diff --git a/code/game/objects/items/implants/implant_storage.dm b/code/game/objects/items/implants/implant_storage.dm
index 739873af00..1f44b5318e 100644
--- a/code/game/objects/items/implants/implant_storage.dm
+++ b/code/game/objects/items/implants/implant_storage.dm
@@ -21,7 +21,7 @@
for(var/X in target.implants)
if(istype(X, type))
var/obj/item/implant/storage/imp_e = X
- GET_COMPONENT_FROM(STR, /datum/component/storage, imp_e.pocket)
+ var/datum/component/storage/STR = imp_e.pocket.GetComponent(/datum/component/storage)
if(!STR || (STR && STR.max_items < max_slot_stacking))
imp_e.pocket.AddComponent(/datum/component/storage/concrete/implant)
qdel(src)
diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm
index 02d0a1c36a..6ae34e9ca2 100644
--- a/code/game/objects/items/manuals.dm
+++ b/code/game/objects/items/manuals.dm
@@ -244,7 +244,7 @@
..()
/obj/item/book/manual/wiki/proc/initialize_wikibook()
- var/wikiurl = CONFIG_GET(string/wikiurl)
+ var/wikiurl = CONFIG_GET(string/wikiurltg)
if(wikiurl)
dat = {"
@@ -270,13 +270,67 @@
"}
-/obj/item/book/manual/wiki/chemistry
+/obj/item/book/manual/wiki/cit
+ name = "Citadel infobook"
+ icon_state ="book8"
+ author = "Nanotrasen"
+ title = "Citadel infobook"
+ page_link = ""
+ window_size = "1500x800" //Too squashed otherwise
+
+/obj/item/book/manual/wiki/cit/initialize_wikibook()
+ var/wikiurl = CONFIG_GET(string/wikiurl)
+ if(wikiurl)
+ dat = {"
+
+
+
+
+
+
+
You start skimming through the manual...
+
+
+
+
+
+ "}
+
+/obj/item/book/manual/wiki/cit/chemistry
name = "Chemistry Textbook"
icon_state ="chemistrybook"
author = "Nanotrasen"
title = "Chemistry Textbook"
+ page_link = "main/guides/guide_chemistry"
+
+/obj/item/book/manual/wiki/cit/chem_recipies
+ name = "Chemistry Recipies"
+ icon_state ="chemrecibook"
+ author = "Chemcat"
+ title = "Chemistry Recipies"
+ page_link = "main/guides/chem_recipies"
+
+/obj/item/book/manual/wiki/chemistry
+ name = "Outdated Chemistry Textbook"
+ icon_state ="chemistrybook_old"
+ author = "Nanotrasen"
+ title = "Outdated Chemistry Textbook"
page_link = "Guide_to_chemistry"
+/obj/item/book/manual/wiki/chemistry/Initialize()
+ ..()
+ new /obj/item/book/manual/wiki/cit/chemistry(loc)
+ new /obj/item/book/manual/wiki/cit/chem_recipies(loc)
+
/obj/item/book/manual/wiki/engineering_construction
name = "Station Repairs and Construction"
icon_state ="bookEngineering"
diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm
index 57b9973aa3..624dbdd8ef 100644
--- a/code/game/objects/items/melee/energy.dm
+++ b/code/game/objects/items/melee/energy.dm
@@ -233,3 +233,152 @@
desc = "An extremely sharp blade made out of hard light. Packs quite a punch."
icon_state = "lightblade"
item_state = "lightblade"
+
+/*/////////////////////////////////////////////////////////////////////////
+///////////// The TRUE Energy Sword ///////////////////////////
+*//////////////////////////////////////////////////////////////////////////
+
+/obj/item/melee/transforming/energy/sword/cx
+ name = "non-eutactic blade"
+ desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable."
+ icon_state = "cxsword_hilt"
+ item_state = "cxsword"
+ force = 3
+ force_on = 21
+ throwforce = 5
+ throwforce_on = 20
+ hitsound = "swing_hit" //it starts deactivated
+ hitsound_on = 'sound/weapons/nebhit.ogg'
+ attack_verb_off = list("tapped", "poked")
+ throw_speed = 3
+ throw_range = 5
+ sharpness = IS_SHARP
+ embedding = list("embedded_pain_multiplier" = 6, "embed_chance" = 20, "embedded_fall_chance" = 60)
+ armour_penetration = 10
+ block_chance = 35
+ light_color = "#37FFF7"
+ actions_types = list()
+
+/obj/item/melee/transforming/energy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
+ altafterattack(A, user, TRUE, params)
+ return TRUE
+
+/obj/item/melee/transforming/energy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
+ if(istype(user))
+ user.visible_message("[user] points the tip of [src] at [target].", "You point the tip of [src] at [target].")
+ return TRUE
+
+/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text)
+ active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE
+ if(active) //also I'd need to rip out the iconstate changing bits
+ force = force_on
+ throwforce = throwforce_on
+ hitsound = hitsound_on
+ throw_speed = 4
+ if(attack_verb_on.len)
+ attack_verb = attack_verb_on
+ w_class = w_class_on
+ START_PROCESSING(SSobj, src)
+ set_light(brightness_on)
+ update_icon()
+ else
+ force = initial(force)
+ throwforce = initial(throwforce)
+ hitsound = initial(hitsound)
+ throw_speed = initial(throw_speed)
+ if(attack_verb_off.len)
+ attack_verb = attack_verb_off
+ w_class = initial(w_class)
+ STOP_PROCESSING(SSobj, src)
+ set_light(0)
+ update_icon()
+ transform_messages(user, supress_message_text)
+ add_fingerprint(user)
+ return TRUE
+
+/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
+ playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1)
+ if(!supress_message_text)
+ to_chat(user, "[src] [active ? "is now active":"can now be concealed"].")
+
+/obj/item/melee/transforming/energy/sword/cx/update_icon()
+ var/mutable_appearance/blade_overlay = mutable_appearance(icon, "cxsword_blade")
+ var/mutable_appearance/gem_overlay = mutable_appearance(icon, "cxsword_gem")
+
+ if(light_color)
+ blade_overlay.color = light_color
+ gem_overlay.color = light_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(gem_overlay)
+
+ if(active)
+ add_overlay(blade_overlay)
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_hands()
+
+/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user)
+ if(!in_range(src, user)) //Basic checks to prevent abuse
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now!")
+ return
+
+ if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
+ if(energy_color_input)
+ light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+ update_light()
+
+/obj/item/melee/transforming/energy/sword/cx/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to recolor it.")
+
+/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(active)
+ if(isinhands)
+ var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
+ blade_inhand.color = light_color
+ . += blade_inhand
+
+//Broken version. Not a toy, but not as strong.
+/obj/item/melee/transforming/energy/sword/cx/broken
+ name = "misaligned non-eutactic blade"
+ desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. This one seems to have a damaged handle and misaligned components, causing the blade to be unstable at best"
+ force_on = 15 //As strong a survival knife/bone dagger
+
+/obj/item/melee/transforming/energy/sword/cx/attackby(obj/item/W, mob/living/user, params)
+ if(istype(W, /obj/item/melee/transforming/energy/sword/cx))
+ if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
+ to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!")
+ return
+ else
+ to_chat(user, "You combine the two light swords, making a single supermassive blade! You're cool.")
+ new /obj/item/twohanded/dualsaber/hypereutactic(user.drop_location())
+ qdel(W)
+ qdel(src)
+ else
+ return ..()
+
+//////// Tatortot NEB /////////////// (same stats as regular esword)
+/obj/item/melee/transforming/energy/sword/cx/traitor
+ name = "\improper Dragon's Tooth Sword"
+ desc = "The Dragon's Tooth sword is a blackmarket modification of a Non-Eutactic Blade, \
+ which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \
+ It appears to have a wooden grip and a shaved down guard."
+ icon_state = "cxsword_hilt_traitor"
+ force_on = 30
+ armour_penetration = 50
+ embedding = list("embedded_pain_multiplier" = 10, "embed_chance" = 75, "embedded_fall_chance" = 0, "embedded_impact_pain_multiplier" = 10)
+ block_chance = 50
+ hitsound_on = 'sound/weapons/blade1.ogg'
+ light_color = "#37F0FF"
+
+/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text)
+ playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1)
+ if(!supress_message_text)
+ to_chat(user, "[src] [active ? "is now active":"can now be concealed"].")
diff --git a/code/game/objects/items/melee/transforming.dm b/code/game/objects/items/melee/transforming.dm
index aabb930bb2..850810bdb2 100644
--- a/code/game/objects/items/melee/transforming.dm
+++ b/code/game/objects/items/melee/transforming.dm
@@ -69,7 +69,7 @@
var/datum/component/butchering/BT = LoadComponent(/datum/component/butchering)
BT.butchering_enabled = TRUE
else
- GET_COMPONENT(BT, /datum/component/butchering)
+ var/datum/component/butchering/BT = GetComponent(/datum/component/butchering)
if(BT)
BT.butchering_enabled = FALSE
transform_messages(user, supress_message_text)
diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm
index 7524fc9007..3f7fe7ee8d 100644
--- a/code/game/objects/items/mop.dm
+++ b/code/game/objects/items/mop.dm
@@ -27,6 +27,7 @@
/obj/item/mop/proc/clean(turf/A)
if(reagents.has_reagent("water", 1) || reagents.has_reagent("holywater", 1) || reagents.has_reagent("vodka", 1) || reagents.has_reagent("cleaner", 1))
SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
+ A.clean_blood()
for(var/obj/effect/O in A)
if(is_cleanable(O))
qdel(O)
diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm
index a73be6e12e..30442d7304 100644
--- a/code/game/objects/items/pet_carrier.dm
+++ b/code/game/objects/items/pet_carrier.dm
@@ -122,7 +122,7 @@
if(user.mob_size <= MOB_SIZE_SMALL)
to_chat(user, "You poke a limb through [src]'s bars and start fumbling for the lock switch... (This will take some time.)")
to_chat(loc, "You see [user] reach through the bars and fumble for the lock switch!")
- if(!do_after(user, rand(300, 400), target = user) || open || !locked || !user in occupants)
+ if(!do_after(user, rand(300, 400), target = user) || open || !locked || !(user in occupants))
return
loc.visible_message("[user] flips the lock switch on [src] by reaching through!", null, null, null, user)
to_chat(user, "Bingo! The lock pops open!")
@@ -132,7 +132,7 @@
else
loc.visible_message("[src] starts rattling as something pushes against the door!", null, null, null, user)
to_chat(user, "You start pushing out of [src]... (This will take about 20 seconds.)")
- if(!do_after(user, 200, target = user) || open || !locked || !user in occupants)
+ if(!do_after(user, 200, target = user) || open || !locked || !(user in occupants))
return
loc.visible_message("[user] shoves out of [src]!", null, null, null, user)
to_chat(user, "You shove open [src]'s door against the lock's resistance and fall out!")
@@ -185,7 +185,7 @@
occupant_weight += occupant.mob_size
/obj/item/pet_carrier/proc/remove_occupant(mob/living/occupant, turf/new_turf)
- if(!occupant in occupants || !istype(occupant))
+ if(!(occupant in occupants) || !istype(occupant))
return
occupant.forceMove(new_turf ? new_turf : drop_location())
occupants -= occupant
diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm
index 8582725cda..7b3dcb1e00 100644
--- a/code/game/objects/items/religion.dm
+++ b/code/game/objects/items/religion.dm
@@ -82,14 +82,6 @@
/obj/item/banner/security/mundane
inspiration_available = FALSE
-/datum/crafting_recipe/security_banner
- name = "Securistan Banner"
- result = /obj/item/banner/security/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/security = 1)
- category = CAT_MISC
-
/obj/item/banner/medical
name = "meditopia banner"
desc = "The banner of Meditopia, generous benefactors that cure wounds and shelter the weak."
@@ -103,14 +95,6 @@
/obj/item/banner/medical/check_inspiration(mob/living/carbon/human/H)
return H.stat //Meditopia is moved to help those in need
-/datum/crafting_recipe/medical_banner
- name = "Meditopia Banner"
- result = /obj/item/banner/medical/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/medical = 1)
- category = CAT_MISC
-
/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H)
H.adjustToxLoss(-15)
H.setOxyLoss(0)
@@ -129,14 +113,6 @@
/obj/item/banner/science/check_inspiration(mob/living/carbon/human/H)
return H.on_fire //Sciencia is pleased by dedication to the art of Toxins
-/datum/crafting_recipe/science_banner
- name = "Sciencia Banner"
- result = /obj/item/banner/science/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/scientist = 1)
- category = CAT_MISC
-
/obj/item/banner/cargo
name = "cargonia banner"
desc = "The banner of the eternal Cargonia, with the mystical power of conjuring any object into existence."
@@ -147,14 +123,6 @@
/obj/item/banner/cargo/mundane
inspiration_available = FALSE
-/datum/crafting_recipe/cargo_banner
- name = "Cargonia Banner"
- result = /obj/item/banner/cargo/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/cargotech = 1)
- category = CAT_MISC
-
/obj/item/banner/engineering
name = "engitopia banner"
desc = "The banner of Engitopia, wielders of limitless power."
@@ -168,14 +136,6 @@
/obj/item/banner/engineering/special_inspiration(mob/living/carbon/human/H)
H.radiation = 0
-/datum/crafting_recipe/engineering_banner
- name = "Engitopia Banner"
- result = /obj/item/banner/engineering/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/engineer = 1)
- category = CAT_MISC
-
/obj/item/banner/command
name = "command banner"
desc = "The banner of Command, a staunch and ancient line of bueraucratic kings and queens."
@@ -189,14 +149,6 @@
/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H)
return HAS_TRAIT(H, TRAIT_MINDSHIELD) //Command is stalwart but rewards their allies.
-/datum/crafting_recipe/command_banner
- name = "Command Banner"
- result = /obj/item/banner/command/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/captainparade = 1)
- category = CAT_MISC
-
/obj/item/banner/red
name = "red banner"
icon_state = "banner-red"
@@ -216,7 +168,7 @@
/obj/item/storage/backpack/bannerpack/Initialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times.
/obj/item/storage/backpack/bannerpack/red
@@ -286,7 +238,6 @@
var/staffcooldown = 0
var/staffwait = 30
-
/obj/item/godstaff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(staffcooldown + staffwait > world.time)
@@ -332,19 +283,16 @@
heat_protection = FEET
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
-
/obj/item/clothing/shoes/plate/red
icon_state = "crusader-red"
/obj/item/clothing/shoes/plate/blue
icon_state = "crusader-blue"
-
/obj/item/storage/box/itemset/crusader
name = "Crusader's Armour Set" //i can't into ck2 references
desc = "This armour is said to be based on the armor of kings on another world thousands of years ago, who tended to assassinate, conspire, and plot against everyone who tried to do the same to them. Some things never change."
-
/obj/item/storage/box/itemset/crusader/blue/New()
..()
contents = list()
@@ -354,7 +302,6 @@
new /obj/item/clothing/gloves/plate/blue(src)
new /obj/item/clothing/shoes/plate/blue(src)
-
/obj/item/storage/box/itemset/crusader/red/New()
..()
contents = list()
@@ -364,7 +311,6 @@
new /obj/item/clothing/gloves/plate/red(src)
new /obj/item/clothing/shoes/plate/red(src)
-
/obj/item/claymore/weak
desc = "This one is rusted."
force = 30
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 9c929a6ebf..2356319cd7 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -680,7 +680,7 @@
action_icon_state = "Chevron_State_0"
var/currentState = 0
- var/maxReduction = 2
+ var/maxReduction = 1
/obj/effect/proc_holder/silicon/cyborg/vtecControl/Click(mob/living/silicon/robot/user)
@@ -688,14 +688,14 @@
currentState = (currentState + 1) % 3
- if(usr)
+ if(istype(self))
switch(currentState)
if (0)
- self.speed = maxReduction
+ self.speed = initial(self.speed)
if (1)
- self.speed -= maxReduction*0.5
+ self.speed = initial(self.speed) - maxReduction * 0.5
if (2)
- self.speed -= maxReduction*1.25
+ self.speed = initial(self.speed) - maxReduction * 1
action.button_icon_state = "Chevron_State_[currentState]"
action.UpdateButtonIcon()
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 5610cbad9a..886997eab9 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -17,7 +17,6 @@
var/self_delay = 50
/obj/item/stack/medical/attack(mob/living/M, mob/user)
-
if(M.stat == DEAD && !stop_bleeding)
var/t_him = "it"
if(M.gender == MALE)
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 155d1f1643..7654199cf5 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -390,9 +390,9 @@
. = ..()
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
- add_blood_DNA(from.return_blood_DNA())
- add_fingerprint_list(from.return_fingerprints())
- add_hiddenprint_list(from.return_hiddenprints())
+ blood_DNA = from.blood_DNA
+ fingerprints = from.fingerprints
+ fingerprintshidden = from.fingerprintshidden
fingerprintslast = from.fingerprintslast
//TODO bloody overlay
@@ -437,4 +437,4 @@
/datum/stack_recipe_list/New(title, recipes)
src.title = title
- src.recipes = recipes
+ src.recipes = recipes
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/telecrystal.dm b/code/game/objects/items/stacks/telecrystal.dm
index 7c34ae87bf..9b5ca2b066 100644
--- a/code/game/objects/items/stacks/telecrystal.dm
+++ b/code/game/objects/items/stacks/telecrystal.dm
@@ -13,7 +13,7 @@
var/mob/living/L = user
for(var/obj/item/implant/uplink/I in L.implants)
if(I?.imp_in)
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, I)
+ var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink)
if(hidden_uplink)
hidden_uplink.telecrystals += amount
use(amount)
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index ad8c4306a5..a79eb299da 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -23,7 +23,7 @@
/obj/item/storage/backpack/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 21
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_items = 21
@@ -34,7 +34,7 @@
/obj/item/storage/backpack/old/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 12
/obj/item/storage/backpack/holding
@@ -58,7 +58,7 @@
/obj/item/storage/backpack/holding/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.allow_big_nesting = TRUE
STR.max_w_class = WEIGHT_CLASS_GIGANTIC
STR.max_combined_w_class = 35
@@ -87,7 +87,7 @@
/obj/item/storage/backpack/santabag/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 60
@@ -260,7 +260,7 @@
/obj/item/storage/backpack/satchel/bone/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 20
STR.max_items = 15
@@ -286,7 +286,7 @@
/obj/item/storage/backpack/satchel/flat/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 6
STR.cant_hold = typecacheof(list(/obj/item/storage/backpack/satchel/flat)) //muh recursive backpacks
@@ -338,7 +338,7 @@
/obj/item/storage/backpack/duffelbag/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 30
/obj/item/storage/backpack/duffelbag/captain
@@ -444,7 +444,7 @@
/obj/item/storage/backpack/duffelbag/syndie/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.silent = TRUE
/obj/item/storage/backpack/duffelbag/syndie/hitman
@@ -594,7 +594,7 @@
// For ClownOps.
/obj/item/storage/backpack/duffelbag/clown/syndie/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
slowdown = 0
STR.silent = TRUE
diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm
index 232d1bd5c9..13efe72686 100644
--- a/code/game/objects/items/storage/bags.dm
+++ b/code/game/objects/items/storage/bags.dm
@@ -21,7 +21,7 @@
/obj/item/storage/bag/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.allow_quick_gather = TRUE
STR.allow_quick_empty = TRUE
STR.display_numerical_stacking = TRUE
@@ -44,7 +44,7 @@
/obj/item/storage/bag/trash/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.max_combined_w_class = 30
STR.max_items = 30
@@ -85,7 +85,7 @@
/obj/item/storage/bag/trash/bluespace/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 60
STR.max_items = 60
@@ -105,12 +105,12 @@
w_class = WEIGHT_CLASS_NORMAL
component_type = /datum/component/storage/concrete/stack
var/spam_protection = FALSE //If this is TRUE, the holder won't receive any messages when they fail to pick up ore through crossing it
- var/datum/component/mobhook
+ var/mob/listeningTo
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/bag/ore/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.allow_quick_empty = TRUE
STR.can_hold = typecacheof(list(/obj/item/stack/ore))
STR.max_w_class = WEIGHT_CLASS_HUGE
@@ -118,15 +118,17 @@
/obj/item/storage/bag/ore/equipped(mob/user)
. = ..()
- if (mobhook && mobhook.parent != user)
- QDEL_NULL(mobhook)
- if (!mobhook)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/Pickup_ores)))
+ if(listeningTo == user)
+ return
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/Pickup_ores)
+ listeningTo = user
/obj/item/storage/bag/ore/dropped()
. = ..()
- if (mobhook)
- QDEL_NULL(mobhook)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
/obj/item/storage/bag/ore/proc/Pickup_ores(mob/living/user)
var/show_message = FALSE
@@ -136,7 +138,7 @@
return
if (istype(user.pulling, /obj/structure/ore_box))
box = user.pulling
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
if(STR)
for(var/A in tile)
if (!is_type_in_typecache(A, STR.can_hold))
@@ -166,7 +168,7 @@
/obj/item/storage/bag/ore/cyborg/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.allow_quick_empty = TRUE
STR.can_hold = typecacheof(list(/obj/item/stack/ore))
STR.max_w_class = WEIGHT_CLASS_HUGE
@@ -178,7 +180,7 @@
/obj/item/storage/bag/ore/large/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.allow_quick_empty = TRUE
STR.can_hold = typecacheof(list(/obj/item/stack/ore))
STR.max_w_class = WEIGHT_CLASS_HUGE
@@ -191,7 +193,7 @@
/obj/item/storage/bag/ore/holding/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.max_items = INFINITY
STR.max_combined_w_class = INFINITY
STR.max_combined_stack_amount = INFINITY
@@ -209,7 +211,7 @@
/obj/item/storage/bag/plants/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 100
STR.max_items = 100
@@ -249,7 +251,7 @@
/obj/item/storage/bag/sheetsnatcher/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.allow_quick_empty = TRUE
STR.can_hold = typecacheof(list(/obj/item/stack/sheet))
STR.cant_hold = typecacheof(list(/obj/item/stack/sheet/mineral/sandstone, /obj/item/stack/sheet/mineral/wood))
@@ -266,7 +268,7 @@
/obj/item/storage/bag/sheetsnatcher/borg/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.max_combined_stack_amount = 500
// -----------------------------
@@ -283,7 +285,7 @@
/obj/item/storage/bag/books/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 21
STR.max_items = 7
@@ -308,15 +310,14 @@
/obj/item/storage/bag/tray/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.insert_preposition = "on"
/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user)
. = ..()
// Drop all the things. All of them.
var/list/obj/item/oldContents = contents.Copy()
- GET_COMPONENT(STR, /datum/component/storage)
- STR.quick_empty()
+ SEND_SIGNAL(src, COMSIG_TRY_STORAGE_QUICK_EMPTY)
// Make each item scatter a bit
for(var/obj/item/I in oldContents)
spawn()
@@ -362,11 +363,11 @@
/obj/item/storage/bag/chemistry/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 200
STR.max_items = 50
STR.insert_preposition = "in"
- STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle))
+ STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/syringe/dart))
/*
* Biowaste bag (mostly for xenobiologists)
@@ -382,7 +383,7 @@
/obj/item/storage/bag/bio/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 200
STR.max_items = 25
STR.insert_preposition = "in"
@@ -397,6 +398,6 @@
/obj/item/storage/bag/bio/holding/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = INFINITY
STR.max_items = 100
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index a2b497cc07..713dbe4133 100755
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -44,7 +44,7 @@
/obj/item/storage/belt/utility/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
var/static/list/can_hold = typecacheof(list(
/obj/item/crowbar,
/obj/item/screwdriver,
@@ -127,7 +127,7 @@
/obj/item/storage/belt/medical/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.can_hold = typecacheof(list(
/obj/item/healthanalyzer,
@@ -199,7 +199,7 @@
/obj/item/storage/belt/security/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 5
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.can_hold = typecacheof(list(
@@ -238,7 +238,7 @@
/obj/item/storage/belt/mining/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 20
@@ -297,7 +297,7 @@
/obj/item/storage/belt/mining/primitive/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 5
/obj/item/storage/belt/soulstone
@@ -308,7 +308,7 @@
/obj/item/storage/belt/soulstone/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(
/obj/item/soulstone
@@ -331,7 +331,7 @@
/obj/item/storage/belt/champion/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 1
STR.can_hold = list(
/obj/item/clothing/mask/luchador
@@ -346,7 +346,7 @@
/obj/item/storage/belt/military/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
/obj/item/storage/belt/military/snack
@@ -359,7 +359,7 @@
/obj/item/storage/belt/military/snack/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.can_hold = typecacheof(list(
@@ -427,7 +427,7 @@
/obj/item/storage/belt/military/assault/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
/obj/item/storage/belt/durathread
@@ -480,7 +480,7 @@
/obj/item/storage/belt/grenade/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 30
STR.display_numerical_stacking = TRUE
STR.max_combined_w_class = 60
@@ -533,7 +533,7 @@
/obj/item/storage/belt/wands/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(
/obj/item/gun/magic/wand
@@ -559,7 +559,7 @@
/obj/item/storage/belt/janitor/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.max_w_class = WEIGHT_CLASS_BULKY // Set to this so the light replacer can fit.
STR.can_hold = typecacheof(list(
@@ -586,7 +586,7 @@
/obj/item/storage/belt/bandolier/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 18
STR.display_numerical_stacking = TRUE
STR.can_hold = typecacheof(list(
@@ -602,7 +602,7 @@
/obj/item/storage/belt/bandolier/durathread/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 32
STR.display_numerical_stacking = TRUE
STR.can_hold = typecacheof(list(
@@ -617,9 +617,12 @@
/obj/item/storage/belt/medolier/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 15
STR.display_numerical_stacking = FALSE
+ STR.allow_quick_gather = TRUE
+ STR.allow_quick_empty = TRUE
+ STR.click_gather = TRUE
STR.can_hold = typecacheof(list(
/obj/item/reagent_containers/syringe/dart
))
@@ -628,6 +631,25 @@
for(var/i in 1 to 16)
new /obj/item/reagent_containers/syringe/dart/(src)
+/obj/item/storage/belt/medolier/afterattack(obj/target, mob/user , proximity)
+ if(!(istype(target, /obj/item/reagent_containers/glass/beaker)))
+ return
+ if(!proximity)
+ return
+ if(!target.reagents)
+ return
+
+ for(var/obj/item/reagent_containers/syringe/dart/D in contents)
+ if(round(target.reagents.total_volume, 1) <= 0)
+ to_chat(user, "You soak as many of the darts as you can with the contents from [target].")
+ return
+ if(D.mode == SYRINGE_INJECT)
+ continue
+
+ D.afterattack(target, user, proximity)
+
+ ..()
+
/obj/item/storage/belt/holster
name = "shoulder holster"
desc = "A holster to carry a handgun and ammo. WARNING: Badasses only."
@@ -637,7 +659,7 @@
/obj/item/storage/belt/holster/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 3
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.can_hold = typecacheof(list(
@@ -661,7 +683,7 @@
/obj/item/storage/belt/fannypack/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 3
STR.max_w_class = WEIGHT_CLASS_SMALL
@@ -728,7 +750,7 @@
/obj/item/storage/belt/sabre/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 1
STR.rustle_sound = FALSE
STR.max_w_class = WEIGHT_CLASS_BULKY
diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm
index 85a06f0c1e..c658eee3d5 100644
--- a/code/game/objects/items/storage/book.dm
+++ b/code/game/objects/items/storage/book.dm
@@ -11,7 +11,7 @@
/obj/item/storage/book/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 1
/obj/item/storage/book/attack_self(mob/user)
diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm
index dd6a6b8453..dde0e0715b 100644
--- a/code/game/objects/items/storage/boxes.dm
+++ b/code/game/objects/items/storage/boxes.dm
@@ -398,7 +398,7 @@
/obj/item/storage/box/donkpockets/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/donkpocket))
/obj/item/storage/box/donkpockets/PopulateContents()
@@ -413,7 +413,7 @@
/obj/item/storage/box/monkeycubes/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 7
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/monkeycube))
@@ -568,7 +568,7 @@
/obj/item/storage/box/snappops/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.can_hold = typecacheof(list(/obj/item/toy/snappop))
STR.max_items = 8
@@ -586,7 +586,7 @@
/obj/item/storage/box/matches/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 10
STR.can_hold = typecacheof(list(/obj/item/match))
@@ -609,7 +609,7 @@
/obj/item/storage/box/lights/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 21
STR.can_hold = typecacheof(list(/obj/item/light/tube, /obj/item/light/bulb))
STR.max_combined_w_class = 21
diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm
index ed547bc17d..782ffd3add 100644
--- a/code/game/objects/items/storage/briefcase.dm
+++ b/code/game/objects/items/storage/briefcase.dm
@@ -17,7 +17,7 @@
/obj/item/storage/briefcase/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 21
@@ -48,7 +48,7 @@
/obj/item/storage/briefcase/lawyer/family/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 14
diff --git a/code/game/objects/items/storage/dakis.dm b/code/game/objects/items/storage/dakis.dm
index 08748bf37e..2703581a94 100644
--- a/code/game/objects/items/storage/dakis.dm
+++ b/code/game/objects/items/storage/dakis.dm
@@ -13,7 +13,7 @@
/obj/item/storage/daki/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.max_combined_w_class = 21
STR.max_items = 3
diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm
index 95639918bb..f0a9ad019b 100644
--- a/code/game/objects/items/storage/fancy.dm
+++ b/code/game/objects/items/storage/fancy.dm
@@ -25,7 +25,7 @@
var/fancy_open = FALSE
/obj/item/storage/fancy/PopulateContents()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
for(var/i = 1 to STR.max_items)
new spawn_type(src)
@@ -72,7 +72,7 @@
/obj/item/storage/fancy/donut_box/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/donut))
@@ -93,7 +93,7 @@
/obj/item/storage/fancy/egg_box/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 12
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/egg))
@@ -115,7 +115,7 @@
/obj/item/storage/fancy/candle_box/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 5
/obj/item/storage/fancy/candle_box/attack_self(mob_user)
@@ -138,7 +138,7 @@
/obj/item/storage/fancy/cigarettes/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(/obj/item/clothing/mask/cigarette, /obj/item/lighter))
@@ -276,7 +276,7 @@
/obj/item/storage/fancy/rollingpapers/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 10
STR.can_hold = typecacheof(list(/obj/item/rollingpaper))
@@ -300,7 +300,7 @@
/obj/item/storage/fancy/cigarettes/cigars/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 5
STR.can_hold = typecacheof(list(/obj/item/clothing/mask/cigarette/cigar))
@@ -347,6 +347,6 @@
/obj/item/storage/fancy/heart_box/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 8
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/tinychocolate))
diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm
index 312ef35430..822a1d5011 100644
--- a/code/game/objects/items/storage/firstaid.dm
+++ b/code/game/objects/items/storage/firstaid.dm
@@ -170,7 +170,7 @@
/obj/item/storage/firstaid/tactical/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
/obj/item/storage/firstaid/tactical/PopulateContents()
@@ -200,7 +200,7 @@
/obj/item/storage/pill_bottle/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.allow_quick_gather = TRUE
STR.click_gather = TRUE
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice))
@@ -337,7 +337,7 @@
/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/penis_enlargement(src)
-
+
/obj/item/storage/pill_bottle/breast_enlargement
name = "breast enlargement pills"
desc = "Made by Fermichem - They have a woman with breasts larger than she is on them. The warming states not to take more than 10u at a time."
@@ -363,7 +363,7 @@
/obj/item/storage/belt/organbox/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 16
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 20
diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm
index eeebc6f4c5..1607b19c2f 100644
--- a/code/game/objects/items/storage/lockbox.dm
+++ b/code/game/objects/items/storage/lockbox.dm
@@ -15,7 +15,7 @@
/obj/item/storage/lockbox/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 14
STR.max_items = 4
@@ -101,7 +101,7 @@
/obj/item/storage/lockbox/medal/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.max_items = 10
STR.max_combined_w_class = 20
diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm
index 20dae54a71..8618e4c3ae 100644
--- a/code/game/objects/items/storage/secure.dm
+++ b/code/game/objects/items/storage/secure.dm
@@ -26,7 +26,7 @@
/obj/item/storage/secure/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.max_combined_w_class = 14
@@ -136,7 +136,7 @@
/obj/item/storage/secure/briefcase/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 21
STR.max_w_class = WEIGHT_CLASS_NORMAL
@@ -146,7 +146,7 @@
/obj/item/storage/secure/briefcase/syndie/PopulateContents()
..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
for(var/i = 0, i < STR.max_items - 2, i++)
new /obj/item/stack/spacecash/c1000(src)
@@ -170,7 +170,7 @@
/obj/item/storage/secure/safe/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.cant_hold = typecacheof(list(/obj/item/storage/secure/briefcase))
STR.max_w_class = 8 //??
diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm
index d18212be42..251703f907 100644
--- a/code/game/objects/items/storage/toolbox.dm
+++ b/code/game/objects/items/storage/toolbox.dm
@@ -35,6 +35,8 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/update_icon()
..()
cut_overlays()
+ if(blood_DNA && blood_DNA.len)
+ add_blood_overlay()
if(has_latches)
var/icon/I = icon('icons/obj/storage.dmi', latches)
add_overlay(I)
@@ -122,7 +124,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/syndicate/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.silent = TRUE
/obj/item/storage/toolbox/syndicate/PopulateContents()
@@ -163,7 +165,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/brass/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 28
STR.max_items = 28
@@ -218,7 +220,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/artistic/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 20
STR.max_items = 10
@@ -256,7 +258,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/gold_real/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 40
STR.max_items = 12
diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm
index cf5d685b4a..84ebc28afa 100644
--- a/code/game/objects/items/storage/uplink_kits.dm
+++ b/code/game/objects/items/storage/uplink_kits.dm
@@ -220,7 +220,7 @@
/obj/item/storage/box/syndie_kit/space/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.can_hold = typecacheof(list(/obj/item/clothing/suit/space/syndicate, /obj/item/clothing/head/helmet/space/syndicate))
@@ -244,7 +244,7 @@
/obj/item/storage/box/syndie_kit/chemical/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 14
/obj/item/storage/box/syndie_kit/chemical/PopulateContents()
diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm
index cb5790e45f..7a6899ad15 100644
--- a/code/game/objects/items/storage/wallets.dm
+++ b/code/game/objects/items/storage/wallets.dm
@@ -11,7 +11,7 @@
/obj/item/storage/wallet/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 4
STR.cant_hold = typecacheof(list(/obj/item/screwdriver/power))
STR.can_hold = typecacheof(list(
diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm
index 8f2b85098d..f3be8cefc8 100644
--- a/code/game/objects/items/tanks/watertank.dm
+++ b/code/game/objects/items/tanks/watertank.dm
@@ -24,7 +24,7 @@
/obj/item/watertank/ui_action_click(mob/user)
toggle_mister(user)
-/obj/item/watertank/item_action_slot_check(slot, mob/user)
+/obj/item/watertank/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == user.getBackSlot())
return 1
@@ -341,7 +341,7 @@
/obj/item/reagent_containers/chemtank/ui_action_click()
toggle_injection()
-/obj/item/reagent_containers/chemtank/item_action_slot_check(slot, mob/user)
+/obj/item/reagent_containers/chemtank/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_BACK)
return 1
diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm
index 5fa0624c0a..e16b0dd690 100644
--- a/code/game/objects/items/teleportation.dm
+++ b/code/game/objects/items/teleportation.dm
@@ -187,8 +187,13 @@
user.show_message("\The [src] is recharging!")
return
var/atom/T = L[t1]
+ var/implantcheckmate = FALSE
+ if(isliving(T))
+ var/mob/living/M = T
+ if(!locate(/obj/item/implant/tracking) in M.implants) //The user was too slow and let the target mob's tracking implant expire or get removed.
+ implantcheckmate = TRUE
var/area/A = get_area(T)
- if(A.noteleport)
+ if(A.noteleport || implantcheckmate)
to_chat(user, "\The [src] is malfunctioning.")
return
current_location = get_turf(user) //Recheck.
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 46fabea8b0..638dcd3556 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -276,6 +276,106 @@
/obj/item/toy/sword/getweight()
return (active ? total_mass_on : total_mass) || w_class *1.25
+/obj/item/toy/sword/cx
+ name = "\improper DX Non-Euplastic LightSword"
+ desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up."
+ icon = 'icons/obj/items_and_weapons.dmi'
+ icon_state = "cxsword_hilt"
+ item_state = "cxsword"
+ active = FALSE
+ w_class = WEIGHT_CLASS_SMALL
+ attack_verb = list("poked", "jabbed", "hit")
+ light_color = "#37FFF7"
+ var/light_brightness = 3
+ actions_types = list()
+
+/obj/item/toy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
+ altafterattack(A, user, TRUE, params)
+ return TRUE
+
+/obj/item/toy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
+ if(istype(user))
+ user.visible_message("[user] points the tip of [src] at [target].", "You point the tip of [src] at [target].")
+ return TRUE
+
+/obj/item/toy/sword/cx/attack_self(mob/user)
+ active = !( active )
+
+ if (active)
+ to_chat(user, "You activate the holographic blade with a press of a button.")
+ playsound(user, 'sound/weapons/nebon.ogg', 50, 1)
+ w_class = WEIGHT_CLASS_BULKY
+ attack_verb = list("slashed", "stabbed", "ravaged")
+ set_light(light_brightness)
+ update_icon()
+
+ else
+ to_chat(user, "You deactivate the holographic blade with a press of a button.")
+ playsound(user, 'sound/weapons/neboff.ogg', 50, 1)
+ w_class = WEIGHT_CLASS_SMALL
+ attack_verb = list("poked", "jabbed", "hit")
+ set_light(0)
+ update_icon()
+
+ add_fingerprint(user)
+
+/obj/item/toy/sword/cx/update_icon()
+ var/mutable_appearance/blade_overlay = mutable_appearance(icon, "cxsword_blade")
+ var/mutable_appearance/gem_overlay = mutable_appearance(icon, "cxsword_gem")
+
+ if(light_color)
+ blade_overlay.color = light_color
+ gem_overlay.color = light_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(gem_overlay)
+
+ if(active)
+ add_overlay(blade_overlay)
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_hands()
+
+/obj/item/toy/sword/cx/AltClick(mob/living/user)
+ if(!in_range(src, user)) //Basic checks to prevent abuse
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now!")
+ return
+
+ if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
+ if(energy_color_input)
+ light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+ update_light()
+
+/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(active)
+ if(isinhands)
+ var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
+ blade_inhand.color = light_color
+ . += blade_inhand
+
+/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params)
+ if(istype(W, /obj/item/toy/sword/cx))
+ if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
+ to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!")
+ return
+ else
+ to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool.")
+ new /obj/item/twohanded/dualsaber/hypereutactic/toy(user.loc)
+ qdel(W)
+ qdel(src)
+ else
+ return ..()
+
+/obj/item/toy/sword/cx/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to recolor it.")
+
/*
* Foam armblade
*/
@@ -337,6 +437,30 @@
/obj/item/twohanded/dualsaber/toy/IsReflect()//Stops Toy Dualsabers from reflecting energy projectiles
return FALSE
+/obj/item/twohanded/dualsaber/hypereutactic/toy
+ name = "\improper DX Hyper-Euplastic LightSword"
+ desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up."
+ force = 0
+ throwforce = 0
+ throw_speed = 3
+ throw_range = 5
+ force_unwielded = 0
+ force_wielded = 0
+ attack_verb = list("attacked", "struck", "hit")
+ total_mass_on = TOTAL_MASS_TOY_SWORD
+ slowdown_wielded = 0
+
+/obj/item/twohanded/dualsaber/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ return FALSE
+
+/obj/item/twohanded/dualsaber/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles
+ return FALSE
+
+/obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow
+ name = "\improper Hyper-Euclidean Reciprocating Trigonometric Zweihander"
+ desc = "A custom-built toy with fancy rainbow lights built-in."
+ hacked = TRUE
+
/obj/item/toy/katana
name = "replica katana"
desc = "Woefully underpowered in D20."
diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm
index b1c2c36585..9b2ec5c98f 100644
--- a/code/game/objects/items/twohanded.dm
+++ b/code/game/objects/items/twohanded.dm
@@ -6,6 +6,7 @@
* Spears
* CHAINSAWS
* Bone Axe and Spear
+ * And more
*/
/*##################################################################
@@ -346,7 +347,8 @@
icon_state = "dualsaber[item_color][wielded]"
else
icon_state = "dualsaber0"
- SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+
+ clean_blood()
/obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user)
if(user.has_dna())
@@ -463,6 +465,116 @@
else
return ..()
+/////////////////////////////////////////////////////
+// HYPEREUTACTIC Blades /////////////////////////
+/////////////////////////////////////////////////////
+
+/obj/item/twohanded/dualsaber/hypereutactic
+ icon = 'icons/obj/1x2.dmi'
+ icon_state = "hypereutactic"
+ lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
+ item_state = "hypereutactic"
+ inhand_x_dimension = 64
+ inhand_y_dimension = 64
+ name = "hypereutactic blade"
+ desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter."
+ force = 7
+ force_unwielded = 7
+ force_wielded = 40
+ wieldsound = 'sound/weapons/nebon.ogg'
+ unwieldsound = 'sound/weapons/neboff.ogg'
+ hitsound_on = 'sound/weapons/nebhit.ogg'
+ slowdown_wielded = 1
+ armour_penetration = 60
+ light_color = "#37FFF7"
+ rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00")
+ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded")
+ spinnable = FALSE
+ total_mass_on = 4
+
+/obj/item/twohanded/dualsaber/hypereutactic/chaplain
+ name = "\improper divine lightblade"
+ desc = "A giant blade of bright and holy light, said to cut down the wicked with ease."
+ force = 5
+ force_unwielded = 5
+ force_wielded = 20
+ block_chance = 50
+ armour_penetration = 0
+ var/chaplain_spawnable = TRUE
+ obj_flags = UNIQUE_RENAME
+
+/obj/item/twohanded/dualsaber/hypereutactic/chaplain/Initialize()
+ . = ..()
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE)
+
+/obj/item/twohanded/dualsaber/hypereutactic/chaplain/IsReflect()
+ return FALSE
+
+/obj/item/twohanded/dualsaber/hypereutactic/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
+ altafterattack(A, user, TRUE, params)
+ return TRUE
+
+/obj/item/twohanded/dualsaber/hypereutactic/altafterattack(atom/target, mob/living/user, proximity_flag, click_parameters) //does right click memes
+ if(istype(user))
+ user.visible_message("[user] points the tip of [src] at [target].", "You point the tip of [src] at [target].")
+ return TRUE
+
+/obj/item/twohanded/dualsaber/hypereutactic/update_icon()
+ var/mutable_appearance/blade_overlay = mutable_appearance(icon, "hypereutactic_blade")
+ var/mutable_appearance/gem_overlay = mutable_appearance(icon, "hypereutactic_gem")
+
+ if(light_color)
+ blade_overlay.color = light_color
+ gem_overlay.color = light_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(gem_overlay)
+
+ if(wielded)
+ add_overlay(blade_overlay)
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_hands()
+
+ clean_blood()
+
+/obj/item/twohanded/dualsaber/hypereutactic/AltClick(mob/living/user)
+ if(!user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now!")
+ return
+ if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
+ if(!energy_color_input || !user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
+ return
+ light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+ update_light()
+
+/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(isinhands)
+ var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
+ gem_inhand.color = light_color
+ . += gem_inhand
+ if(wielded)
+ var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade")
+ blade_inhand.color = light_color
+ . += blade_inhand
+
+/obj/item/twohanded/dualsaber/hypereutactic/examine(mob/user)
+ ..()
+ if(!hacked)
+ to_chat(user, "Alt-click to recolor it.")
+
+/obj/item/twohanded/dualsaber/hypereutactic/rainbow_process()
+ . = ..()
+ update_icon()
+ update_light()
+
//spears
/obj/item/twohanded/spear
icon_state = "spearglass0"
@@ -624,7 +736,7 @@
force = on ? force_on : initial(force)
throwforce = on ? force_on : initial(force)
icon_state = "chainsaw_[on ? "on" : "off"]"
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = on
if(on)
@@ -847,18 +959,20 @@
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
- var/datum/component/mobhook
+ var/mob/listeningTo
var/zoom_out_amt = 6
var/zoom_amt = 10
+/obj/item/twohanded/binoculars/Destroy()
+ listeningTo = null
+ return ..()
+
/obj/item/twohanded/binoculars/wield(mob/user)
. = ..()
if(!wielded)
return
- if(QDELETED(mobhook))
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/unwield)))
- else
- user.TakeComponent(mobhook)
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/unwield)
+ listeningTo = user
user.visible_message("[user] holds [src] up to [user.p_their()] eyes.","You hold [src] up to your eyes.")
item_state = "binoculars_wielded"
user.regenerate_icons()
@@ -882,7 +996,8 @@
/obj/item/twohanded/binoculars/unwield(mob/user)
. = ..()
- mobhook.RemoveComponent()
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
user.visible_message("[user] lowers [src].","You lower [src].")
item_state = "binoculars"
user.regenerate_icons()
@@ -891,4 +1006,4 @@
var/client/C = user.client
C.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
- user.client.pixel_y = 0
+ user.client.pixel_y = 0
\ No newline at end of file
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 5f21862c17..7526807eeb 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -8,6 +8,7 @@
var/climbable = FALSE
var/mob/living/structureclimber
var/broken = 0 //similar to machinery's stat BROKEN
+ layer = BELOW_OBJ_LAYER
/obj/structure/Initialize()
if (!armor)
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index edcb4a6181..172120861b 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -4,7 +4,6 @@
icon = 'icons/obj/closet.dmi'
icon_state = "generic"
density = TRUE
- layer = BELOW_OBJ_LAYER
var/icon_door = null
var/icon_door_override = FALSE //override to have open overlay use icon different to its base's
var/secure = FALSE //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights
@@ -615,3 +614,6 @@
user.resting = FALSE
togglelock(user)
T1.visible_message("[user] dives into [src]!")
+
+/obj/structure/closet/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
+ return ..() && opened
diff --git a/code/game/objects/structures/crates_lockers/closets/genpop.dm b/code/game/objects/structures/crates_lockers/closets/genpop.dm
new file mode 100644
index 0000000000..80b64aaedc
--- /dev/null
+++ b/code/game/objects/structures/crates_lockers/closets/genpop.dm
@@ -0,0 +1,117 @@
+/obj/structure/closet/secure_closet/genpop
+ desc = "It's a secure locker for inmates's personal belongings."
+ var/default_desc = "It's a secure locker for the storage inmates's personal belongings during their time in prison."
+ name = "prisoner closet"
+ var/default_name = "prisoner closet"
+ req_access = list(ACCESS_BRIG)
+ var/obj/item/card/id/prisoner/registered_id = null
+ icon_state = "prisoner"
+ locked = FALSE
+ anchored = TRUE
+ opened = TRUE
+ density = FALSE
+
+/obj/structure/closet/secure_closet/genpop/attackby(obj/item/W, mob/user, params)
+ if(!broken && locked && W == registered_id) //Prisoner opening
+ handle_prisoner_id(user)
+ return
+
+ return ..()
+
+/obj/structure/closet/secure_closet/genpop/proc/handle_prisoner_id(mob/user)
+ var/obj/item/card/id/prisoner/prisoner_id = null
+ for(prisoner_id in user.held_items)
+ if(prisoner_id != registered_id)
+ prisoner_id = null
+ else
+ break
+
+ if(!prisoner_id)
+ to_chat(user, "Access Denied.")
+ return FALSE
+
+ qdel(registered_id)
+ registered_id = null
+ locked = FALSE
+ open(user)
+ desc = "It's a secure locker for prisoner effects."
+ to_chat(user, "You insert your prisoner id into \the [src] and it springs open!")
+
+ return TRUE
+
+/obj/structure/closet/secure_closet/genpop/proc/handle_edit_sentence(mob/user)
+ var/prisoner_name = input(user, "Please input the name of the prisoner.", "Prisoner Name", registered_id.registered_name) as text|null
+ if(prisoner_name == null | !user.Adjacent(src))
+ return FALSE
+ var/sentence_length = input(user, "Please input the length of their sentence in minutes (0 for perma).", "Sentence Length", registered_id.sentence) as num|null
+ if(sentence_length == null | !user.Adjacent(src))
+ return FALSE
+ var/crimes = input(user, "Please input their crimes.", "Crimes", registered_id.crime) as text|null
+ if(crimes == null | !user.Adjacent(src))
+ return FALSE
+
+ registered_id.registered_name = prisoner_name
+ var/filteredsentlength = text2num(sentence_length)
+ registered_id.sentence = filteredsentlength ? (filteredsentlength MINUTES) + world.time : 0
+ registered_id.crime = crimes
+ registered_id.update_label(prisoner_name, registered_id.assignment)
+ if(registered_id.sentence)
+ START_PROCESSING(SSobj, registered_id)
+ else
+ STOP_PROCESSING(SSobj, registered_id)
+
+ name = "[default_name] ([prisoner_name])"
+ desc = "[default_desc] It contains the personal effects of [prisoner_name]."
+
+ return TRUE
+
+/obj/structure/closet/secure_closet/genpop/togglelock(mob/living/user)
+ if(!allowed(user))
+ return ..()
+
+ if(!broken && locked && registered_id != null)
+ var/name = registered_id.registered_name
+ var/result = alert(user, "This locker currently contains [name]'s personal belongings ","Locker In Use","Reset","Amend ID", "Open")
+ if(!user.Adjacent(src))
+ return
+ if(result == "Reset")
+ name = default_name
+ desc = default_desc
+ registered_id = null
+ if(result == "Open" | result == "Reset")
+ locked = FALSE
+ open(user)
+ if(result == "Amend ID")
+ handle_edit_sentence(user)
+ else
+ return ..()
+
+/obj/structure/closet/secure_closet/genpop/close(mob/living/user)
+ if(registered_id != null)
+ locked = TRUE
+ return ..()
+
+/obj/structure/closet/secure_closet/genpop/attack_hand(mob/user)
+ if(user.lying && get_dist(src, user) > 0)
+ return
+
+ if(!broken && registered_id != null && registered_id in user.held_items)
+ handle_prisoner_id(user)
+ return
+
+ if(!broken && opened && !locked && allowed(user) && !registered_id) //Genpop setup
+
+ registered_id = new /obj/item/card/id/prisoner/(src.contents)
+ if(handle_edit_sentence(user))
+ close(user)
+ locked = TRUE
+ update_icon()
+ registered_id.forceMove(src.loc)
+ new /obj/item/clothing/under/rank/prisoner(src.loc)
+ else
+ qdel(registered_id)
+ registered_id = null
+
+ return
+
+ ..()
\ No newline at end of file
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index cd87075258..31bf9318ce 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -4,7 +4,6 @@
desc = "A large structural assembly made out of metal; It requires a layer of metal before it can be considered a wall."
anchored = TRUE
density = TRUE
- layer = BELOW_OBJ_LAYER
var/state = GIRDER_NORMAL
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
var/can_displace = TRUE //If the girder can be moved around by wrenching it
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 13ca421daa..5733ea123c 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -6,6 +6,7 @@
density = TRUE
anchored = TRUE
opacity = TRUE
+ layer = CLOSED_DOOR_LAYER
icon = 'icons/obj/doors/mineral_doors.dmi'
icon_state = "metal"
@@ -90,6 +91,7 @@
flick("[initial_state]opening",src)
sleep(10)
density = FALSE
+ layer = OPEN_DOOR_LAYER
state = 1
air_update_turf(1)
update_icon()
@@ -111,6 +113,7 @@
density = TRUE
set_opacity(TRUE)
state = 0
+ layer = initial(layer)
air_update_turf(1)
update_icon()
isSwitchingStates = 0
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index eaf3629718..e7be30520e 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -133,9 +133,11 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
/obj/structure/bodycontainer/proc/close()
playsound(src, 'sound/effects/roll.ogg', 5, 1)
- playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
+ playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
for(var/atom/movable/AM in connected.loc)
if(!AM.anchored || AM == connected)
+ if(ismob(AM) && !isliving(AM))
+ continue
AM.forceMove(src)
recursive_organ_check(src)
update_icon()
@@ -305,7 +307,7 @@ GLOBAL_LIST_EMPTY(crematoriums)
/obj/structure/tray
icon = 'icons/obj/stationobjs.dmi'
density = TRUE
- layer = BELOW_OBJ_LAYER
+ layer = TRAY_LAYER
var/obj/structure/bodycontainer/connected = null
anchored = TRUE
pass_flags = LETPASSTHROW
diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm
index 889cdab388..419502e2b0 100644
--- a/code/game/objects/structures/reflector.dm
+++ b/code/game/objects/structures/reflector.dm
@@ -5,7 +5,6 @@
desc = "A base for reflector assemblies."
anchored = FALSE
density = FALSE
- layer = BELOW_OBJ_LAYER
var/deflector_icon_state
var/image/deflector_overlay
var/finished = FALSE
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index ee46538be1..392c802ed8 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -4,7 +4,6 @@
animate_movement = FORWARD_STEPS
anchored = TRUE
density = TRUE
- layer = BELOW_OBJ_LAYER
var/moving = 0
var/datum/gas_mixture/air_contents = new()
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 46db567b10..76c8f7f11f 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -318,6 +318,7 @@
/obj/machinery/shower/proc/wash_obj(obj/O)
. = SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ . = O.clean_blood()
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
if(isitem(O))
var/obj/item/I = O
@@ -328,8 +329,9 @@
/obj/machinery/shower/proc/wash_turf()
if(isturf(loc))
var/turf/tile = loc
- SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
tile.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
+ tile.clean_blood()
+ SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/obj/effect/E in tile)
if(is_cleanable(E))
qdel(E)
@@ -381,7 +383,8 @@
else if(H.w_uniform && wash_obj(H.w_uniform))
H.update_inv_w_uniform()
if(washgloves)
- SEND_SIGNAL(H, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ H.clean_blood()
+ SEND_SIGNAL(H, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(H.shoes && washshoes && wash_obj(H.shoes))
H.update_inv_shoes()
if(H.wear_mask && washmask && wash_obj(H.wear_mask))
@@ -398,9 +401,11 @@
else
if(M.wear_mask && wash_obj(M.wear_mask))
M.update_inv_wear_mask(0)
- SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ M.clean_blood()
+ SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
else
- SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ L.clean_blood()
+ SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
/obj/machinery/shower/proc/contamination_cleanse(atom/movable/thing)
var/datum/component/radioactive/healthy_green_glow = thing.GetComponent(/datum/component/radioactive)
@@ -498,7 +503,8 @@
H.regenerate_icons()
user.drowsyness = max(user.drowsyness - rand(2,3), 0) //Washing your face wakes you up if you're falling asleep
else
- SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ user.clean_blood()
/obj/structure/sink/attackby(obj/item/O, mob/living/user, params)
if(busy)
@@ -554,7 +560,8 @@
busy = FALSE
return 1
busy = FALSE
- SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ O.clean_blood()
O.acid_level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
@@ -675,4 +682,4 @@
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
- playsound(loc, 'sound/items/welder.ogg', 80, 1)
+ playsound(loc, 'sound/items/welder.ogg', 80, 1)
\ No newline at end of file
diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm
index e441ccd6cc..f1c5080c8f 100644
--- a/code/game/turfs/change_turf.dm
+++ b/code/game/turfs/change_turf.dm
@@ -41,7 +41,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/open/copyTurf(turf/T, copy_air = FALSE)
. = ..()
if (isopenturf(T))
- GET_COMPONENT(slip, /datum/component/wet_floor)
+ var/datum/component/wet_floor/slip = GetComponent(/datum/component/wet_floor)
if(slip)
var/datum/component/wet_floor/WF = T.AddComponent(/datum/component/wet_floor)
WF.InheritComponent(slip)
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index f6d234b346..bd24e0ff93 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -251,6 +251,7 @@
M.apply_water()
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ clean_blood()
for(var/obj/effect/O in src)
if(is_cleanable(O))
qdel(O)
diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm
index 677fba2990..0a7b507488 100644
--- a/code/game/turfs/simulated/chasm.dm
+++ b/code/game/turfs/simulated/chasm.dm
@@ -15,11 +15,11 @@
AddComponent(/datum/component/chasm, SSmapping.get_turf_below(src))
/turf/open/chasm/proc/set_target(turf/target)
- GET_COMPONENT(chasm_component, /datum/component/chasm)
+ var/datum/component/chasm/chasm_component = GetComponent(/datum/component/chasm)
chasm_component.target_turf = target
/turf/open/chasm/proc/drop(atom/movable/AM)
- GET_COMPONENT(chasm_component, /datum/component/chasm)
+ var/datum/component/chasm/chasm_component = GetComponent(/datum/component/chasm)
chasm_component.drop(AM)
/turf/open/chasm/MakeSlippery(wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent)
diff --git a/code/modules/NTNet/services/_service.dm b/code/modules/NTNet/services/_service.dm
index 8611c2d25d..3622dc3881 100644
--- a/code/modules/NTNet/services/_service.dm
+++ b/code/modules/NTNet/services/_service.dm
@@ -17,7 +17,7 @@
/datum/ntnet_service/proc/connect(datum/ntnet/net)
if(!istype(net))
return FALSE
- GET_COMPONENT(interface, /datum/component/ntnet_interface)
+ var/datum/component/ntnet_interface/interface = GetComponent(/datum/component/ntnet_interface)
if(!interface.register_connection(net))
return FALSE
if(!net.register_service(src))
@@ -29,7 +29,7 @@
/datum/ntnet_service/proc/disconnect(datum/ntnet/net, force = FALSE)
if(!istype(net) || (!net.unregister_service(src) && !force))
return FALSE
- GET_COMPONENT(interface, /datum/component/ntnet_interface)
+ var/datum/component/ntnet_interface/interface = GetComponent(/datum/component/ntnet_interface)
interface.unregister_connection(net)
networks_by_id -= net.network_id
return TRUE
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 4e58a9cba5..ce4b8f7e39 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -318,6 +318,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
RemoveActive()
state = AHELP_CLOSED
GLOB.ahelp_tickets.ListInsert(src)
+ to_chat(initiator, "Ticket closed by [usr?.client?.holder?.fakekey? usr.client.holder.fakekey : "an administrator"].")
AddInteraction("Closed by [key_name].")
if(!silent)
SSblackbox.record_feedback("tally", "ahelp_stats", 1, "closed")
@@ -336,7 +337,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
addtimer(CALLBACK(initiator, /client/proc/giveadminhelpverb), 50)
AddInteraction("Resolved by [key_name].")
- to_chat(initiator, "Your ticket has been resolved by an admin. The Adminhelp verb will be returned to you shortly.")
+ to_chat(initiator, "Your ticket has been resolved by [usr?.client?.holder?.fakekey? usr.client.holder.fakekey : "an administrator"]. The Adminhelp verb will be returned to you shortly.")
if(!silent)
SSblackbox.record_feedback("tally", "ahelp_stats", 1, "resolved")
var/msg = "Ticket [TicketHref("#[id]")] resolved by [key_name]"
@@ -353,7 +354,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
SEND_SOUND(initiator, sound('sound/effects/adminhelp.ogg'))
- to_chat(initiator, "- AdminHelp Rejected! -")
+ to_chat(initiator, "- AdminHelp Rejected by [usr?.client?.holder?.fakekey? usr.client.holder.fakekey : "an administrator"]! -")
to_chat(initiator, "Your admin help was rejected. The adminhelp verb has been returned to you so that you may try again.")
to_chat(initiator, "Please try to be calm, clear, and descriptive in admin helps, do not assume the admin has seen any related events, and clearly state the names of anybody you are reporting.")
@@ -369,7 +370,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
if(state != AHELP_ACTIVE)
return
- var/msg = "- AdminHelp marked as IC issue! - "
+ var/msg = "- AdminHelp marked as IC issue by [usr?.client?.holder?.fakekey? usr.client.holder.fakekey : "an administrator"]! - "
msg += "Losing is part of the game! "
msg += "It is also possible that your ahelp is unable to be answered properly, due to events occurring in the round."
if(initiator)
diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm
index 5b74ae7c5b..e70ea1c1b3 100644
--- a/code/modules/admin/verbs/modifyvariables.dm
+++ b/code/modules/admin/verbs/modifyvariables.dm
@@ -534,7 +534,7 @@ GLOBAL_PROTECT(VVpixelmovement)
if (prompt != "Continue")
return FALSE
return TRUE
-
+
/client/proc/modify_variables(atom/O, param_var_name = null, autodetect_class = 0)
if(!check_rights(R_VAREDIT))
@@ -545,7 +545,7 @@ GLOBAL_PROTECT(VVpixelmovement)
var/var_value
if(param_var_name)
- if(!param_var_name in O.vars)
+ if(!(param_var_name in O.vars))
to_chat(src, "A variable with this name ([param_var_name]) doesn't exist in this datum ([O])")
return
variable = param_var_name
diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm
index 0fca957ffe..e8d30e8dbe 100644
--- a/code/modules/antagonists/abductor/abductor.dm
+++ b/code/modules/antagonists/abductor/abductor.dm
@@ -26,7 +26,7 @@
sub_role = "Scientist"
outfit = /datum/outfit/abductor/scientist
landmark_type = /obj/effect/landmark/abductor/scientist
- greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
+ greet_text = "Use your experimental console and surgical equipment to monitor your agent and experiment upon abducted humans."
show_in_antagpanel = TRUE
/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team)
@@ -40,17 +40,18 @@
return team
/datum/antagonist/abductor/on_gain()
- owner.special_role = "[name] [sub_role]"
- owner.assigned_role = "[name] [sub_role]"
- owner.objectives += team.objectives
+ owner.special_role = "[name]"
+ owner.assigned_role = "[name]"
+ objectives += team.objectives
finalize_abductor()
+ ADD_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
return ..()
/datum/antagonist/abductor/on_removal()
- owner.objectives -= team.objectives
if(owner.current)
to_chat(owner.current,"You are no longer the [owner.special_role]!")
owner.special_role = null
+ REMOVE_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
return ..()
/datum/antagonist/abductor/greet()
@@ -64,6 +65,7 @@
//Equip
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/abductor)
+
H.real_name = "[team.name] [sub_role]"
H.equipOutfit(outfit)
@@ -75,11 +77,15 @@
update_abductor_icons_added(owner,"abductor")
-/datum/antagonist/abductor/scientist/finalize_abductor()
- ..()
- var/mob/living/carbon/human/H = owner.current
- var/datum/species/abductor/A = H.dna.species
- A.scientist = TRUE
+/datum/antagonist/abductor/scientist/on_gain()
+ ADD_TRAIT(owner, TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST)
+ ADD_TRAIT(owner, TRAIT_SURGEON, ABDUCTOR_ANTAGONIST)
+ . = ..()
+
+/datum/antagonist/abductor/scientist/on_removal()
+ REMOVE_TRAIT(owner, TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST)
+ REMOVE_TRAIT(owner, TRAIT_SURGEON, ABDUCTOR_ANTAGONIST)
+ . = ..()
/datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin)
var/list/current_teams = list()
@@ -93,8 +99,8 @@
else
return
new_owner.add_antag_datum(src)
- log_admin("[key_name(usr)] made [key_name(new_owner.current)] [name] on [choice]!")
- message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner.current)] [name] on [choice] !")
+ log_admin("[key_name(usr)] made [key_name(new_owner)] [name] on [choice]!")
+ message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner)] [name] on [choice] !")
/datum/antagonist/abductor/get_admin_commands()
. = ..()
@@ -147,7 +153,7 @@
result += "The abductors of [name] were:"
for(var/datum/mind/abductor_mind in members)
result += printplayer(abductor_mind)
- result += printobjectives(abductor_mind)
+ result += printobjectives(objectives)
return "
[result.Join(" ")]
"
@@ -172,7 +178,6 @@
var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
var/datum/objective/abductee/O = new objtype()
objectives += O
- owner.objectives += objectives
/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override)
update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee")
@@ -214,4 +219,4 @@
/datum/antagonist/proc/update_abductor_icons_removed(datum/mind/alien_mind)
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_ABDUCTOR]
hud.leave_hud(alien_mind.current)
- set_antag_hud(alien_mind.current, null)
\ No newline at end of file
+ set_antag_hud(alien_mind.current, null)
diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
index 1573204d88..3d874aac58 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
@@ -55,7 +55,7 @@
var/datum/action/A = X
A.UpdateButtonIcon()
-/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user)
+/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_WEAR_SUIT) //we only give the mob the ability to activate the vest if he's actually wearing it.
return 1
@@ -132,22 +132,26 @@
/obj/item/abductor
icon = 'icons/obj/abductor.dmi'
-/obj/item/abductor/proc/AbductorCheck(user)
- if(isabductor(user))
+/obj/item/abductor/proc/AbductorCheck(mob/user)
+ if(HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING))
+ return TRUE
+ if (istype(user) && user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
return TRUE
to_chat(user, "You can't figure how this works!")
return FALSE
-/obj/item/abductor/proc/ScientistCheck(user)
- if(!AbductorCheck(user))
- return FALSE
+/obj/item/abductor/proc/ScientistCheck(mob/user)
+ var/training = HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
+ var/sci_training = HAS_TRAIT(user, TRAIT_ABDUCTOR_SCIENTIST_TRAINING) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_SCIENTIST_TRAINING))
- var/mob/living/carbon/human/H = user
- var/datum/species/abductor/S = H.dna.species
- if(S.scientist)
- return TRUE
- to_chat(user, "You're not trained to use this!")
- return FALSE
+ if(training && !sci_training)
+ to_chat(user, "You're not trained to use this!")
+ . = FALSE
+ else if(!training && !sci_training)
+ to_chat(user, "You can't figure how this works!")
+ . = FALSE
+ else
+ . = TRUE
/obj/item/abductor/gizmo
name = "science tool"
@@ -683,7 +687,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
desc = "Abduct with style - spiky style. Prevents digital tracking."
icon_state = "alienhelmet"
item_state = "alienhelmet"
- blockTracking = 1
+ blockTracking = TRUE
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
// Operating Table / Beds / Lockers
diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm
index 8e722ec33e..a35cbbf0e4 100644
--- a/code/modules/antagonists/abductor/equipment/gland.dm
+++ b/code/modules/antagonists/abductor/equipment/gland.dm
@@ -5,6 +5,7 @@
icon_state = "gland"
status = ORGAN_ROBOTIC
beating = TRUE
+ var/true_name = "baseline placebo referencer"
var/cooldown_low = 300
var/cooldown_high = 300
var/next_activation = 0
@@ -16,6 +17,11 @@
var/mind_control_duration = 1800
var/active_mind_control = FALSE
+/obj/item/organ/heart/gland/examine(mob/user)
+ . = ..()
+ if((user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)) || isobserver(user))
+ to_chat(user, "It is \a [true_name].")
+
/obj/item/organ/heart/gland/proc/ownerCheck()
if(ishuman(owner))
return TRUE
@@ -42,19 +48,19 @@
/obj/item/organ/heart/gland/proc/mind_control(command, mob/living/user)
if(!ownerCheck() || !mind_control_uses || active_mind_control)
- return
+ return FALSE
mind_control_uses--
to_chat(owner, "You suddenly feel an irresistible compulsion to follow an order...")
to_chat(owner, "[command]")
active_mind_control = TRUE
- log_admin("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
+ message_admins("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
update_gland_hud()
addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration)
/obj/item/organ/heart/gland/proc/clear_mind_control()
if(!ownerCheck() || !active_mind_control)
- return
+ return FALSE
to_chat(owner, "You feel the compulsion fade, and you completely forget about your previous orders.")
active_mind_control = FALSE
@@ -95,6 +101,7 @@
return
/obj/item/organ/heart/gland/heals
+ true_name = "coherency harmonizer"
cooldown_low = 200
cooldown_high = 400
uses = -1
@@ -109,6 +116,7 @@
owner.adjustOxyLoss(-20)
/obj/item/organ/heart/gland/slime
+ true_name = "gastric animation galvanizer"
cooldown_low = 600
cooldown_high = 1200
uses = -1
@@ -130,6 +138,7 @@
Slime.Leader = owner
/obj/item/organ/heart/gland/mindshock
+ true_name = "neural crosstalk uninhibitor"
cooldown_low = 400
cooldown_high = 700
uses = -1
@@ -156,6 +165,7 @@
H.hallucination += 60
/obj/item/organ/heart/gland/pop
+ true_name = "anthropmorphic translocator"
cooldown_low = 900
cooldown_high = 1800
uses = -1
@@ -171,6 +181,7 @@
owner.set_species(species)
/obj/item/organ/heart/gland/ventcrawling
+ true_name = "pliant cartilage enabler"
cooldown_low = 1800
cooldown_high = 2400
uses = 1
@@ -183,6 +194,7 @@
owner.ventcrawler = VENTCRAWLER_ALWAYS
/obj/item/organ/heart/gland/viral
+ true_name = "contamination incubator"
cooldown_low = 1800
cooldown_high = 2400
uses = 1
@@ -217,6 +229,7 @@
return A
/obj/item/organ/heart/gland/trauma
+ true_name = "white matter randomiser"
cooldown_low = 800
cooldown_high = 1200
uses = 5
@@ -235,6 +248,7 @@
owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
/obj/item/organ/heart/gland/spiderman
+ true_name = "araneae cloister accelerator"
cooldown_low = 450
cooldown_high = 900
uses = -1
@@ -249,6 +263,7 @@
S.directive = "Protect your nest inside [owner.real_name]."
/obj/item/organ/heart/gland/egg
+ true_name = "roe/enzymatic synthesizer"
cooldown_low = 300
cooldown_high = 400
uses = -1
@@ -264,6 +279,7 @@
new /obj/item/reagent_containers/food/snacks/egg/gland(T)
/obj/item/organ/heart/gland/electric
+ true_name = "electron accumulator/discharger"
cooldown_low = 800
cooldown_high = 1200
uses = -1
@@ -289,6 +305,7 @@
playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, 1)
/obj/item/organ/heart/gland/chem
+ true_name = "intrinsic pharma-provider"
cooldown_low = 50
cooldown_high = 50
uses = -1
@@ -315,6 +332,7 @@
..()
/obj/item/organ/heart/gland/plasma
+ true_name = "effluvium sanguine-synonym emitter"
cooldown_low = 1200
cooldown_high = 1800
uses = -1
diff --git a/code/modules/antagonists/abductor/machinery/camera.dm b/code/modules/antagonists/abductor/machinery/camera.dm
index 41cfa6a954..00e48cb1c7 100644
--- a/code/modules/antagonists/abductor/machinery/camera.dm
+++ b/code/modules/antagonists/abductor/machinery/camera.dm
@@ -55,8 +55,7 @@
actions += set_droppoint_action
/obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H)
- var/datum/species/abductor/S = H.dna.species
- return S.scientist
+ return HAS_TRAIT(H, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)
/datum/action/innate/teleport_in
name = "Send To"
diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm
index 46d69ba9bb..9a9b1a6ba0 100644
--- a/code/modules/antagonists/abductor/machinery/console.dm
+++ b/code/modules/antagonists/abductor/machinery/console.dm
@@ -28,7 +28,7 @@
. = ..()
if(.)
return
- if(!isabductor(user))
+ if(!HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) && !HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
to_chat(user, "You start mashing alien buttons at random!")
if(do_after(user,100, target = src))
TeleporterSend()
diff --git a/code/modules/antagonists/abductor/machinery/pad.dm b/code/modules/antagonists/abductor/machinery/pad.dm
index 1cb95fbf05..ab636f7d0e 100644
--- a/code/modules/antagonists/abductor/machinery/pad.dm
+++ b/code/modules/antagonists/abductor/machinery/pad.dm
@@ -53,4 +53,4 @@
. = ..()
var/datum/effect_system/spark_spread/S = new
S.set_up(10,0,loc)
- S.start()
\ No newline at end of file
+ S.start()
diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
index 2018067b77..8000be87e6 100644
--- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
+++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
@@ -366,6 +366,8 @@
break
if(!GLOB.ratvar_awakens)
+ if(GLOB.clockwork_vitality <= 0)
+ break
GLOB.clockwork_vitality -= vitality_used
sleep(2)
diff --git a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
index f44f67e9cb..28deba679b 100644
--- a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
+++ b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
@@ -27,7 +27,7 @@
qdel(blaster)
return ..()
-/obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user)
+/obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot != SLOT_GLASSES)
return 0
return ..()
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
index da499065d7..3d467350ff 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
@@ -119,3 +119,33 @@
var/datum/clockwork_scripture/create_object/construct/clockwork_marauder/CM = new()
CM.recent_marauders--
qdel(CM)
+
+//Summon Neovgre: Summon a very powerful combat mech that explodes when destroyed for massive damage.
+/datum/clockwork_scripture/create_object/summon_arbiter
+ descname = "Powerful Assault Mech"
+ name = "Summon Neovgre, the Anima Bulwark"
+ desc = "Calls forth the mighty Anima Bulwark, a weapon of unmatched power,\
+ mech with superior defensive and offensive capabilities. It will \
+ steadily regenerate HP and triple its regeneration speed while standing \
+ on a clockwork tile. It will automatically draw power from nearby sigils of \
+ transmission should the need arise. Its Arbiter laser cannon can decimate foes \
+ from a range and is capable of smashing through any barrier presented to it. \
+ Be warned, choosing to pilot Neovgre is a lifetime commitment, once you are \
+ in you cannot leave and when it is destroyed it will explode catastrophically with you inside."
+ invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!")
+ channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya.
+ power_cost = 75000 //75 KW
+ usage_tip = "Neovgre is a powerful mech that will crush your enemies!"
+ invokers_required = 5
+ multiple_invokers_used = TRUE
+ object_path = /obj/mecha/combat/neovgre
+ tier = SCRIPTURE_APPLICATION
+ primary_component = BELLIGERENT_EYE
+ sort_priority = 2
+ creator_message = "Neovgre, the Anima Bulwark towers over you... your enemies reckoning has come."
+
+/datum/clockwork_scripture/create_object/summon_arbiter/check_special_requirements()
+ if(GLOB.neovgre_exists)
+ to_chat(invoker, "\"You've already got one...\"")
+ return FALSE
+ return ..()
diff --git a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm
index 7654c0203b..3a461b7745 100644
--- a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm
@@ -78,7 +78,7 @@
return
voters += user.key
else
- if(!user.key in voters)
+ if(!(user.key in voters))
return
voters -= user.key
var/votes_left = votes_needed - voters.len
diff --git a/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm b/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
index 8d65574987..6aede1592e 100644
--- a/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
@@ -7,7 +7,6 @@
break_message = "The vent snaps and collapses!"
max_integrity = 100
density = FALSE
- layer = BELOW_OBJ_LAYER
/obj/structure/destructible/clockwork/trap/steam_vent/activate()
opacity = !opacity
diff --git a/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm b/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm
index fb8397eed7..32b1b61dd1 100644
--- a/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm
@@ -5,7 +5,6 @@
unanchored_icon = "wall_gear"
climbable = TRUE
max_integrity = 100
- layer = BELOW_OBJ_LAYER
construction_value = 3
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
break_message = "The gear breaks apart into shards of alloy!"
diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm
index 49c34131fc..faea113ac5 100644
--- a/code/modules/antagonists/disease/disease_mob.dm
+++ b/code/modules/antagonists/disease/disease_mob.dm
@@ -31,7 +31,6 @@ the new instance inside the host to be updated to the template's stats.
var/browser_open = FALSE
var/mob/living/following_host
- var/datum/component/redirect/move_listener
var/list/disease_instances
var/list/hosts //this list is associative, affected_mob -> disease_instance
var/datum/disease/advance/sentient_disease/disease_template
@@ -261,16 +260,10 @@ the new instance inside the host to be updated to the template's stats.
refresh_adaptation_menu()
/mob/camera/disease/proc/set_following(mob/living/L)
+ if(following_host)
+ UnregisterSignal(following_host, COMSIG_MOVABLE_MOVED)
+ RegisterSignal(L, COMSIG_MOVABLE_MOVED, .proc/follow_mob)
following_host = L
- if(!move_listener)
- move_listener = L.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/follow_mob)))
- else
- if(L)
- L.TakeComponent(move_listener)
- if(QDELING(move_listener))
- move_listener = null
- else
- QDEL_NULL(move_listener)
follow_mob()
/mob/camera/disease/proc/follow_next(reverse = FALSE)
diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm
index 112a31f44d..a03151e2d7 100644
--- a/code/modules/antagonists/revenant/revenant_abilities.dm
+++ b/code/modules/antagonists/revenant/revenant_abilities.dm
@@ -27,6 +27,7 @@
if(prob(10))
to_chat(target, "You feel as if you are being watched.")
return
+ face_atom(target)
draining = TRUE
essence_drained += rand(15, 20)
to_chat(src, "You search for the soul of [target].")
diff --git a/code/modules/antagonists/revenant/revenant_blight.dm b/code/modules/antagonists/revenant/revenant_blight.dm
index 89d8de283a..3e05b8d945 100644
--- a/code/modules/antagonists/revenant/revenant_blight.dm
+++ b/code/modules/antagonists/revenant/revenant_blight.dm
@@ -12,8 +12,8 @@
disease_flags = CURABLE
permeability_mod = 1
severity = DISEASE_SEVERITY_DANGEROUS
- var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
- var/datum/mood_event/revenant_blight/depression
+ var/finalstage = FALSE //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
+ var/depression = FALSE
/datum/disease/revblight/cure()
if(affected_mob)
@@ -44,7 +44,8 @@
affected_mob.emote("pale")
if(3)
if(!depression)
- depression = SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
+ SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
+ depression = TRUE
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.12, SANITY_CRAZY)
if(prob(10))
affected_mob.emote(pick("pale","shiver"))
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 57488a6722..576fc6b9bf 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -113,7 +113,7 @@
/obj/singularity/wizard/attack_tk(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
- GET_COMPONENT_FROM(insaneinthemembrane, /datum/component/mood, C)
+ var/datum/component/mood/insaneinthemembrane = C.GetComponent(/datum/component/mood)
if(insaneinthemembrane.sanity < 15)
return //they've already seen it and are about to die, or are just too insane to care
to_chat(C, "OH GOD! NONE OF IT IS REAL! NONE OF IT IS REEEEEEEEEEEEEEEEEEEEEEEEAL!")
@@ -324,14 +324,11 @@
cooldown = world.time + cooldown_time
/obj/item/voodoo/proc/update_targets()
- possible = list()
+ LAZYINITLIST(possible)
if(!voodoo_link)
return
- var/list/prints = voodoo_link.return_fingerprints()
- if(!length(prints))
- return FALSE
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
- if(prints[md5(H.dna.uni_identity)])
+ if(md5(H.dna.uni_identity) in voodoo_link.fingerprints)
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm
index 1df8e43316..6f4c3fca10 100644
--- a/code/modules/antagonists/wizard/equipment/soulstone.dm
+++ b/code/modules/antagonists/wizard/equipment/soulstone.dm
@@ -238,6 +238,7 @@
T.stop_sound_channel(CHANNEL_HEARTBEAT)
T.invisibility = INVISIBILITY_ABSTRACT
T.dust_animation()
+ QDEL_IN(T, 5)
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade(src)
S.status_flags |= GODMODE //So they won't die inside the stone somehow
S.canmove = FALSE//Can't move out of the soul stone
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 07f31a6678..7405549b3d 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -10,7 +10,7 @@
var/maxlength = 8
var/list/obj/effect/beam/i_beam/beams
var/olddir = 0
- var/datum/component/redirect/listener
+ var/turf/listeningTo
var/hearing_range = 3
/obj/item/assembly/infra/Initialize()
@@ -33,7 +33,7 @@
/obj/item/assembly/infra/Destroy()
STOP_PROCESSING(SSobj, src)
- QDEL_NULL(listener)
+ listeningTo = null
QDEL_LIST(beams)
. = ..()
@@ -163,8 +163,12 @@
next_activate = world.time + 30
/obj/item/assembly/infra/proc/switchListener(turf/newloc)
- QDEL_NULL(listener)
- listener = newloc.AddComponent(/datum/component/redirect, list(COMSIG_ATOM_EXITED = CALLBACK(src, .proc/check_exit)))
+ if(listeningTo == newloc)
+ return
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_ATOM_EXITED)
+ RegisterSignal(newloc, COMSIG_ATOM_EXITED, .proc/check_exit)
+ listeningTo = newloc
/obj/item/assembly/infra/proc/check_exit(datum/source, atom/movable/offender)
if(QDELETED(src))
diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm
index 8e320b2f3e..f9c831a65a 100644
--- a/code/modules/atmospherics/gasmixtures/reactions.dm
+++ b/code/modules/atmospherics/gasmixtures/reactions.dm
@@ -210,9 +210,9 @@
return cached_results["fire"] ? REACTING : NO_REACTION
-//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again)
+//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again). Again!
//Fusion Rework Counter: Please increment this if you make a major overhaul to this system again.
-//5 reworks
+//6 reworks
/datum/gas_reaction/fusion
exclude = FALSE
@@ -220,100 +220,79 @@
name = "Plasmic Fusion"
id = "fusion"
-//Since fusion isn't really intended to happen in successive chains, the requirements are very high
/datum/gas_reaction/fusion/init_reqs()
min_requirements = list(
"TEMP" = FUSION_TEMPERATURE_THRESHOLD,
- "ENER" = FUSION_ENERGY_THRESHOLD,
+ /datum/gas/tritium = FUSION_TRITIUM_MOLES_USED,
/datum/gas/plasma = FUSION_MOLE_THRESHOLD,
- /datum/gas/tritium = FUSION_MOLE_THRESHOLD
- )
+ /datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
var/list/cached_gases = air.gases
- var/temperature = air.temperature
- if(!air.analyzer_results)
- air.analyzer_results = new
- var/list/cached_scan_results = air.analyzer_results
var/turf/open/location
if (istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
var/datum/pipeline/fusion_pipenet = holder
location = get_turf(pick(fusion_pipenet.members))
else
location = get_turf(holder)
-
+ if(!air.analyzer_results)
+ air.analyzer_results = new
+ var/list/cached_scan_results = air.analyzer_results
var/old_heat_capacity = air.heat_capacity()
- var/reaction_energy = 0
-
- var/mediation = FUSION_MEDIATION_FACTOR*(air.heat_capacity()-(cached_gases[/datum/gas/plasma]*GLOB.meta_gas_specific_heats[/datum/gas/plasma]))/(air.total_moles()-cached_gases[/datum/gas/plasma]) //This is the average specific heat of the mixture,not including plasma.
-
- var/gases_fused = air.total_moles() - cached_gases[/datum/gas/plasma]
- var/plasma_differential = (cached_gases[/datum/gas/plasma] - gases_fused) / air.total_moles()
- var/reaction_efficiency = FUSION_EFFICIENCY_BASE ** -((plasma_differential ** 2) / FUSION_EFFICIENCY_DIVISOR) //https://www.desmos.com/calculator/6jjx3vdrvx
-
+ var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
+ var/initial_plasma = cached_gases[/datum/gas/plasma]
+ var/initial_carbon = cached_gases[/datum/gas/carbon_dioxide]
+ var/scale_factor = (air.volume)/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
+ var/toroidal_size = (2*PI)+TORADIANS(arctan((air.volume-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
var/gas_power = 0
+ var/list/gas_fusion_powers = GLOB.meta_gas_fusions
for (var/gas_id in cached_gases)
- gas_power += reaction_efficiency * (GLOB.meta_gas_fusions[gas_id]*cached_gases[gas_id])
+ gas_power += (gas_fusion_powers[gas_id]*cached_gases[gas_id])
+ var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
+ cached_scan_results[id] = instability//used for analyzer feedback
- var/power_ratio = gas_power/mediation
- cached_scan_results[id] = power_ratio //used for analyzer feedback
+ var/plasma = (initial_plasma-FUSION_MOLE_THRESHOLD)/(scale_factor) //We have to scale the amounts of carbon and plasma down a significant amount in order to show the chaotic dynamics we want
+ var/carbon = (initial_carbon-FUSION_MOLE_THRESHOLD)/(scale_factor) //We also subtract out the threshold amount to make it harder for fusion to burn itself out.
- for (var/gas_id in cached_gases) //and now we fuse
- cached_gases[gas_id] = 0
+ //The reaction is a specific form of the Kicked Rotator system, which displays chaotic behavior and can be used to model particle interactions.
+ plasma = MODULUS(plasma - (instability*sin(TODEGREES(carbon))), toroidal_size)
+ carbon = MODULUS(carbon - plasma, toroidal_size)
- var/radiation_power = (FUSION_RADIATION_FACTOR * power_ratio) / (power_ratio + FUSION_RADIATION_CONSTANT) //https://www.desmos.com/calculator/4i1f296phl
- var/zap_power = ((FUSION_ZAP_POWER_ASYMPTOTE * power_ratio) / (power_ratio + FUSION_ZAP_POWER_CONSTANT)) + FUSION_ZAP_POWER_BASE //https://www.desmos.com/calculator/n0zkdpxnrr
- var/do_explosion = FALSE
- var/zap_range //these ones are set later
- var/fusion_prepare_to_die_edition_rng
- if (power_ratio > FUSION_SUPER_TIER_THRESHOLD) //power ratio 50+: SUPER TIER. The gases become so energized that they fuse into a ton of tritium, which is pretty nice! Until you consider the fact that everything just exploded, the canister is probably going to break and you're irradiated.
- reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_SUPER * (power_ratio / FUSION_ENERGY_DIVISOR_SUPER)
- cached_gases[/datum/gas/tritium] += gases_fused * FUSION_GAS_CREATION_FACTOR_TRITIUM //60% of the gas is converted to energy, 40% to trit
- fusion_prepare_to_die_edition_rng = 100 //Wait a minute..
- do_explosion = TRUE
- zap_range = FUSION_ZAP_RANGE_SUPER
+ cached_gases[/datum/gas/plasma] = plasma*scale_factor + FUSION_MOLE_THRESHOLD //Scales the gases back up
+ cached_gases[/datum/gas/carbon_dioxide] = carbon*scale_factor + FUSION_MOLE_THRESHOLD
+ var/delta_plasma = initial_plasma - cached_gases[/datum/gas/plasma]
- else if (power_ratio > FUSION_HIGH_TIER_THRESHOLD) //power ratio 20-50; High tier. The reaction is so energized that it fuses into a small amount of stimulum, and some pluoxium. Very dangerous, but super cool and super useful.
- reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_HIGH * (power_ratio / FUSION_ENERGY_DIVISOR_HIGH)
- cached_gases[/datum/gas/stimulum] += gases_fused * FUSION_GAS_CREATION_FACTOR_STIM //40% of the gas is converted to energy, 60% to stim and pluox
- cached_gases[/datum/gas/pluoxium] += gases_fused * FUSION_GAS_CREATION_FACTOR_PLUOX
- fusion_prepare_to_die_edition_rng = power_ratio //Now we're getting into dangerous territory
- do_explosion = TRUE
- zap_range = FUSION_ZAP_RANGE_HIGH
-
- else if (power_ratio > FUSION_MID_TIER_THRESHOLD) //power_ratio 5 to 20; Mediation is overpowered, fusion reaction starts to break down.
- reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_MID * (power_ratio / FUSION_ENERGY_DIVISOR_MID)
- cached_gases[/datum/gas/nitryl] += gases_fused * FUSION_GAS_CREATION_FACTOR_NITRYL //20% of the gas is converted to energy, 80% to nitryl and N2O
- cached_gases[/datum/gas/nitrous_oxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_N2O
- fusion_prepare_to_die_edition_rng = power_ratio * FUSION_MID_TIER_RAD_PROB_FACTOR //Still unlikely, but don't stand next to the reaction unprotected
- zap_range = FUSION_ZAP_RANGE_MID
-
- else //power ratio 0 to 5; Gas power is overpowered. Fusion isn't nearly as powerful.
- reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_LOW * (power_ratio / FUSION_ENERGY_DIVISOR_LOW)
- cached_gases[/datum/gas/bz] += gases_fused * FUSION_GAS_CREATION_FACTOR_BZ //10% of the gas is converted to energy, 90% to BZ and CO2
- cached_gases[/datum/gas/carbon_dioxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_CO2
- fusion_prepare_to_die_edition_rng = power_ratio * FUSION_LOW_TIER_RAD_PROB_FACTOR //Low, but still something to look out for
- zap_range = FUSION_ZAP_RANGE_LOW
-
- //All the deadly consequences of fusion, consolidated for your viewing pleasure
- if (location)
- if(prob(fusion_prepare_to_die_edition_rng)) //Some.. permanent effects
- if(do_explosion)
- explosion(location, 0, 0, 5, power_ratio, TRUE, TRUE) //large shockwave, the actual radius is quite small - people will recognize that you're doing fusion
- radiation_pulse(location, radiation_power) //You mean causing a super-tier fusion reaction in the halls is a bad idea?
- SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, 30000)//The science is cool though.
- playsound(location, 'sound/effects/supermatter.ogg', 100, 0)
- else
- playsound(location, 'sound/effects/phasein.ogg', 75, 0)
- //These will always happen, so be prepared
- tesla_zap(location, zap_range, zap_power, TESLA_FUSION_FLAGS) //larpers beware
- location.fire_nuclear_particles(power_ratio) //see code/modules/projectile/energy/nuclear_particle.dm
+ reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass.
+ if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
+ reaction_energy = max(reaction_energy,0) //Stable reactions don't end up endothermic.
+ else if (reaction_energy < 0)
+ reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
+ if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
+ cached_gases[/datum/gas/plasma] = initial_plasma
+ cached_gases[/datum/gas/carbon_dioxide] = initial_carbon
+ return NO_REACTION
+ cached_gases[/datum/gas/tritium] -= FUSION_TRITIUM_MOLES_USED
+ //The decay of the tritium and the reaction's energy produces waste gases, different ones depending on whether the reaction is endo or exothermic
if(reaction_energy > 0)
+ cached_gases[/datum/gas/oxygen] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
+ cached_gases[/datum/gas/nitrous_oxide] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
+ else
+ cached_gases[/datum/gas/bz] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
+ cached_gases[/datum/gas/nitryl] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
+
+ if(reaction_energy)
+ if(location)
+ var/particle_chance = ((PARTICLE_CHANCE_CONSTANT)/(reaction_energy-PARTICLE_CHANCE_CONSTANT)) + 1//Asymptopically approaches 100% as the energy of the reaction goes up.
+ if(prob(PERCENT(particle_chance)))
+ location.fire_nuclear_particle()
+ var/rad_power = max((FUSION_RAD_COEFFICIENT/instability) + FUSION_RAD_MAX,0)
+ radiation_pulse(location,rad_power)
+
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.temperature = max(((temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB)
+ air.temperature = CLAMP(((air.temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY)
return REACTING
/datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst.
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 74f81ec9a0..2631491350 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -587,3 +587,57 @@
shoes = /obj/item/clothing/shoes/sneakers/black
suit = /obj/item/clothing/suit/armor/vest
glasses = /obj/item/clothing/glasses/sunglasses/reagent
+
+/obj/effect/mob_spawn/human/lavaknight
+ name = "odd cryogenics pod"
+ desc = "A humming cryo pod. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant."
+ mob_name = "a displaced knight from another dimension"
+ icon = 'icons/obj/machines/sleeper.dmi'
+ icon_state = "sleeper"
+ roundstart = FALSE
+ id_job = "Knight"
+ job_description = "Cydonian Knight"
+ death = FALSE
+ random = TRUE
+ outfit = /datum/outfit/lavaknight
+ mob_species = /datum/species/human
+ flavour_text = "You are a knight who conveniently has some form of retrograde amnesia. \
+ You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \
+ Remember: hostile creatures and such are fair game for attacking, but under no circumstances are you to attack anything capable of thought and/or speech unless it has made it its life's calling to chase you to the ends of the earth."
+ assignedrole = "Cydonian Knight"
+
+/obj/effect/mob_spawn/human/lavaknight/special(mob/living/new_spawn)
+ if(ishuman(new_spawn))
+ var/mob/living/carbon/human/H = new_spawn
+ H.dna.features["mam_ears"] = "Cat, Big" //cat people
+ H.dna.features["mcolor"] = H.hair_color
+ H.update_body()
+
+/obj/effect/mob_spawn/human/lavaknight/Destroy()
+ new/obj/structure/showcase/machinery/oldpod/used(drop_location())
+ return ..()
+
+/datum/outfit/lavaknight
+ name = "Cydonian Knight"
+ uniform = /obj/item/clothing/under/assistantformal
+ mask = /obj/item/clothing/mask/breath
+ shoes = /obj/item/clothing/shoes/sneakers/black
+ r_pocket = /obj/item/melee/transforming/energy/sword/cx
+ suit = /obj/item/clothing/suit/space/hardsuit/lavaknight
+ suit_store = /obj/item/tank/internals/oxygen
+ id = /obj/item/card/id/knight/blue
+
+/obj/effect/mob_spawn/human/lavaknight/captain
+ name = "odd gilded cryogenics pod"
+ desc = "A humming cryo pod that appears to be gilded. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant."
+ flavour_text = "You are a knight who conveniently has some form of retrograde amnesia. \
+ You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \
+ Remember: hostile creatures and such are fair game for attacking, but under no circumstances are you to attack anything capable of thought and/or speech unless it has made it its life's calling to chase you to the ends of the earth. \
+ You feel a natural instict to lead, and as such, you should strive to lead your comrades to safety, and hopefully home. You also feel a burning determination to uphold your vow, as well as your fellow comrade's."
+ outfit = /datum/outfit/lavaknight/captain
+ id_job = "Knight Captain"
+
+/datum/outfit/lavaknight/captain
+ name ="Cydonian Knight Captain"
+ l_pocket = /obj/item/twohanded/dualsaber/hypereutactic
+ id = /obj/item/card/id/knight/captain
diff --git a/code/modules/cargo/bounties/assistant.dm b/code/modules/cargo/bounties/assistant.dm
index cf4efaa8c6..4edcb04e8f 100644
--- a/code/modules/cargo/bounties/assistant.dm
+++ b/code/modules/cargo/bounties/assistant.dm
@@ -1,46 +1,46 @@
/datum/bounty/item/assistant/strange_object
name = "Strange Object"
description = "Nanotrasen has taken an interest in strange objects. Find one in maint, and ship it off to CentCom right away."
- reward = 1200
+ reward = 600
wanted_types = list(/obj/item/relic)
/datum/bounty/item/assistant/scooter
name = "Scooter"
description = "Nanotrasen has determined walking to be wasteful. Ship a scooter to CentCom to speed operations up."
- reward = 1080 // the mat hoffman
+ reward = 850 // the mat hoffman
wanted_types = list(/obj/vehicle/ridden/scooter)
include_subtypes = FALSE
/datum/bounty/item/assistant/skateboard
name = "Skateboard"
description = "Nanotrasen has determined walking to be wasteful. Ship a skateboard to CentCom to speed operations up."
- reward = 900 // the tony hawk
+ reward = 700 // the tony hawk
wanted_types = list(/obj/vehicle/ridden/scooter/skateboard)
/datum/bounty/item/assistant/stunprod
name = "Stunprod"
description = "CentCom demands a stunprod to use against dissidents. Craft one, then ship it."
- reward = 1300
+ reward = 800
wanted_types = list(/obj/item/melee/baton/cattleprod)
/datum/bounty/item/assistant/soap
name = "Soap"
description = "Soap has gone missing from CentCom's bathrooms and nobody knows who took it. Replace it and be the hero CentCom needs."
- reward = 2000
+ reward = 1000
required_count = 3
wanted_types = list(/obj/item/soap)
/datum/bounty/item/assistant/spear
name = "Spears"
description = "CentCom's security forces are going through budget cuts. You will be paid if you ship a set of spears."
- reward = 2000
+ reward = 1000
required_count = 5
wanted_types = list(/obj/item/twohanded/spear)
/datum/bounty/item/assistant/toolbox
name = "Toolboxes"
description = "There's an absence of robustness at Central Command. Hurry up and ship some toolboxes as a solution."
- reward = 2000
+ reward = 1000
required_count = 6
wanted_types = list(/obj/item/storage/toolbox)
@@ -53,81 +53,81 @@
/datum/bounty/item/assistant/clown_box
name = "Clown Box"
description = "The universe needs laughter. Stamp cardboard with a clown stamp and ship it out."
- reward = 1500
+ reward = 750
wanted_types = list(/obj/item/storage/box/clown)
/datum/bounty/item/assistant/cheesiehonkers
name = "Cheesie Honkers"
description = "Apparently the company that makes Cheesie Honkers is going out of business soon. CentCom wants to stock up before it happens!"
- reward = 1200
+ reward = 1000
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/cheesiehonkers)
/datum/bounty/item/assistant/baseball_bat
name = "Baseball Bat"
description = "Baseball fever is going on at CentCom! Be a dear and ship them some baseball bats, so that management can live out their childhood dream."
- reward = 2000
+ reward = 1000
required_count = 5
wanted_types = list(/obj/item/melee/baseball_bat)
/datum/bounty/item/assistant/extendohand
name = "Extendo-Hand"
description = "Commander Betsy is getting old, and can't bend over to get the telescreen remote anymore. Management has requested an extendo-hand to help her out."
- reward = 2500
+ reward = 1250
wanted_types = list(/obj/item/extendohand)
/datum/bounty/item/assistant/donut
name = "Donuts"
description = "CentCom's security forces are facing heavy losses against the Syndicate. Ship donuts to raise morale."
- reward = 3000
+ reward = 2000
required_count = 10
wanted_types = list(/obj/item/reagent_containers/food/snacks/donut)
/datum/bounty/item/assistant/donkpocket
name = "Donk-Pockets"
description = "Consumer safety recall: Warning. Donk-Pockets manufactured in the past year contain hazardous lizard biomatter. Return units to CentCom immediately."
- reward = 3000
+ reward = 1000
required_count = 10
wanted_types = list(/obj/item/reagent_containers/food/snacks/donkpocket)
/datum/bounty/item/assistant/briefcase
name = "Briefcase"
description = "Central Command will be holding a business convention this year. Ship a few briefcases in support."
- reward = 2500
+ reward = 1500
required_count = 5
wanted_types = list(/obj/item/storage/briefcase, /obj/item/storage/secure/briefcase)
/datum/bounty/item/assistant/sunglasses
name = "Sunglasses"
description = "A famous blues duo is passing through the sector, but they've lost their shades and they can't perform. Ship new sunglasses to CentCom to rectify this."
- reward = 3000
+ reward = 1000
required_count = 2
wanted_types = list(/obj/item/clothing/glasses/sunglasses)
/datum/bounty/item/assistant/monkey_hide
name = "Monkey Hide"
description = "One of the scientists at CentCom is interested in testing products on monkey skin. Your mission is to acquire monkey's hide and ship it."
- reward = 1500
+ reward = 500
wanted_types = list(/obj/item/stack/sheet/animalhide/monkey)
/datum/bounty/item/assistant/shard
name = "Shards"
description = "A killer clown has been stalking CentCom, and staff have been unable to catch her because she's not wearing shoes. Please ship some shards so that a booby trap can be constructed."
- reward = 1500
+ reward = 500
required_count = 15
wanted_types = list(/obj/item/shard)
/datum/bounty/item/assistant/comfy_chair
name = "Comfy Chairs"
description = "Commander Pat is unhappy with his chair. He claims it hurts his back. Ship some alternatives out to humor him."
- reward = 1500
+ reward = 900
required_count = 5
wanted_types = list(/obj/structure/chair/comfy)
/datum/bounty/item/assistant/geranium
name = "Geraniums"
description = "Commander Zot has the hots for Commander Zena. Send a shipment of geraniums - her favorite flower - and he'll happily reward you."
- reward = 4000
+ reward = 1000
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/poppy/geranium)
@@ -142,7 +142,7 @@
/datum/bounty/item/assistant/shadyjims
name = "Shady Jim's"
description = "There's an irate officer at CentCom demanding that he receive a box of Shady Jim's cigarettes. Please ship one. He's starting to make threats."
- reward = 500
+ reward = 750
wanted_types = list(/obj/item/storage/fancy/cigarettes/cigpack_shadyjims)
/datum/bounty/item/assistant/potted_plants
diff --git a/code/modules/cargo/bounties/botany.dm b/code/modules/cargo/bounties/botany.dm
index 34906b321a..754de480cd 100644
--- a/code/modules/cargo/bounties/botany.dm
+++ b/code/modules/cargo/bounties/botany.dm
@@ -1,5 +1,5 @@
/datum/bounty/item/botany
- reward = 5000
+ reward = 1200
var/datum/bounty/item/botany/multiplier = 0 //adds bonus reward money; increased for higher tier or rare mutations
var/datum/bounty/item/botany/bonus_desc //for adding extra flavor text to bounty descriptions
var/datum/bounty/item/botany/foodtype = "meal" //same here
@@ -64,7 +64,7 @@
multiplier = 4 //hush money
bonus_desc = "Do not mention this shipment to security."
foodtype = "\"meal\""
-
+
/datum/bounty/item/botany/cannabis_white
name = "Lifeweed Leaves"
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/white)
diff --git a/code/modules/cargo/bounties/chef.dm b/code/modules/cargo/bounties/chef.dm
index b9d9ebc184..719a2d10a5 100644
--- a/code/modules/cargo/bounties/chef.dm
+++ b/code/modules/cargo/bounties/chef.dm
@@ -1,34 +1,34 @@
/datum/bounty/item/chef/birthday_cake
name = "Birthday Cake"
description = "Nanotrasen's birthday is coming up! Ship them a birthday cake to celebrate!"
- reward = 4000
+ reward = 1000
wanted_types = list(/obj/item/reagent_containers/food/snacks/store/cake/birthday, /obj/item/reagent_containers/food/snacks/cakeslice/birthday)
/datum/bounty/item/chef/soup
name = "Soup"
description = "To quell the homeless uprising, Nanotrasen will be serving soup to all underpaid workers. Ship any type of soup."
- reward = 3000
+ reward = 700
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/soup)
/datum/bounty/item/chef/popcorn
name = "Popcorn Bags"
description = "Upper management wants to host a movie night. Ship bags of popcorn for the occasion."
- reward = 3000
+ reward = 800
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/popcorn)
/datum/bounty/item/chef/onionrings
name = "Onion Rings"
description = "Nanotrasen is remembering Saturn day. Ship onion rings to show the station's support."
- reward = 3000
+ reward = 800
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/onionrings)
/datum/bounty/item/chef/icecreamsandwich
name = "Ice Cream Sandwiches"
description = "Upper management has been screaming non-stop for ice cream. Please send some."
- reward = 4000
+ reward = 800
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/icecreamsandwich)
@@ -36,7 +36,7 @@
name = "Bread"
description = "Problems with central planning have led to bread prices skyrocketing. Ship some bread to ease tensions."
reward = 1000
- wanted_types = list(/obj/item/reagent_containers/food/snacks/store/bread, /obj/item/reagent_containers/food/snacks/breadslice, /obj/item/reagent_containers/food/snacks/bun, /obj/item/reagent_containers/food/snacks/pizzabread, /obj/item/reagent_containers/food/snacks/rawpastrybase)
+ wanted_types = list(/obj/item/reagent_containers/food/snacks/store/bread, /obj/item/reagent_containers/food/snacks/breadslice, /obj/item/reagent_containers/food/snacks/bun, /obj/item/reagent_containers/food/snacks/pizzabread, /obj/item/reagent_containers/food/snacks/rawpastrybase)
/datum/bounty/item/chef/pie
name = "Pie"
@@ -47,21 +47,21 @@
/datum/bounty/item/chef/salad
name = "Salad or Rice Bowls"
description = "CentCom management is going on a health binge. Your order is to ship salad or rice bowls."
- reward = 3000
+ reward = 1200
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/salad)
/datum/bounty/item/chef/carrotfries
name = "Carrot Fries"
description = "Night sight can mean life or death! A shipment of carrot fries is the order."
- reward = 3500
+ reward = 1300
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/carrotfries)
/datum/bounty/item/chef/superbite
name = "Super Bite Burger"
description = "Commander Tubbs thinks he can set a competitive eating world record. All he needs is a super bite burger shipped to him."
- reward = 12000
+ reward = 1800
wanted_types = list(/obj/item/reagent_containers/food/snacks/burger/superbite)
/datum/bounty/item/chef/poppypretzel
@@ -73,19 +73,19 @@
/datum/bounty/item/chef/cubancarp
name = "Cuban Carp"
description = "To celebrate the birth of Castro XXVII, ship one cuban carp to CentCom."
- reward = 8000
+ reward = 3000
wanted_types = list(/obj/item/reagent_containers/food/snacks/cubancarp)
/datum/bounty/item/chef/hotdog
name = "Hot Dog"
description = "Nanotrasen is conducting taste tests to determine the best hot dog recipe. Ship your station's version to participate."
- reward = 8000
+ reward = 4000
wanted_types = list(/obj/item/reagent_containers/food/snacks/hotdog)
/datum/bounty/item/chef/eggplantparm
name = "Eggplant Parmigianas"
description = "A famous singer will be arriving at CentCom, and their contract demands that they only be served Eggplant Parmigiana. Ship some, please!"
- reward = 3500
+ reward = 2500
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/eggplantparm)
@@ -99,33 +99,33 @@
/datum/bounty/item/chef/chawanmushi
name = "Chawanmushi"
description = "Nanotrasen wants to improve relations with its sister company, Japanotrasen. Ship Chawanmushi immediately."
- reward = 8000
+ reward = 5000
wanted_types = list(/obj/item/reagent_containers/food/snacks/chawanmushi)
/datum/bounty/item/chef/kebab
name = "Kebabs"
description = "Remove all kebab from station you are best food. Ship to CentCom to remove from the premises."
- reward = 3500
+ reward = 1500
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/kebab)
/datum/bounty/item/chef/soylentgreen
name = "Soylent Green"
description = "CentCom has heard wonderful things about the product 'Soylent Green', and would love to try some. If you endulge them, expect a pleasant bonus."
- reward = 5000
+ reward = 4000
wanted_types = list(/obj/item/reagent_containers/food/snacks/soylentgreen)
/datum/bounty/item/chef/pancakes
name = "Pancakes"
description = "Here at Nanotrasen we consider employees to be family. And you know what families love? Pancakes. Ship a baker's dozen."
- reward = 5000
+ reward = 4000
required_count = 13
wanted_types = list(/datum/crafting_recipe/food/pancakes)
/datum/bounty/item/chef/nuggies
name = "Chicken Nuggets"
description = "The vice president's son won't shut up about chicken nuggies. Would you mind shipping some?"
- reward = 4000
+ reward = 2500
required_count = 6
wanted_types = list(/obj/item/reagent_containers/food/snacks/nugget)
diff --git a/code/modules/cargo/bounties/engineering.dm b/code/modules/cargo/bounties/engineering.dm
index cf2cd7d93c..1f16788c4d 100644
--- a/code/modules/cargo/bounties/engineering.dm
+++ b/code/modules/cargo/bounties/engineering.dm
@@ -27,41 +27,41 @@
/datum/bounty/item/engineering/pacman
name = "P.A.C.M.A.N.-type portable generator"
description = "A neighboring station had a problem with their SMES, and now need something to power their communications console. Can you send them a P.AC.M.A.N.?"
- reward = 3500 //2500 for the cargo one
+ reward = 1500 //2500 for the cargo one
wanted_types = list(/obj/machinery/power/port_gen/pacman)
/datum/bounty/item/engineering/canisters
name = "Gas Canisters"
description = "After a recent debacle in a nearby sector, 10 gas canisters are needed for containing an experimental aerosol before it kills all the local fauna."
- reward = 5000
+ reward = 3000
required_count = 10 //easy to make
wanted_types = list(/obj/machinery/portable_atmospherics/canister)
/datum/bounty/item/engineering/microwave
name = "Microwaves"
description = "Due to a shortage of microwaves, our chefs are incapable of keeping up with our sheer volume of orders. We need at least three microwaves to keep up with our crew's dietary habits."
- reward = 2000
+ reward = 1000
required_count = 3
wanted_types = list(/obj/machinery/microwave)
/datum/bounty/item/engineering/hydroponicstrays
name = "Hydroponics Tray"
description = "The garden has become a hot spot of late, they need a few more hydroponics tray to grow more flowers."
- reward = 2500
+ reward = 1500
required_count = 5
wanted_types = list(/obj/machinery/hydroponics)
/datum/bounty/item/engineering/rcd
name = "Spare RCD"
description = "Construction and repairs to are shuttles are going slowly. As it turns out, we're a little short on RCDs, can you send us a few?"
- reward = 2500
+ reward = 1500
required_count = 3
wanted_types = list(/obj/item/construction/rcd)
/datum/bounty/item/engineering/rpd
name = "Spare RPD"
description = "Our Atmospheric Technicians are still living in the past, relying on stationary pipe dispensers to produce the pipes necessary to accomplish their strenuous tasks. They could use an upgrade. Could you send us some Rapid Pipe Dispensers?"
- reward = 3000
+ reward = 2500
required_count = 3
wanted_types = list(/obj/item/pipe_dispenser)
@@ -75,19 +75,19 @@
/datum/bounty/item/engineering/arcadetrail
name = "Orion Trail Arcade Games"
description = "The staff have nothing to do when off-work. Can you send us some Orion Trail games to play?"
- reward = 3000
+ reward = 1500
required_count = 5
wanted_types = list(/obj/machinery/computer/arcade/orion_trail)
/datum/bounty/item/engineering/arcadebattle
name = "Battle Arcade Games"
description = "The staff have nothing to do when off-work. Can you send us some Battle Arcade games to play?"
- reward = 3000
+ reward = 1500
required_count = 5
wanted_types = list(/obj/machinery/computer/arcade/battle)
/datum/bounty/item/engineering/energy_ball
name = "Contained Tesla Ball"
description = "Station 24 is being overrun by hordes of angry Mothpeople. They are requesting the ultimate bug zapper."
- reward = 75000 //requires 14k credits of purchases, not to mention cooperation with engineering/heads of staff to set up inside the cramped shuttle
+ reward = 50000 //requires 14k credits of purchases, not to mention cooperation with engineering/heads of staff to set up inside the cramped shuttle
wanted_types = list(/obj/singularity/energy_ball)
diff --git a/code/modules/cargo/bounties/medical.dm b/code/modules/cargo/bounties/medical.dm
index 3129051754..22964e1fb7 100644
--- a/code/modules/cargo/bounties/medical.dm
+++ b/code/modules/cargo/bounties/medical.dm
@@ -7,34 +7,34 @@
/datum/bounty/item/medical/lung
name = "Lungs"
description = "A recent explosion at Central Command has left multiple staff with punctured lungs. Ship spare lungs to be rewarded."
- reward = 10000
+ reward = 3000
required_count = 3
wanted_types = list(/obj/item/organ/lungs)
/datum/bounty/item/medical/appendix
name = "Appendix"
description = "Chef Gibb of Central Command wants to prepare a meal using a very special delicacy: an appendix. If you ship one, he'll pay."
- reward = 5000 //there are no synthetic appendixes
+ reward = 3500 //there are no synthetic appendixes
wanted_types = list(/obj/item/organ/appendix)
/datum/bounty/item/medical/ears
name = "Ears"
description = "Multiple staff at Station 12 have been left deaf due to unauthorized clowning. Ship them new ears."
- reward = 10000
+ reward = 5000
required_count = 3
wanted_types = list(/obj/item/organ/ears)
/datum/bounty/item/medical/liver
name = "Livers"
description = "Multiple high-ranking CentCom diplomats have been hospitalized with liver failure after a recent meeting with Third Soviet Union ambassadors. Help us out, will you?"
- reward = 10000
+ reward = 5500
required_count = 3
wanted_types = list(/obj/item/organ/liver)
/datum/bounty/item/medical/eye
name = "Organic Eyes"
description = "Station 5's Research Director Willem is requesting a few pairs of non-robotic eyes. Don't ask questions, just ship them."
- reward = 10000
+ reward = 3000
required_count = 3
wanted_types = list(/obj/item/organ/eyes)
exclude_types = list(/obj/item/organ/eyes/robotic)
@@ -42,7 +42,7 @@
/datum/bounty/item/medical/tongue
name = "Tongues"
description = "A recent attack by Mime extremists has left staff at Station 23 speechless. Ship some spare tongues."
- reward = 10000
+ reward = 4500
required_count = 3
wanted_types = list(/obj/item/organ/tongue)
@@ -79,7 +79,7 @@
required_count = 200
wanted_types = (L,/datum/reagent/blood)
if(istype(L,/datum/reagent/blood))
- wanted_types += L
+ wanted_types += L
/datum/bounty/item/medical/bloodu //Dosnt work do to how blood is yet*
name = "U-Type Blood"
@@ -88,40 +88,40 @@
required_count = 200
wanted_types = (U,/datum/reagent/blood)
if(istype(U,/datum/reagent/blood))
- wanted_types += U
+ wanted_types += U
*/
/datum/bounty/item/medical/surgery
name = "Surgery tool implants"
description = "Our medical interns keep dropping their Shambler's Juice while they're performing open heart surgery. One of them even had the audacity to say he only had two hands!"
- reward = 10000
+ reward = 7000
required_count = 3
wanted_types = list(/obj/item/organ/cyberimp/arm/surgery)
/datum/bounty/item/medical/chemmaker
name = "Portable Chem Dispenser"
description = "After a new chemist mixed up some water and a banana, we lost our only chem dispenser. Please send us a replacement and you will be compensated."
- reward = 7000
+ reward = 5000
wanted_types = list(/obj/machinery/chem_dispenser)
/datum/bounty/item/medical/advhealthscaner
name = "Advanced Health Analyzer"
description = "A ERT Medical unit needs the new 'advanced health analyzer', for a mission at a Station 4. Can you send some?."
- reward = 4000
+ reward = 3000
required_count = 5
wanted_types = list(/obj/item/healthanalyzer/advanced)
/datum/bounty/item/medical/wallmounts
name = "Defibrillator wall mounts"
description = "New Space OSHA regulation state that are new cloning medical wing needs a few 'Easy to access defibrillartors'. Can you send a few before we get a lawsuit?"
- reward = 5000
+ reward = 2000
required_count = 3
wanted_types = list(/obj/machinery/defibrillator_mount)
/datum/bounty/item/medical/defibrillator
name = "New defibillators"
description = "After years of storge are defibrillator units have become more liabilities then we want. Please send us some new ones to replace these old ones."
- reward = 5000
+ reward = 2250
required_count = 5
wanted_types = list(/obj/item/defibrillator)
diff --git a/code/modules/cargo/bounties/mining.dm b/code/modules/cargo/bounties/mining.dm
index 51d93f83b5..1f3266af62 100644
--- a/code/modules/cargo/bounties/mining.dm
+++ b/code/modules/cargo/bounties/mining.dm
@@ -8,58 +8,58 @@
/datum/bounty/item/mining/goliath_boat
name = "Goliath Hide Boat"
description = "Commander Menkov wants to participate in the annual Lavaland Regatta. He is asking your shipwrights to build the swiftest boat known to man."
- reward = 10000
+ reward = 5500
wanted_types = list(/obj/vehicle/ridden/lavaboat)
/datum/bounty/item/mining/bone_oar
name = "Bone Oars"
description = "Commander Menkov requires oars to participate in the annual Lavaland Regatta. Ship a pair over."
- reward = 4000
+ reward = 2000
required_count = 2
wanted_types = list(/obj/item/oar)
/datum/bounty/item/mining/bone_axe
name = "Bone Axe"
description = "Station 12 has had their fire axes stolen by marauding clowns. Ship them a bone axe as a replacement."
- reward = 7500
+ reward = 3500
wanted_types = list(/obj/item/twohanded/fireaxe/boneaxe)
/datum/bounty/item/mining/bone_armor
name = "Bone Armor"
description = "Station 14 has volunteered their lizard crew for ballistic armor testing. Ship over some bone armor."
- reward = 5000
+ reward = 2000
wanted_types = list(/obj/item/clothing/suit/armor/bone)
/datum/bounty/item/mining/skull_helmet
name = "Skull Helmet"
description = "Station 42's Head of Security has her birthday tomorrow! We want to suprise her with a fashionable skull helmet."
- reward = 4000
+ reward = 2000
wanted_types = list(/obj/item/clothing/head/helmet/skull)
/datum/bounty/item/mining/bone_talisman
name = "Bone Talismans"
description = "Station 14's Research Director claims that pagan bone talismans protect their wearer. Ship them a few so they can start testing."
- reward = 7500
+ reward = 3500
required_count = 3
wanted_types = list(/obj/item/clothing/accessory/talisman)
/datum/bounty/item/mining/bone_dagger
name = "Bone Daggers"
description = "Central Command's canteen is undergoing budget cuts. Ship over some bone daggers so our Chef can keep working."
- reward = 5000
+ reward = 1000
required_count = 3
wanted_types = list(/obj/item/kitchen/knife/combat/bone)
/datum/bounty/item/mining/basalt
name = "Artificial Basalt Tiles"
description = "Central Command's Ash Walker exhibit needs to be expanded again, we just need some more basalt flooring."
- reward = 5000
+ reward = 2200
required_count = 60
wanted_types = list(/obj/item/stack/tile/basalt)
/datum/bounty/item/mining/fruit
name = "Cactus Fruit"
description = "Central Command's Ash Walker habitat needs more fauna, send us some local fruit seeds!"
- reward = 2000
+ reward = 1000
required_count = 1
wanted_types = list(/obj/item/seeds/lavaland/cactus)
diff --git a/code/modules/cargo/bounties/reagent.dm b/code/modules/cargo/bounties/reagent.dm
index 9f1c76db3d..5137d0a6f3 100644
--- a/code/modules/cargo/bounties/reagent.dm
+++ b/code/modules/cargo/bounties/reagent.dm
@@ -116,11 +116,11 @@ datum/bounty/reagent/complex_drink/New()
wanted_reagent = new reagent_type
name = wanted_reagent.name
description = "CentCom is offering a reward for talented mixologists. Ship a container of [name] to claim the prize."
- reward += rand(0, 4) * 500
+ reward += rand(0, 4) * 300
/datum/bounty/reagent/chemical
name = "Chemical"
- reward = 4000
+ reward = 2750
required_volume = 30
datum/bounty/reagent/chemical/New()
diff --git a/code/modules/cargo/bounties/science.dm b/code/modules/cargo/bounties/science.dm
index 2ac79f6ee8..6102d8d685 100644
--- a/code/modules/cargo/bounties/science.dm
+++ b/code/modules/cargo/bounties/science.dm
@@ -1,116 +1,116 @@
/datum/bounty/item/science/boh
name = "Bag of Holding"
description = "Nanotrasen would make good use of high-capacity backpacks. If you have any, please ship them."
- reward = 10000
+ reward = 5000
wanted_types = list(/obj/item/storage/backpack/holding)
/datum/bounty/item/science/tboh
name = "Trash Bag of Holding"
description = "Nanotrasen would make good use of high-capacity trash bags. If you have any, please ship them."
- reward = 10000
+ reward = 3000
wanted_types = list(/obj/item/storage/backpack/holding)
/datum/bounty/item/science/bluespace_syringe
name = "Bluespace Syringe"
description = "Nanotrasen would make good use of high-capacity syringes. If you have any, please ship them."
- reward = 10000
+ reward = 1500
wanted_types = list(/obj/item/reagent_containers/syringe/bluespace)
/datum/bounty/item/science/bluespace_body_bag
name = "Bluespace Body Bag"
description = "Nanotrasen would make good use of high-capacity body bags. If you have any, please ship them."
- reward = 10000
+ reward = 5000
wanted_types = list(/obj/item/bodybag/bluespace)
/datum/bounty/item/science/nightvision_goggles
name = "Night Vision Goggles"
description = "An electrical storm has busted all the lights at CentCom. While management is waiting for replacements, perhaps some night vision goggles can be shipped?"
- reward = 10000
+ reward = 1000
wanted_types = list(/obj/item/clothing/glasses/night, /obj/item/clothing/glasses/meson/night, /obj/item/clothing/glasses/hud/health/night, /obj/item/clothing/glasses/hud/security/night, /obj/item/clothing/glasses/hud/diagnostic/night)
/datum/bounty/item/science/experimental_welding_tool
name = "Experimental Welding Tool"
description = "A recent accident has left most of CentCom's welding tools exploded. Ship replacements to be rewarded."
- reward = 10000
+ reward = 5000
required_count = 3
wanted_types = list(/obj/item/weldingtool/experimental)
/datum/bounty/item/science/cryostasis_beaker
name = "Cryostasis Beaker"
description = "Chemists at Central Command have discovered a new chemical that can only be held in cryostasis beakers. The only problem is they don't have any! Rectify this to receive payment."
- reward = 10000
+ reward = 2000
wanted_types = list(/obj/item/reagent_containers/glass/beaker/noreact)
/datum/bounty/item/science/diamond_drill
name = "Diamond Mining Drill"
description = "Central Command is willing to pay three months salary in exchange for one diamond mining drill."
- reward = 15000
+ reward = 5500
wanted_types = list(/obj/item/pickaxe/drill/diamonddrill, /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill)
/datum/bounty/item/science/floor_buffer
name = "Floor Buffer Upgrade"
description = "One of CentCom's janitors made a small fortune betting on carp races. Now they'd like to commission an upgrade to their floor buffer."
- reward = 10000
+ reward = 3000
wanted_types = list(/obj/item/janiupgrade)
/datum/bounty/item/science/advanced_mop
name = "Advanced Mop"
description = "Excuse me. I'd like to request $17 for a push broom rebristling. Either that, or an advanced mop."
- reward = 10000
+ reward = 3000
wanted_types = list(/obj/item/mop/advanced)
/datum/bounty/item/science/advanced_egun
name = "Advanced Energy Gun"
description = "With the price of rechargers on the rise, upper management is interested in purchasing guns that are self-powered. If you ship one, they'll pay."
- reward = 10000
+ reward = 1800
wanted_types = list(/obj/item/gun/energy/e_gun/nuclear)
/datum/bounty/item/science/bscells
name = "Bluespace Power Cells"
description = "Someone in upper management keeps using the excuse that his tablet battery dies when he's in the middle of work. This will be the last time he doesn't have his presentation, I swear to -"
- reward = 7000
+ reward = 3000
required_count = 10 //Easy to make
wanted_types = list(/obj/item/stock_parts/cell/bluespace)
/datum/bounty/item/science/t4manip
name = "Femto-Manipulators"
description = "One of our Chief Engineers has OCD. Can you send us some femto-manipulators so he stops complaining that his ID doesn't fit perfectly in the PDA slot?"
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/manipulator/femto)
/datum/bounty/item/science/t4bins
name = "Bluespace Matter Bins"
description = "The local Janitorial union has gone on strike. Can you send us some bluespace bins so we don't have to take out our own trash?"
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/matter_bin/bluespace)
/datum/bounty/item/science/t4capacitor
name = "Quadratic Capacitor"
description = "One of our linguists doesn't understand why they're called Quadratic capacitors. Can you give him a few so he leaves us alone about it?"
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/capacitor/quadratic)
/datum/bounty/item/science/t4triphasic
name = "Triphasic Scanning Module"
description = "One of our scientists got into the liberty caps and is demanding new scanning modules so he can talk to ghosts. At this point we just want him out of our office."
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/scanning_module/triphasic)
/datum/bounty/item/science/t4microlaser
name = "Quad-Ultra Micro-Laser"
description = "The cats on Vega 9 are breeding out of control. We need something to corral them into one area so we can saturation bomb it."
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/micro_laser/quadultra)
/datum/bounty/item/science/fakecrystals
name = "synthetic bluespace crystals"
description = "Don't, uh, tell anyone, but one of our BSA arrays might have had a little... accident. Send us some bluespace crystals so we can recalibrate it before anyone realizes. The whole set uses artificial bluespace crystals, so we need and not any other type of bluespace crystals..."
- reward = 10000
+ reward = 8000
required_count = 5
wanted_types = list(/obj/item/stack/ore/bluespace_crystal/artificial)
exclude_types = list(/obj/item/stack/ore/bluespace_crystal,
diff --git a/code/modules/cargo/bounties/security.dm b/code/modules/cargo/bounties/security.dm
index cae8d10c61..6ed86cd4b7 100644
--- a/code/modules/cargo/bounties/security.dm
+++ b/code/modules/cargo/bounties/security.dm
@@ -1,54 +1,54 @@
/datum/bounty/item/security/riotshotgun
name = "Riot Shotguns"
description = "Hooligans have boarded CentCom! Ship riot shotguns quick, or things are going to get dirty."
- reward = 5000
+ reward = 2500
required_count = 2
wanted_types = list(/obj/item/gun/ballistic/shotgun/riot)
/datum/bounty/item/security/recharger
name = "Rechargers"
description = "Nanotrasen military academy is conducting marksmanship exercises. They request that rechargers be shipped."
- reward = 2000
+ reward = 1700
required_count = 3
wanted_types = list(/obj/machinery/recharger)
/datum/bounty/item/security/practice
name = "Practice Laser Gun"
description = "Nanotrasen Military Academy is conducting routine marksmanship exercises. The clown hid all the practice lasers, and we're not using live weapons after last time."
- reward = 3000
+ reward = 1500
required_count = 3
wanted_types = list(/obj/item/gun/energy/laser/practice)
/datum/bounty/item/security/flashshield
name = "Strobe Shield"
description = "One of our Emergency Response Agents thinks there's vampires in a local station. Send him something to help with his fear of the dark and protect him, too."
- reward = 5000
+ reward = 3000
wanted_types = list(/obj/item/assembly/flash/shield)
/datum/bounty/item/security/sechuds
name = "Sec HUDs"
description = "Nanotrasen military academy has started to train officers how to use Sec HUDs to the fullest affect. Please send spare Sec HUDs so we can teach the men."
- reward = 3000
+ reward = 1250
required_count = 5
wanted_types = list(/obj/item/clothing/glasses/hud/security)
/datum/bounty/item/security/techslugs
name = "Tech Slugs"
description = "Nanotrasen Military Academy is conducting an ammo loading and use lessons, on the new 'Tech Slugs'. Problem is we don't have any, please fix this..."
- reward = 7500
+ reward = 3500
required_count = 15
wanted_types = list(/obj/item/ammo_casing/shotgun/techshell)
-/datum/bounty/item/security/WT550
+/datum/bounty/item/security/wt550
name = "Spare WT-550 clips"
description = "Nanotrasen Military Academy's ammunition is running low, please send in spare ammo for practice."
- reward = 7500
+ reward = 1500
required_count = 5
wanted_types = list(/obj/item/ammo_box/magazine/wt550m9)
/datum/bounty/item/security/pins
name = "Test range firing pins"
description = "Nanotrasen Military Academy just got a new set of guns, sadly they didn't come with any pins. Can you send us some Test range locked firing pins?"
- reward = 5000
+ reward = 2750
required_count = 3
wanted_types = list(/obj/item/firing_pin/test_range)
diff --git a/code/modules/cargo/bounties/slime.dm b/code/modules/cargo/bounties/slime.dm
index 4aa0797c70..f52f995a27 100644
--- a/code/modules/cargo/bounties/slime.dm
+++ b/code/modules/cargo/bounties/slime.dm
@@ -1,10 +1,10 @@
/datum/bounty/item/slime
- reward = 3000
+ reward = 1950
/datum/bounty/item/slime/New()
..()
description = "Nanotrasen's science lead is hunting for the rare and exotic [name]. A bounty has been offered for finding it."
- reward += rand(0, 4) * 500
+ reward += rand(0, 4) * 250
/datum/bounty/item/slime/green
name = "Green Slime Extract"
diff --git a/code/modules/cargo/bounties/special.dm b/code/modules/cargo/bounties/special.dm
index adffaf999a..be91b1d8aa 100644
--- a/code/modules/cargo/bounties/special.dm
+++ b/code/modules/cargo/bounties/special.dm
@@ -1,14 +1,14 @@
/datum/bounty/item/alien_organs
name = "Alien Organs"
description = "Nanotrasen is interested in studying Xenomorph biology. Ship a set of organs to be thoroughly compensated."
- reward = 25000
+ reward = 13500
required_count = 3
wanted_types = list(/obj/item/organ/brain/alien, /obj/item/organ/alien, /obj/item/organ/body_egg/alien_embryo)
/datum/bounty/item/syndicate_documents
name = "Syndicate Documents"
description = "Intel regarding the syndicate is highly prized at CentCom. If you find syndicate documents, ship them. You could save lives."
- reward = 15000
+ reward = 10000
wanted_types = list(/obj/item/documents/syndicate, /obj/item/documents/photocopy)
/datum/bounty/item/syndicate_documents/applies_to(obj/O)
@@ -22,15 +22,15 @@
/datum/bounty/item/adamantine
name = "Adamantine"
description = "Nanotrasen's anomalous materials division is in desparate need for Adamantine. Send them a large shipment and we'll make it worth your while."
- reward = 35000
+ reward = 15000
required_count = 10
wanted_types = list(/obj/item/stack/sheet/mineral/adamantine)
/datum/bounty/more_bounties
name = "More Bounties"
description = "Complete enough bounties and CentCom will issue new ones!"
- reward = 3 // number of bounties
- var/required_bounties = 5
+ reward = 8 // number of bounties
+ var/required_bounties = 3
/datum/bounty/more_bounties/can_claim()
return ..() && completed_bounty_count() >= required_bounties
diff --git a/code/modules/cargo/bounties/virus.dm b/code/modules/cargo/bounties/virus.dm
index 8f078a2668..938ac7708d 100644
--- a/code/modules/cargo/bounties/virus.dm
+++ b/code/modules/cargo/bounties/virus.dm
@@ -1,5 +1,5 @@
/datum/bounty/virus
- reward = 5000
+ reward = 3000
var/shipped = FALSE
var/stat_value = 0
var/stat_name = ""
@@ -11,7 +11,7 @@
stat_value *= -1
name = "Virus ([stat_name] of [stat_value])"
description = "Nanotrasen is interested in a virus with a [stat_name] stat of exactly [stat_value]. Central Command will pay handsomely for such a virus."
- reward += rand(0, 4) * 500
+ reward += rand(0, 4) * 400
/datum/bounty/virus/completion_string()
return shipped ? "Shipped" : "Not Shipped"
diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm
index b7550465d9..9a99f201b3 100644
--- a/code/modules/cargo/exports.dm
+++ b/code/modules/cargo/exports.dm
@@ -1,6 +1,6 @@
/* How it works:
The shuttle arrives at CentCom dock and calls sell(), which recursively loops through all the shuttle contents that are unanchored.
-
+
Each object in the loop is checked for applies_to() of various export datums, except the invalid ones.
*/
@@ -31,7 +31,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
setupExports()
var/list/contents = AM.GetAllContents()
-
+
var/datum/export_report/report = external_report
if(!report) //If we don't have any longer transaction going on
report = new
@@ -58,7 +58,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
var/unit_name = "" // Unit name. Only used in "Received [total_amount] [name]s [message]." message
var/message = ""
var/cost = 100 // Cost of item, in cargo credits. Must not alow for infinite price dupes, see above.
- var/k_elasticity = 1/30 //coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity"
+ var/k_elasticity = 1/20 //coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity" - CIT EDIT 30 - > 20
var/list/export_types = list() // Type of the exported object. If none, the export datum is considered base type.
var/include_subtypes = TRUE // Set to FALSE to make the datum apply only to a strict type.
var/list/exclude_types = list() // Types excluded from export
@@ -125,9 +125,9 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
if(amount <=0 || the_cost <=0)
return FALSE
-
+
report.total_value[src] += the_cost
-
+
if(istype(O, /datum/export/material))
report.total_amount[src] += amount*MINERAL_MATERIAL_AMOUNT
else
@@ -148,7 +148,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
var/total_value = ex.total_value[src]
var/total_amount = ex.total_amount[src]
-
+
var/msg = "[total_value] credits: Received [total_amount] "
if(total_value > 0)
msg = "+" + msg
diff --git a/code/modules/cargo/exports/gear.dm b/code/modules/cargo/exports/gear.dm
index 125e0f708b..7ff14df04c 100644
--- a/code/modules/cargo/exports/gear.dm
+++ b/code/modules/cargo/exports/gear.dm
@@ -1,83 +1,800 @@
/datum/export/gear
+ include_subtypes = FALSE
+
+//blanket
+/datum/export/gear/hat
+ cost = 3
+ unit_name = "clothing"
+ export_types = list(/obj/item/clothing)
+ include_subtypes = TRUE
+
+//Hats
+
+//Blanket
+/datum/export/gear/hat
+ cost = 5
+ unit_name = "hat"
+ export_types = list(/obj/item/clothing/head)
+ include_subtypes = TRUE
/datum/export/gear/sec_helmet
- cost = 100
+ cost = 70
unit_name = "helmet"
export_types = list(/obj/item/clothing/head/helmet/sec)
-/datum/export/gear/sec_armor
- cost = 100
- unit_name = "armor vest"
- export_types = list(/obj/item/clothing/suit/armor/vest)
+/datum/export/gear/sec_soft
+ cost = 50
+ unit_name = "soft sec cap"
+ export_types = list(/obj/item/clothing/head/soft/sec)
-/datum/export/gear/riot_shield
- cost = 100
- unit_name = "riot shield"
- export_types = list(/obj/item/shield/riot)
+/datum/export/gear/sec_helmetalt
+ cost = 50
+ unit_name = "bullet proof helmet"
+ export_types = list(/obj/item/clothing/head/helmet/alt)
+/datum/export/gear/sec_helmetold
+ cost = 10
+ unit_name = "old helmet"
+ export_types = list(/obj/item/clothing/head/helmet/old)
+
+/datum/export/gear/sec_helmetblue
+ cost = 75
+ unit_name = "blue helmet"
+ export_types = list(/obj/item/clothing/head/helmet/blueshirt)
+
+/datum/export/gear/sec_helmetriot
+ cost = 100
+ unit_name = "riot helmet"
+ export_types = list(/obj/item/clothing/head/helmet/riot)
+
+/datum/export/gear/sec_helmet_light
+ cost = 20
+ unit_name = "justice helmet"
+ export_types = list(/obj/item/clothing/head/helmet/justice/escape)
+ include_subtypes = TRUE
+
+/datum/export/gear/syndicate_helmetswat
+ cost = 250
+ unit_name = "syndicate helmet"
+ export_types = list(/obj/item/clothing/head/helmet/swat)
+
+/datum/export/gear/sec_helmetswat
+ cost = 150
+ unit_name = "swat helmet"
+ export_types = list(/obj/item/clothing/head/helmet/swat/nanotrasen)
+
+/datum/export/gear/thunder_helmet
+ cost = 120
+ unit_name = "thunder dome helmet"
+ export_types = list(/obj/item/clothing/head/helmet/thunderdome)
+
+/datum/export/gear/roman_real
+ cost = 30
+ unit_name = "roman helmet"
+ export_types = list(/obj/item/clothing/head/helmet/roman)
+
+/datum/export/gear/roman_realalt
+ cost = 60
+ unit_name = "legionnaire helmet"
+ export_types = list(/obj/item/clothing/head/helmet/roman/legionnaire)
+
+/datum/export/gear/roman_fake
+ cost = 10
+ unit_name = "toy roman helmet"
+ export_types = list(/obj/item/clothing/head/helmet/roman/fake)
+
+/datum/export/gear/roman_fakealt
+ cost = 20
+ unit_name = "toy legionnaire helmet"
+ export_types = list(/obj/item/clothing/head/helmet/roman/legionnaire/fake)
+
+/datum/export/gear/ash_walker_helm
+ cost = 70
+ unit_name = "gladiator helmet"
+ export_types = list(/obj/item/clothing/head/helmet/gladiator)
+
+/datum/export/gear/lasertag
+ cost = 30 //Has armor
+ unit_name = "lasertag helmet"
+ export_types = list(/obj/item/clothing/head/helmet/redtaghelm)
+
+/datum/export/gear/lasertag/blue
+ export_types = list(/obj/item/clothing/head/helmet/bluetaghelm)
+
+/datum/export/gear/knight_helmet
+ cost = 200
+ k_elasticity = 1/5 //Rare, dont flood it
+ unit_name = "knight helmet"
+ export_types = list(/obj/item/clothing/head/helmet/knight, /obj/item/clothing/head/helmet/knight/blue, /obj/item/clothing/head/helmet/knight/yellow, /obj/item/clothing/head/helmet/knight/red)
+
+/datum/export/gear/skull_hat
+ cost = 70
+ k_elasticity = 1/15 //Its just a skull
+ unit_name = "skull"
+ export_types = list(/obj/item/clothing/head/helmet/skull)
+
+/datum/export/gear/durathread_helm
+ cost = 100
+ k_elasticity = 1/15
+ unit_name = "durathread hat"
+ export_types = list(/obj/item/clothing/head/helmet/durathread, /obj/item/clothing/head/beret/durathread, /obj/item/clothing/head/beanie/durathread)
+
+/datum/export/gear/hard_hats
+ cost = 50
+ unit_name = "hard hat"
+ export_types = list(/obj/item/clothing/head/hardhat, /obj/item/clothing/head/hardhat/orange, /obj/item/clothing/head/hardhat/white, /obj/item/clothing/head/hardhat/dblue)
+
+/datum/export/gear/atmos_helm
+ cost = 200 //Armored, fire proof, light, and presser proof
+ unit_name = "atmos hard hat"
+ export_types = list(/obj/item/clothing/head/hardhat/atmos)
+
+/datum/export/gear/crowns
+ cost = 350 //Armored, gold 300cr of gold to make so give them 50 more for working
+ k_elasticity = 1/5 //Anti-floods
+ unit_name = "crown"
+ export_types = list(/obj/item/clothing/head/crown, /obj/item/clothing/head/crown/fancy)
+
+/datum/export/gear/cchat
+ cost = 40
+ unit_name = "centcom hat"
+ export_types = list(/obj/item/clothing/head/centhat)
+
+/datum/export/gear/caphat
+ cost = 150
+ unit_name = "command hat"
+ export_types = list(/obj/item/clothing/head/caphat, /obj/item/clothing/head/caphat/parade, /obj/item/clothing/head/caphat/beret)
+
+/datum/export/gear/hophat
+ cost = 130
+ unit_name = "hop hat"
+ export_types = list(/obj/item/clothing/head/hopcap, /obj/item/clothing/head/hopcap/beret)
+
+/datum/export/gear/dechat
+ cost = 75
+ k_elasticity = 1/8 //Anti-floods
+ unit_name = "fedora"
+ export_types = list(/obj/item/clothing/head/fedora/det_hat, /obj/item/clothing/head/fedora/curator, /obj/item/clothing/head/fedora)
+
+/datum/export/gear/hoshat
+ cost = 140
+ unit_name = "hos hat"
+ export_types = list(/obj/item/clothing/head/HoS, /obj/item/clothing/head/HoS/beret, /obj/item/clothing/head/beret/sec/navyhos)
+
+/datum/export/gear/syndahoshat
+ cost = 300
+ unit_name = "syndicate command hat"
+ export_types = list(/obj/item/clothing/head/HoS/syndicate, /obj/item/clothing/head/HoS/beret/syndicate)
+
+/datum/export/gear/wardenhat
+ cost = 90
+ unit_name = "warden hat"
+ export_types = list(/obj/item/clothing/head/warden, /obj/item/clothing/head/warden/drill, /obj/item/clothing/head/beret/sec/navywarden)
+
+/datum/export/gear/sechats
+ cost = 60
+ unit_name = "sec beret"
+ export_types = list(/obj/item/clothing/head/beret/sec, /obj/item/clothing/head/beret/sec/navyofficer)
+
+/datum/export/gear/berets
+ cost = 30
+ unit_name = "beret"
+ export_types = list(/obj/item/clothing/head/beret/qm, /obj/item/clothing/head/beret/rd, /obj/item/clothing/head/beret/cmo, /obj/item/clothing/head/beret)
+
+/datum/export/gear/berets
+ cost = 30
+ unit_name = "beret"
+ export_types = list(/obj/item/clothing/head/beret/qm, /obj/item/clothing/head/beret/rd, /obj/item/clothing/head/beret/cmo, /obj/item/clothing/head/beret)
+
+/datum/export/gear/collectable
+ cost = 500
+ unit_name = "collectable hat"
+ k_elasticity = 1/10 //dont flood these
+ export_types = list(/obj/item/clothing/head/collectable)
+ include_subtypes = TRUE
+
+/datum/export/gear/fancyhats
+ cost = 75
+ unit_name = "fancy hat"
+ k_elasticity = 1/10 //dont flood these
+ export_types = list(/obj/item/clothing/head/that, /obj/item/clothing/head/bowler, /obj/item/clothing/head/lizard, /obj/item/clothing/head/canada)
+
+/datum/export/gear/welders
+ cost = 30
+ unit_name = "welder helm"
+ k_elasticity = 1/20 //dont flood these
+ export_types = list(/obj/item/clothing/head/welding)
+
+/datum/export/gear/magichat //Magic as is Antags-Wiz/Cults
+ cost = 450
+ unit_name = "magic hat"
+ export_types = list(/obj/item/clothing/head/wizard, /obj/item/clothing/head/culthood, /obj/item/clothing/head/magus, /obj/item/clothing/head/helmet/clockwork)
+ exclude_types = list(/obj/item/clothing/head/wizard/fake, /obj/item/clothing/head/wizard/marisa/fake)
+ include_subtypes = TRUE
+
+//Shoes
+
+//Blanket
+/datum/export/gear/shoes
+ cost = 1 //Really dont want to sell EVERY SHOE EVER - yet*
+ unit_name = "shoes"
+ export_types = list(/obj/item/clothing/shoes)
+ include_subtypes = TRUE
+
+/datum/export/gear/clown_shoesmk
+ cost = 600
+ unit_name = "mk-honk prototype shoes"
+ export_types = list(/obj/item/clothing/shoes/clown_shoes/banana_shoes)
+
+/datum/export/gear/magboots
+ cost = 50
+ unit_name = "magboots"
+ export_types = list(/obj/item/clothing/shoes/magboots, /obj/item/clothing/shoes/magboots/atmos)
+
+/datum/export/gear/nosellboots
+ cost = -5000 //We DONT want scew antags
+ unit_name = "error shipment stolen"
+ export_types = list(/obj/item/clothing/shoes/magboots/advance, /obj/item/clothing/shoes/magboots/deathsquad)
+
+/datum/export/gear/syndamagboots
+ cost = 250
+ unit_name = "blood redmagboots"
+ export_types = list(/obj/item/clothing/shoes/magboots/syndie)
+
+/datum/export/gear/combatboots
+ cost = 30
+ unit_name = "combat boots"
+ export_types = list(/obj/item/clothing/shoes/combat)
+
+/datum/export/gear/swatboots
+ cost = 45
+ unit_name = "swat boots"
+ export_types = list(/obj/item/clothing/shoes/combat/swat)
+
+/datum/export/gear/galoshes
+ cost = 50
+ unit_name = "galoshes"
+ export_types = list(/obj/item/clothing/shoes/galoshes, /obj/item/clothing/shoes/galoshes/dry)
+
+/datum/export/gear/clown
+ cost = 10
+ unit_name = "clown shoes"
+ export_types = list(/obj/item/clothing/shoes/clown_shoes, /obj/item/clothing/shoes/clown_shoes/jester)
+
+/datum/export/gear/dressshoes
+ cost = 10
+ unit_name = "dress shoes"
+ export_types = list(/obj/item/clothing/shoes/laceup, /obj/item/clothing/shoes/singerb, /obj/item/clothing/shoes/singery)
+
+/datum/export/gear/working
+ cost = 15
+ unit_name = "boots"
+ export_types = list(/obj/item/clothing/shoes/jackboots/fast, /obj/item/clothing/shoes/winterboots, /obj/item/clothing/shoes/jackboots, /obj/item/clothing/shoes/workboots, /obj/item/clothing/shoes/workboots/mining)
+
+/datum/export/gear/hopboots
+ cost = 350 //costs 1000 credits for miners to get
+ unit_name = "jump boots"
+ export_types = list(/obj/item/clothing/shoes/bhop)
+
+/datum/export/gear/magicboots //Magic as in Antag - Wiz/Cults
+ cost = 450
+ unit_name = "magic shoes"
+ export_types = list(/obj/item/clothing/shoes/sandal/marisa, /obj/item/clothing/shoes/sandal/magic, /obj/item/clothing/shoes/cult, /obj/item/clothing/shoes/clockwork, /obj/item/clothing/shoes/clown_shoes/taeclowndo, /obj/item/clothing/shoes/sandal/slippers)
+ include_subtypes = TRUE
+
+//Headsets/Ears
+
+//Blanket
+/datum/export/gear/ears
+ cost = 2 //We dont want to sell every headset ever
+ unit_name = "ear gear"
+ export_types = list(/obj/item/clothing/ears, /obj/item/radio/headset)
+ include_subtypes = TRUE
+
+//Gloves
+
+//Blanket
+/datum/export/gear/gloves
+ cost = 4 //Glove crafting can be done
+ unit_name = "gloves"
+ export_types = list(/obj/item/clothing/gloves)
+ include_subtypes = TRUE
+
+/datum/export/gear/boxing
+ cost = 10 //Padding as well as a weapon
+ unit_name = "boxing gloves"
+ export_types = list(/obj/item/clothing/gloves/boxing)
+ include_subtypes = TRUE
+
+/datum/export/gear/combatgloves
+ cost = 80
+ unit_name = "combat gloves"
+ export_types = list(/obj/item/clothing/gloves/combat, /obj/item/clothing/gloves/rapid, /obj/item/clothing/gloves/krav_maga)
+ include_subtypes = TRUE
+
+/datum/export/gear/bonegloves
+ cost = 30
+ unit_name = "bone bracers"
+ export_types = list(/obj/item/clothing/gloves/bracer)
+
+/datum/export/gear/yellowgloves
+ cost = 50
+ unit_name = "insulated gloves"
+ export_types = list(/obj/item/clothing/gloves/color/yellow, /obj/item/clothing/gloves/color/red/insulated)
+
+/datum/export/gear/leathergloves
+ cost = 20
+ unit_name = "leather gloves"
+ export_types = list(/obj/item/clothing/gloves/botanic_leather)
+
+/datum/export/gear/fancy
+ cost = 25
+ unit_name = "fancy gloves"
+ export_types = list(/obj/item/clothing/gloves/color/black, /obj/item/clothing/gloves/color/captain, /obj/item/clothing/gloves/color/white)
+
+/datum/export/gear/magicgloves//Magic as in Antag - Wiz/Cults
+ cost = 400
+ unit_name = "magic gloves"
+ export_types = list(/obj/item/clothing/gloves/clockwork)
+ include_subtypes = TRUE
+
+//Ties/neck
+
+//Blanket
+/datum/export/gear/neck
+ cost = 5 //Fancy!
+ unit_name = "neck based gear"
+ export_types = list(/obj/item/clothing/neck)
+ include_subtypes = TRUE
+
+/datum/export/gear/collar
+ cost = 7
+ unit_name = "collar"
+ export_types = list(/obj/item/clothing/neck/petcollar)
+ include_subtypes = TRUE
+
+/datum/export/gear/bling
+ cost = 15 //Needs a coin
+ unit_name = "gold plated necklace"
+ export_types = list(/obj/item/clothing/neck/necklace/dope)
+
+//masks
+
+//Blanket
+/datum/export/gear/masks
+ cost = 3 //Mostly just fake stuff and clowngear
+ unit_name = "face gear"
+ export_types = list(/obj/item/clothing/mask)
+ include_subtypes = TRUE
+
+/datum/export/gear/gasmask
+ cost = 4
+ unit_name = "gas mask"
+ export_types = list(/obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas/glass)
+
+/datum/export/gear/minermask
+ cost = 10
+ unit_name = "armored mask"
+ export_types = list(/obj/item/clothing/mask/gas/welding, /obj/item/clothing/mask/gas/explorer, /obj/item/clothing/mask/gas/syndicate)
+
+/datum/export/gear/sechailer
+ cost = 6
+ unit_name = "sec hailer"
+ export_types = list(/obj/item/clothing/mask/gas/sechailer)
+ include_subtypes = TRUE
/datum/export/gear/mask/breath
cost = 2
unit_name = "breath mask"
export_types = list(/obj/item/clothing/mask/breath)
-/datum/export/gear/mask/gas
- cost = 10
- unit_name = "gas mask"
- export_types = list(/obj/item/clothing/mask/gas)
- include_subtypes = FALSE
+//Hardsuits //If you steal/fine more they are worth selling
+//Blanket
+/datum/export/gear/hardsuit
+ cost = 250 //Its just metal/plastic after all
+ unit_name = "unknown hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit)
+ include_subtypes = TRUE
-/datum/export/gear/space/helmet
- cost = 75
+/datum/export/gear/engi_hardsuit
+ cost = 500
+ unit_name = "engine hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/engine)
+
+/datum/export/gear/atmos_hardsuit
+ cost = 600
+ unit_name = "atmos hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/engine/atmos)
+
+/datum/export/gear/engi_hardsuit
+ cost = 1000
+ unit_name = "elite engine hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/engine/elite)
+
+/datum/export/gear/mining_hardsuit
+ cost = 350 //common
+ unit_name = "mining hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/mining)
+
+/datum/export/gear/sec_hardsuit
+ cost = 750
+ unit_name = "sec hardsuit"
+ export_types = list(/obj/item/clothing/head/helmet/space/hardsuit/mining, /obj/item/clothing/head/helmet/space/hardsuit/syndi/owl)
+
+/datum/export/gear/syndi_hardsuit
+ cost = 1250
+ unit_name = "syndi hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/syndi)
+
+/datum/export/gear/syndi_hardsuit
+ cost = 2750
+ unit_name = "elite syndi hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/syndi/elite)
+
+/datum/export/gear/medical_hardsuit
+ cost = 350 //Not all that good
+ unit_name = "meidcal hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/medical)
+
+/datum/export/gear/rd_hardsuit
+ cost = 850 //rare
+ unit_name = "prototype hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/rd)
+
+/datum/export/gear/sec_hardsuit
+ cost = 750
+ unit_name = "sec hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/security)
+
+/datum/export/gear/command_hardsuit
+ cost = 1300
+ unit_name = "command hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/security/hos, /obj/item/clothing/suit/space/hardsuit/captain)
+
+/datum/export/gear/magic_hardsuit
+ cost = 3000
+ unit_name = "magic hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/wizard, /obj/item/clothing/suit/space/hardsuit/shielded/wizard, /obj/item/clothing/suit/space/hardsuit/cult)
+ include_subtypes = TRUE
+
+/datum/export/gear/shield_hardsuit
+ cost = 2000
+ unit_name = "shielded hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/shielded)
+ include_subtypes = TRUE
+
+/datum/export/gear/rigs
+ cost = 2750
+ unit_name = "RIG"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/ancient, /obj/item/clothing/suit/space/hardsuit/ancient/mason)
+
+//Soft Suits
+
+//Blanket
+datum/export/gear/space/helmet
+ cost = 55
unit_name = "space helmet"
- export_types = list(/obj/item/clothing/head/helmet/space, /obj/item/clothing/head/helmet/space/eva, /obj/item/clothing/head/helmet/space/nasavoid)
- include_subtypes = FALSE
+ export_types = list(/obj/item/clothing/head/helmet/space)
+ include_subtypes = TRUE
/datum/export/gear/space/suit
- cost = 150
+ cost = 60
unit_name = "space suit"
- export_types = list(/obj/item/clothing/suit/space, /obj/item/clothing/suit/space/eva, /obj/item/clothing/suit/space/nasavoid)
- include_subtypes = FALSE
+ export_types = list(/obj/item/clothing/suit/space)
+ include_subtypes = TRUE
+datum/export/gear/space/helmet/plasma
+ cost = 100
+ unit_name = "plasmaman space helmet"
+ export_types = list(/obj/item/clothing/suit/space/eva/plasmaman)
-/datum/export/gear/space/syndiehelmet
- cost = 150
- unit_name = "Syndicate space helmet"
+/datum/export/gear/space/suit/plasma
+ cost = 100
+ unit_name = "plasmaman space suit"
+ export_types = list(/obj/item/clothing/suit/space/eva/plasmaman)
+
+datum/export/gear/space/helmet/synda
+ cost = 150 //Flash proof
+ unit_name = "syndicate space helmet"
export_types = list(/obj/item/clothing/head/helmet/space/syndicate)
+ include_subtypes = TRUE
-/datum/export/gear/space/syndiesuit
- cost = 300
- unit_name = "Syndicate space suit"
- export_types = list(/obj/item/clothing/suit/space/syndicate)
+/datum/export/gear/space/suit/synda
+ cost = 150
+ unit_name = "syndicate space suit"
+ export_types = list(/obj/item/clothing/head/helmet/space/syndicate)
+ include_subtypes = TRUE
+//Glasses
+
+//Blanket
+datum/export/gear/glasses //glasses are not worth selling
+ cost = 3
+ unit_name = "glasses"
+ export_types = list(/obj/item/clothing/glasses)
+ include_subtypes = TRUE
+
+/datum/export/gear/mesons
+ cost = 6
+ unit_name = "mesons"
+ export_types = list(/obj/item/clothing/glasses/meson, /obj/item/clothing/glasses/material/mining)
+ include_subtypes = TRUE
+
+/datum/export/gear/scigoggles
+ cost = 8
+ unit_name = "chem giggles"
+ export_types = list(/obj/item/clothing/glasses/science)
+ include_subtypes = TRUE
+
+/datum/export/gear/nvgoggles
+ cost = 20
+ unit_name = "night vison giggles"
+ export_types = list(/obj/item/clothing/glasses/night)
+ include_subtypes = TRUE
+
+/datum/export/gear/sunglasses
+ cost = 12
+ unit_name = "sunglasses"
+ export_types = list(/obj/item/clothing/glasses/sunglasses)
+ include_subtypes = TRUE
+
+/datum/export/gear/huds
+ cost = 10
+ unit_name = "huds"
+ export_types = list(/obj/item/clothing/glasses/hud)
+ include_subtypes = TRUE
+
+/datum/export/gear/huds/glasses
+ cost = 22
+ export_types = list(/obj/item/clothing/glasses/hud/health/sunglasses, /obj/item/clothing/glasses/hud/security/sunglasses)
+
+/datum/export/gear/weldinggoggles
+ cost = 20
+ unit_name = "welding goggles"
+ export_types = list(/obj/item/clothing/glasses/welding)
+ include_subtypes = TRUE
+
+/datum/export/gear/thermals
+ cost = 30
+ unit_name = "heat seeing goggles"
+ export_types = list(/obj/item/clothing/glasses/thermal, /obj/item/clothing/glasses/hud/toggle/thermal)
+ include_subtypes = TRUE
+
+/datum/export/gear/magic_glasses
+ cost = 140
+ unit_name = "magic goggles"
+ export_types = list(/obj/item/clothing/glasses/godeye, /obj/item/clothing/glasses/hud/health/night/cultblind, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor)
+ include_subtypes = TRUE
+
+//////////
+//UNDER///
+//////////
+
+/datum/export/gear/jumpsuit
+ cost = 3
+ unit_name = "jumpsuit"
+ k_elasticity = 1/100 //you can craft white jumpsuits, if someone does that 300 times, they deserve the 800 credits
+ export_types = list(/obj/item/clothing/under)
+ include_subtypes = TRUE
+
+/datum/export/gear/fancy_jumpsuit
+ cost = 10
+ unit_name = "fancy clothing"
+ k_elasticity = 1/90 //These will be what sells
+ export_types = list(/obj/item/clothing/under/scratch, /obj/item/clothing/under/sl_suit, /obj/item/clothing/under/rank/vice, /obj/item/clothing/under/suit_jacket, \
+ /obj/item/clothing/under/burial, /obj/item/clothing/under/skirt/black, /obj/item/clothing/under/captainparade, /obj/item/clothing/under/hosparademale, \
+ /obj/item/clothing/under/hosparadefem, /obj/item/clothing/under/assistantformal, /obj/item/clothing/under/stripeddress, /obj/item/clothing/under/redeveninggown, \
+ /obj/item/clothing/under/plaid_skirt, /obj/item/clothing/under/geisha, /obj/item/clothing/under/trek, /obj/item/clothing/under/wedding, /obj/item/clothing/under/aviatoruniform,\
+ /obj/item/clothing/under/mega, /obj/item/clothing/under/cia, /obj/item/clothing/under/casualwear, /obj/item/clothing/under/rank)
+ include_subtypes = TRUE
+
+/datum/export/gear/armored_jumpsuit
+ cost = 15
+ unit_name = "armored_jumpsuit"
+ k_elasticity = 1/90 //These will be what sells
+ export_types = list(/obj/item/clothing/under/durathread, /obj/item/clothing/under/rank/security, /obj/item/clothing/under/plasmaman, /obj/item/clothing/under/syndicate, \
+ /obj/item/clothing/under/rank/det, /obj/item/clothing/under/rank/head_of_security, /obj/item/clothing/under/rank/security/spacepol)
+ exclude_types = list(/obj/item/clothing/under/syndicate/tacticool, /obj/item/clothing/under/syndicate/tacticool/skirt)
+ include_subtypes = TRUE
+
+/datum/export/gear/jumpsuit_addon
+ cost = 12 //Few and rare as well as quick drop off of vaule
+ unit_name = "jumpsuit add on"
+ k_elasticity = 1/10
+ export_types = list(/obj/item/clothing/accessory)
+ include_subtypes = TRUE
+
+/datum/export/gear/robes_magic
+ cost = 120
+ unit_name = "magic robes"
+ export_types = list(/obj/item/clothing/suit/wizrobe, /obj/item/clothing/suit/cultrobes, /obj/item/clothing/suit/magusred, /obj/item/clothing/suit/hooded/cultrobes)
+ exclude_types = list(/obj/item/clothing/suit/wizrobe/fake)
+ include_subtypes = TRUE
+
+//Amror
+/datum/export/gear/armor
+ cost = 80
+ unit_name = "misc armor"
+ export_types = list(/obj/item/clothing/suit/armor)
+ include_subtypes = TRUE
+
+/datum/export/gear/sec_armor
+ cost = 180
+ unit_name = "sec armor"
+ export_types = list(/obj/item/clothing/suit/armor/vest/leather, /obj/item/clothing/suit/armor/bulletproof, /obj/item/clothing/suit/armor/vest/det_suit)
+ include_subtypes = TRUE
+
+/datum/export/gear/hosarmor
+ cost = 380
+ unit_name = "hos armor"
+ export_types = list(/obj/item/clothing/suit/armor/hos)
+ include_subtypes = TRUE
+
+/datum/export/gear/wardenarmor
+ cost = 280
+ unit_name = "warden armor"
+ export_types = list(/obj/item/clothing/suit/armor/vest/warden)
+ include_subtypes = TRUE
+
+/datum/export/gear/reflector
+ cost = 500
+ unit_name = "reflector armor"
+ export_types = list(/obj/item/clothing/suit/armor/laserproof)
+ include_subtypes = TRUE
+
+/datum/export/gear/heavy_armor
+ cost = 600 //REALY hard to fine/make takes lots of slimes
+ unit_name = "heavy armor"
+ export_types = list(/obj/item/clothing/suit/armor/heavy)
+ include_subtypes = TRUE
+
+/datum/export/gear/plate_armor
+ cost = 200
+ unit_name = "plate armor"
+ export_types = list(/obj/item/clothing/suit/armor/riot/knight)
+ include_subtypes = TRUE
+
+/datum/export/gear/riot_armor
+ cost = 250
+ unit_name = "riot armor"
+ export_types = list(/obj/item/clothing/suit/armor/riot)
+ include_subtypes = TRUE
+
+/datum/export/gear/bone_armor
+ cost = 50
+ unit_name = "bone armor"
+ export_types = list(/obj/item/clothing/suit/armor/bone)
+ include_subtypes = TRUE
+
+/datum/export/gear/swat_armor
+ cost = 350
+ unit_name = "swat mki armor"
+ export_types = list(/obj/item/clothing/suit/space/swat)
+ include_subtypes = TRUE
+
+/datum/export/gear/dragon_armor
+ cost = 750
+ unit_name = "drake bone armor"
+ export_types = list(/obj/item/clothing/suit/hooded/cloak/drake)
+ include_subtypes = TRUE
+
+/datum/export/gear/commandamor
+ cost = 480
+ unit_name = "command armor"
+ export_types = list(/obj/item/clothing/suit/armor/vest/capcarapace, /obj/item/clothing/suit/armor/centcom)
+ include_subtypes = TRUE
+
+/datum/export/gear/reactive_base
+ cost = 600
+ k_elasticity = 1/2 //Lets not go over board
+ unit_name = "hollow reactive armor"
+ export_types = list(/obj/item/reactive_armour_shell, /obj/item/clothing/suit/armor/reactive)
+
+/datum/export/gear/reactive_active
+ cost = 1200
+ k_elasticity = 1/3 //Lets not go over board
+ unit_name = "working reactive armor"
+ export_types = list(/obj/item/clothing/suit/armor/reactive/repulse, /obj/item/clothing/suit/armor/reactive/tesla, /obj/item/clothing/suit/armor/reactive/teleport)
+
+///////////////////////////
+//Bomb/Rad/Bio Suits/Fire//
+///////////////////////////
/datum/export/gear/radhelmet
- cost = 50
+ cost = 20
unit_name = "radsuit hood"
export_types = list(/obj/item/clothing/head/radiation)
/datum/export/gear/radsuit
- cost = 100
+ cost = 40
unit_name = "radsuit"
export_types = list(/obj/item/clothing/suit/radiation)
+/datum/export/gear/firehelmet
+ cost = 10
+ unit_name = "firesuit helmet"
+ export_types = list(/obj/item/clothing/head/hardhat/red)
+
+/datum/export/gear/fireatmos
+ cost = 120
+ unit_name = "atmos firesuit"
+ export_types = list(/obj/item/clothing/suit/fire/atmos)
+
+/datum/export/gear/firesuit
+ cost = 20
+ unit_name = "firesuit"
+ export_types = list(/obj/item/clothing/suit/fire, /obj/item/clothing/suit/fire/firefighter, /obj/item/clothing/suit/fire/heavy)
+
/datum/export/gear/biohood
- cost = 50
+ cost = 40
unit_name = "biosuit hood"
export_types = list(/obj/item/clothing/head/bio_hood)
+ include_subtypes = TRUE
/datum/export/gear/biosuit
- cost = 100
+ cost = 60
unit_name = "biosuit"
export_types = list(/obj/item/clothing/suit/bio_suit)
+ include_subtypes = TRUE
/datum/export/gear/bombhelmet
- cost = 50
+ cost = 40
unit_name = "bomb suit hood"
export_types = list(/obj/item/clothing/head/bomb_hood)
+ include_subtypes = TRUE
/datum/export/gear/bombsuit
- cost = 100
+ cost = 60
unit_name = "bomb suit"
export_types = list(/obj/item/clothing/suit/bomb_suit)
+ include_subtypes = TRUE
+
+////////////////////
+//Cloaks and Coats//
+////////////////////
+
+/datum/export/gear/cloaks
+ cost = 30
+ unit_name = "cloak"
+ export_types = list(/obj/item/clothing/neck/cloak)
+ include_subtypes = TRUE
+
+/datum/export/gear/cloaksmining
+ cost = 90
+ unit_name = "lava land cloak"
+ export_types = list(/obj/item/clothing/suit/hooded/cloak/goliath)
+ include_subtypes = TRUE
+
+/datum/export/gear/labcoats
+ cost = 15
+ unit_name = "labcoats"
+ export_types = list(/obj/item/clothing/suit/toggle/labcoat)
+ include_subtypes = TRUE
+
+/datum/export/gear/wintercoats
+ cost = 25
+ unit_name = "wintercoats"
+ export_types = list(/obj/item/clothing/suit/hooded/wintercoat)
+ include_subtypes = TRUE
+
+//////////
+//SUITS///
+//////////
+
+/datum/export/gear/suits
+ cost = 40
+ unit_name = "suit"
+ export_types = list(/obj/item/clothing/suit)
+ include_subtypes = TRUE
+
+//////////////////////
+//Chameleon Gear//////
+//////////////////////
+/datum/export/gear/chameleon //Selling a full kit is easy money for 2 tc
+ cost = 280
+ unit_name = "chameleon item"
+ export_types = list(/obj/item/clothing/head/chameleon, /obj/item/clothing/mask/chameleon, /obj/item/clothing/under/chameleon, /obj/item/clothing/suit/chameleon, /obj/item/clothing/glasses/chameleon,\
+ /obj/item/clothing/gloves/chameleon, /obj/item/clothing/head/chameleon, /obj/item/clothing/shoes/chameleon, /obj/item/storage/backpack/chameleon, \
+ /obj/item/storage/belt/chameleon, /obj/item/radio/headset/chameleon, /obj/item/pda/chameleon, /obj/item/stamp/chameleon, /obj/item/clothing/neck/cloak/chameleon)
+ include_subtypes = TRUE
\ No newline at end of file
diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm
index bf77d836fb..88ff5f4729 100644
--- a/code/modules/cargo/exports/large_objects.dm
+++ b/code/modules/cargo/exports/large_objects.dm
@@ -1,3 +1,6 @@
+/datum/export/large
+ k_elasticity = 0
+
/datum/export/large/crate
cost = 500
k_elasticity = 0
@@ -21,13 +24,13 @@
export_types = list(/obj/structure/ore_box)
/datum/export/large/crate/wood
- cost = 240
+ cost = 140
unit_name = "wooden crate"
export_types = list(/obj/structure/closet/crate/wooden)
exclude_types = list()
/datum/export/large/crate/coffin
- cost = 250//50 wooden crates cost 2000 points, and you can make 10 coffins in seconds with those planks. Each coffin selling for 250 means you can make a net gain of 500 points for wasting your time making coffins.
+ cost = 150
unit_name = "coffin"
export_types = list(/obj/structure/closet/crate/coffin)
@@ -131,16 +134,48 @@
unit_name = "security barrier"
export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security)
+/datum/export/large/frame
+ cost = 20
+ unit_name = "structure frame"
+ export_types = list(/obj/structure/frame, /obj/structure/table_frame)
+ include_subtypes = TRUE
+
+/datum/export/large/pacman
+ cost = 125
+ unit_name = "pacman"
+ export_types = list(/obj/machinery/power/port_gen/pacman)
+
+/datum/export/large/pacman
+ cost = 150
+ unit_name = "super pacman"
+ export_types = list(/obj/machinery/power/port_gen/pacman/super)
+
+/datum/export/large/pacman
+ cost = 175
+ unit_name = "mrs super pacman"
+ export_types = list(/obj/machinery/power/port_gen/pacman/mrs)
+
+/datum/export/large/hydroponics
+ cost = 120
+ unit_name = "hydroponics tray"
+ export_types = list(/obj/machinery/hydroponics)
+
+/datum/export/large/nice_chair
+ cost = 12
+ unit_name = "Padded Chair"
+ export_types = list(/obj/structure/chair/comfy)
+
/datum/export/large/gas_canister
cost = 10 //Base cost of canister. You get more for nice gases inside.
unit_name = "Gas Canister"
export_types = list(/obj/machinery/portable_atmospherics/canister)
+
/datum/export/large/gas_canister/get_cost(obj/O)
var/obj/machinery/portable_atmospherics/canister/C = O
var/worth = 10
var/gases = C.air_contents.gases
- worth += gases[/datum/gas/bz]*4
+ worth += gases[/datum/gas/bz]*4
worth += gases[/datum/gas/stimulum]*25
worth += gases[/datum/gas/hypernoblium]*1000
worth += gases[/datum/gas/miasma]*15
@@ -149,86 +184,169 @@
worth += gases[/datum/gas/nitryl]*30
return worth
-/datum/export/large/odysseus
+
+//////////////
+//Matstatues//
+//////////////
+
+/datum/export/large/nukestatue
+ cost = 175
+ unit_name = "Nuke statue"
+ export_types = list(/obj/structure/statue/uranium/nuke)
+
+/datum/export/large/engstatue
+ cost = 175
+ unit_name = "Engine statue"
+ export_types = list(/obj/structure/statue/uranium/eng)
+
+/datum/export/large/plasmastatue
+ cost = 720
+ unit_name = "Scientist statue"
+ export_types = list(/obj/structure/statue/plasma/scientist)
+
+/datum/export/large/hosstatue
+ cost = 225
+ unit_name = "HoS statue"
+ export_types = list(/obj/structure/statue/gold/hos)
+
+/datum/export/large/rdstatue
+ cost = 225
+ unit_name = "RD statue"
+ export_types = list(/obj/structure/statue/gold/rd)
+
+/datum/export/large/hopstatue
+ cost = 225
+ unit_name = "HoP statue"
+ export_types = list(/obj/structure/statue/gold/hop)
+
+/datum/export/large/cmostatue
+ cost = 225
+ unit_name = "CMO statue"
+ export_types = list(/obj/structure/statue/gold/cmo)
+
+/datum/export/large/cestatue
+ cost = 225
+ unit_name = "CE statue"
+ export_types = list(/obj/structure/statue/gold/ce)
+
+/datum/export/large/mdstatue
+ cost = 200
+ unit_name = "MD statue"
+ export_types = list(/obj/structure/statue/silver/md)
+
+/datum/export/large/janitorstatue
+ cost = 200
+ unit_name = "Janitor statue"
+ export_types = list(/obj/structure/statue/silver/janitor)
+
+/datum/export/large/secstatue
+ cost = 200
+ unit_name = "Sec statue"
+ export_types = list(/obj/structure/statue/silver/sec)
+
+/datum/export/large/medborgstatue
+ cost = 200
+ unit_name = "Medborg statue"
+ export_types = list(/obj/structure/statue/silver/medborg)
+
+/datum/export/large/secborgstatue
+ cost = 200
+ unit_name = "Secborg statue"
+ export_types = list(/obj/structure/statue/silver/secborg)
+
+/datum/export/large/capstatue
+ cost = 1200
+ unit_name = "Captain statue"
+ export_types = list(/obj/structure/statue/diamond/captain)
+
+/datum/export/large/aistatue
+ cost = 1200
+ unit_name = "AI statue"
+ export_types = list(/obj/structure/statue/diamond/ai1, /obj/structure/statue/diamond/ai2)
+
+/datum/export/large/clownstatue
+ cost = 2750
+ unit_name = "Clown statue"
+ export_types = list(/obj/structure/statue/bananium/clown)
+
+/datum/export/large/sandstatue
+ cost = 90 //Big cash
+ unit_name = "sandstone statue"
+ export_types = list(/obj/structure/statue/sandstone/assistant)
+
+////////////
+//MECHS/////
+////////////
+
+/datum/export/large/mech
+ include_subtypes = FALSE
+
+/datum/export/large/mech/odysseus
cost = 5500
unit_name = "working odysseus"
export_types = list(/obj/mecha/medical/odysseus)
- include_subtypes = FALSE
-/datum/export/large/ripley
+/datum/export/large/mech/ripley
cost = 6500
unit_name = "working ripley"
export_types = list(/obj/mecha/working/ripley)
- include_subtypes = FALSE
-/datum/export/large/firefighter
+/datum/export/large/mech/firefighter
cost = 9000
unit_name = "working firefighter"
export_types = list(/obj/mecha/working/ripley/firefighter)
- include_subtypes = FALSE
-/datum/export/large/gygax
+/datum/export/large/mech/gygax
cost = 19000
unit_name = "working gygax"
export_types = list(/obj/mecha/combat/gygax)
- include_subtypes = FALSE
-/datum/export/large/durand
+/datum/export/large/mech/durand
cost = 10000
unit_name = "working durand"
export_types = list(/obj/mecha/combat/durand)
- include_subtypes = FALSE
-/datum/export/large/phazon
+/datum/export/large/mech/phazon
cost = 25000 //Little over half do to needing a core
unit_name = "working phazon"
export_types = list(/obj/mecha/combat/phazon)
- include_subtypes = FALSE
-/datum/export/large/marauder
+/datum/export/large/mech/marauder
cost = 15000 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price.
unit_name = "working marauder"
export_types = list(/obj/mecha/combat/marauder)
- include_subtypes = FALSE
-/datum/export/large/deathripley
+/datum/export/large/mech/deathripley
cost = 8500 //Still a "Combat class" mech - Illegal tech as well! 165% "normal" boundy price.
unit_name = "working illegally modified"
export_types = list(/obj/mecha/working/ripley/deathripley)
- include_subtypes = FALSE
-/datum/export/large/gygaxdark
+/datum/export/large/mech/gygaxdark
cost = 28500 //Still a Combat class mech - Illegal tech as well! 150% "normal" boundy price.
unit_name = "working illegally modified gygax"
export_types = list(/obj/mecha/combat/gygax/dark)
- include_subtypes = FALSE
-/datum/export/large/oldripley
+/datum/export/large/mech/oldripley
cost = 6250 //old mech - Scrap metal ! 50% "normal" boundy price.
unit_name = "working miner ripley"
export_types = list(/obj/mecha/working/ripley/mining)
- include_subtypes = FALSE
-/datum/export/large/honk
+/datum/export/large/mech/honk
cost = 12000 //Still a "Combat class" mech - Comats bordem honk!
unit_name = "working honker"
export_types = list(/obj/mecha/combat/honker)
- include_subtypes = FALSE
-/datum/export/large/reticence
+/datum/export/large/mech/reticence
cost = 12000 //Still a "Combat class" mech - Has cloking and lethal weaponds.
unit_name = "working reticence"
export_types = list(/obj/mecha/combat/reticence)
- include_subtypes = FALSE
-/datum/export/large/seraph
+/datum/export/large/mech/seraph
cost = 25500 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price.
unit_name = "working seraph"
export_types = list(/obj/mecha/combat/marauder/seraph)
- include_subtypes = FALSE
-/datum/export/large/mauler
+/datum/export/large/mech/mauler
cost = 12000 //Still a Combat class mech - CC lethal weaponds.
unit_name = "working legally modified marauder"
export_types = list(/obj/mecha/combat/marauder/mauler)
- include_subtypes = FALSE
diff --git a/code/modules/cargo/exports/manifest.dm b/code/modules/cargo/exports/manifest.dm
index d03f5a46ce..60515781f9 100644
--- a/code/modules/cargo/exports/manifest.dm
+++ b/code/modules/cargo/exports/manifest.dm
@@ -80,7 +80,7 @@
// Paper work done correctly
/datum/export/paperwork_correct
- cost = 150
+ cost = 120 // finicky number 20 x 120 = 2400 per crate
k_elasticity = 0
unit_name = "correct paperwork"
export_types = list(/obj/item/folder/paperwork_correct)
diff --git a/code/modules/cargo/exports/materials.dm b/code/modules/cargo/exports/materials.dm
index 04dc76fd52..cd11660ed8 100644
--- a/code/modules/cargo/exports/materials.dm
+++ b/code/modules/cargo/exports/materials.dm
@@ -1,4 +1,5 @@
/datum/export/material
+ k_elasticity = 0
cost = 5 // Cost per MINERAL_MATERIAL_AMOUNT, which is 2000cm3 as of April 2016.
message = "cm3 of developer's tears. Please, report this on github"
var/material_id = null
@@ -27,51 +28,56 @@
return round(amount/MINERAL_MATERIAL_AMOUNT)
-// Materials. Nothing but plasma is really worth selling. Better leave it all to RnD and sell some plasma instead.
+// Materials. Selling raw can lead to a big payout but takes a lot of work for miners to get a lot. Best to craft art/rnd gear
/datum/export/material/bananium
- cost = 1000
+ cost = 500
material_id = MAT_BANANIUM
message = "cm3 of bananium"
/datum/export/material/diamond
- cost = 500
+ cost = 250
material_id = MAT_DIAMOND
message = "cm3 of diamonds"
/datum/export/material/plasma
- cost = 200
+ cost = 100
k_elasticity = 0
material_id = MAT_PLASMA
message = "cm3 of plasma"
/datum/export/material/uranium
- cost = 100
+ cost = 50
material_id = MAT_URANIUM
message = "cm3 of uranium"
/datum/export/material/gold
- cost = 125
+ cost = 60
material_id = MAT_GOLD
message = "cm3 of gold"
/datum/export/material/silver
- cost = 50
+ cost = 25
material_id = MAT_SILVER
message = "cm3 of silver"
/datum/export/material/titanium
- cost = 125
+ cost = 60
material_id = MAT_TITANIUM
message = "cm3 of titanium"
/datum/export/material/plastitanium
- cost = 325 // plasma + titanium costs
+ cost = 165 // plasma + titanium costs
material_id = MAT_TITANIUM // code can only check for one material_id; plastitanium is half plasma, half titanium
message = "cm3 of plastitanium"
-/datum/export/material/metal
+/datum/export/material/plastic
cost = 5
+ material_id = MAT_PLASTIC
+ message = "cm3 of plastic"
+
+/datum/export/material/metal
+ cost = 3
message = "cm3 of metal"
material_id = MAT_METAL
export_types = list(
@@ -79,7 +85,7 @@
/obj/item/stack/rods, /obj/item/stack/ore, /obj/item/coin)
/datum/export/material/glass
- cost = 5
+ cost = 3
message = "cm3 of glass"
material_id = MAT_GLASS
export_types = list(/obj/item/stack/sheet/glass, /obj/item/stack/ore,
diff --git a/code/modules/cargo/exports/orgains_robotics.dm b/code/modules/cargo/exports/orgains_robotics.dm
new file mode 100644
index 0000000000..924d27c1d2
--- /dev/null
+++ b/code/modules/cargo/exports/orgains_robotics.dm
@@ -0,0 +1,141 @@
+// Orgains and Robotics exports. Hearts, new lims, implants, etc.
+
+/datum/export/robotics
+ include_subtypes = FALSE
+ k_elasticity = 0 //ALWAYS worth selling upgrades
+
+/datum/export/implant
+ include_subtypes = FALSE
+ k_elasticity = 0 //ALWAYS worth selling upgrades
+
+/datum/export/orgains
+ include_subtypes = TRUE
+ k_elasticity = 0 //ALWAYS worth selling orgains
+
+/datum/export/implant/autodoc
+ cost = 150
+ unit_name = "autsurgeon"
+ export_types = list(/obj/item/autosurgeon)
+ include_subtypes = TRUE
+
+/datum/export/implant/implant
+ cost = 50
+ unit_name = "implant"
+ export_types = list(/obj/item/implant)
+ include_subtypes = TRUE
+
+/datum/export/implant/cnsreboot
+ cost = 350
+ unit_name = "anti drop implant"
+ export_types = list(/obj/item/organ/cyberimp/brain/anti_drop)
+
+/datum/export/implant/antistun
+ cost = 450
+ unit_name = "rebooter implant"
+ export_types = list(/obj/item/organ/cyberimp/brain/anti_stun)
+
+/datum/export/implant/breathtube
+ cost = 150
+ unit_name = "breath implant"
+ export_types = list(/obj/item/organ/cyberimp/mouth/breathing_tube)
+
+/datum/export/implant/hungerbgone
+ cost = 200
+ unit_name = "nutriment implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/nutriment)
+
+/datum/export/implant/hungerbgoneplus
+ cost = 300
+ unit_name = "upgraded nutriment implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/nutriment/plus)
+
+/datum/export/implant/reviver
+ cost = 350
+ unit_name = "reviver implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/reviver)
+
+/datum/export/implant/thrusters
+ cost = 150
+ unit_name = "thrusters set implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/thrusters)
+
+/datum/export/implant/thrusters
+ cost = 150
+ unit_name = "thrusters set implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/thrusters)
+
+/datum/export/implant/arm
+ cost = 200
+ unit_name = "arm set implant"
+ export_types = list(/obj/item/organ/cyberimp/arm/toolset, /obj/item/organ/cyberimp/arm/surgery)
+ include_subtypes = TRUE
+
+/datum/export/implant/combatarm
+ cost = 800
+ unit_name = "combat arm set implant"
+ export_types = list(/obj/item/organ/cyberimp/arm/gun/laser, /obj/item/organ/cyberimp/arm/gun/taser, /obj/item/organ/cyberimp/arm/esword, /obj/item/organ/cyberimp/arm/medibeam, /obj/item/organ/cyberimp/arm/combat, /obj/item/organ/cyberimp/arm/flash, /obj/item/organ/cyberimp/arm/baton)
+ include_subtypes = TRUE
+
+/datum/export/orgains/heart
+ cost = 250
+ unit_name = "heart"
+ export_types = list(/obj/item/organ/heart)
+ exclude_types = list(/obj/item/organ/heart/cursed, /obj/item/organ/heart/cybernetic)
+
+/datum/export/orgains/tongue
+ cost = 75
+ unit_name = "tongue"
+ export_types = list(/obj/item/organ/tongue)
+
+/datum/export/orgains/eyes
+ cost = 50 //So many things take your eyes out anyways
+ unit_name = "eyes"
+ export_types = list(/obj/item/organ/eyes)
+ exclude_types = list(/obj/item/organ/eyes/robotic)
+
+/datum/export/orgains/stomach
+ cost = 50 //can be replaced
+ unit_name = "stomach"
+ export_types = list(/obj/item/organ/stomach)
+
+/datum/export/orgains/lungs
+ cost = 150
+ unit_name = "lungs"
+ export_types = list(/obj/item/organ/lungs)
+ exclude_types = list(/obj/item/organ/lungs/cybernetic, /obj/item/organ/lungs/cybernetic/upgraded)
+
+/datum/export/orgains/liver
+ cost = 175
+ unit_name = "liver"
+ export_types = list(/obj/item/organ/liver)
+ exclude_types = list(/obj/item/organ/liver/cybernetic, /obj/item/organ/liver/cybernetic/upgraded)
+
+/datum/export/orgains/tail //Shhh
+ cost = 500
+ unit_name = "error shipment failer"
+ export_types = list(/obj/item/organ/tail)
+
+/datum/export/orgains/vocal_cords
+ cost = 500
+ unit_name = "vocal cords"
+ export_types = list(/obj/item/organ/vocal_cords) //These are gotten via different races
+
+/datum/export/robotics/lims
+ cost = 30
+ unit_name = "robotic lim replacement"
+ export_types = list(/obj/item/bodypart/l_arm/robot, /obj/item/bodypart/r_arm/robot, /obj/item/bodypart/l_leg/robot, /obj/item/bodypart/r_leg/robot, /obj/item/bodypart/chest/robot, /obj/item/bodypart/head/robot)
+
+/datum/export/robotics/surpluse
+ cost = 40
+ unit_name = "robotic lim replacement"
+ export_types = list(/obj/item/bodypart/l_arm/robot/surplus, /obj/item/bodypart/r_arm/robot/surplus, /obj/item/bodypart/l_leg/robot/surplus, /obj/item/bodypart/r_leg/robot/surplus)
+
+/datum/export/robotics/surplus_upgraded
+ cost = 50
+ unit_name = "upgraded robotic lim replacement"
+ export_types = list(/obj/item/bodypart/l_arm/robot/surplus_upgraded, /obj/item/bodypart/r_arm/robot/surplus_upgraded, /obj/item/bodypart/l_leg/robot/surplus_upgraded, /obj/item/bodypart/r_leg/robot/surplus_upgraded)
+
+/datum/export/robotics/surgery_gear_basic
+ cost = 5
+ unit_name = "surgery tool"
+ export_types = list(/obj/item/retractor, /obj/item/hemostat, /obj/item/cautery, /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/circular_saw, /obj/item/surgical_drapes)
diff --git a/code/modules/cargo/exports/parts.dm b/code/modules/cargo/exports/parts.dm
index e6fda5f6b1..b505bb5da4 100644
--- a/code/modules/cargo/exports/parts.dm
+++ b/code/modules/cargo/exports/parts.dm
@@ -6,16 +6,96 @@
export_types = list(/obj/item/solar_assembly)
/datum/export/solar/tracker_board
- cost = 100
+ cost = 30
unit_name = "solar tracker board"
export_types = list(/obj/item/electronics/tracker)
/datum/export/solar/control_board
- cost = 150
+ cost = 75
unit_name = "solar panel control board"
export_types = list(/obj/item/circuitboard/computer/solar_control)
/datum/export/swarmer
- cost = 2000
+ cost = 500
unit_name = "deactivated alien deconstruction drone"
export_types = list(/obj/item/deactivated_swarmer)
+
+//Board
+
+/datum/export/board
+ cost = 5
+ unit_name = "circuit board"
+ export_types = list(/obj/item/circuitboard)
+ include_subtypes = TRUE
+
+/datum/export/board/SMES
+ cost = 20
+ k_elasticity = 1/2 //Only a few
+ unit_name = "smes board"
+ export_types = list(/obj/item/circuitboard/machine/smes)
+
+//Stock Parts
+
+/datum/export/subspace
+ cost = 3
+ unit_name = "subspace part"
+ export_types = list(/obj/item/stock_parts/subspace)
+ include_subtypes = TRUE
+
+/datum/export/t1
+ cost = 1
+ unit_name = "basic stock part"
+ export_types = list(/obj/item/stock_parts/capacitor, /obj/item/stock_parts/scanning_module, /obj/item/stock_parts/manipulator, /obj/item/stock_parts/micro_laser, /obj/item/stock_parts/matter_bin)
+
+/datum/export/t2
+ cost = 2
+ unit_name = "upgraded stock part"
+ export_types = list(/obj/item/stock_parts/capacitor/adv, /obj/item/stock_parts/scanning_module/adv, /obj/item/stock_parts/manipulator/nano, /obj/item/stock_parts/micro_laser/high, /obj/item/stock_parts/matter_bin/adv)
+
+/datum/export/t3
+ cost = 3
+ unit_name = "advanced stock part"
+ export_types = list(/obj/item/stock_parts/capacitor/super, /obj/item/stock_parts/scanning_module/phasic, /obj/item/stock_parts/manipulator/pico, /obj/item/stock_parts/micro_laser/ultra, /obj/item/stock_parts/matter_bin/super)
+
+/datum/export/t4
+ cost = 4
+ unit_name = "blue space stock part"
+ export_types = list(/obj/item/stock_parts/capacitor/quadratic, /obj/item/stock_parts/scanning_module/triphasic, /obj/item/stock_parts/manipulator/femto, /obj/item/stock_parts/micro_laser/quadultra, /obj/item/stock_parts/matter_bin/bluespace)
+
+//Cells
+
+/datum/export/cell
+ cost = 5
+ unit_name = "power cell"
+ export_types = list(/obj/item/stock_parts/cell)
+ include_subtypes = TRUE
+
+/datum/export/cell
+ cost = 10
+ unit_name = "upgraded power cell"
+ export_types = list(/obj/item/stock_parts/cell/upgraded, /obj/item/stock_parts/cell/upgraded/plus)
+
+/datum/export/cellhigh
+ cost = 15
+ unit_name = "high power cell"
+ export_types = list(/obj/item/stock_parts/cell/high, /obj/item/stock_parts/cell/high/plus)
+
+/datum/export/cellhyper
+ cost = 20
+ unit_name = "super-capacity power cell"
+ export_types = list(/obj/item/stock_parts/cell/super, /obj/item/stock_parts/cell/hyper)
+
+/datum/export/cellbs
+ cost = 25
+ unit_name = "bluespace power cell"
+ export_types = list(/obj/item/stock_parts/cell/bluespace)
+
+/datum/export/cellyellow
+ cost = 40
+ unit_name = "slime power cell"
+ export_types = list(/obj/item/stock_parts/cell/high/slime)
+
+/datum/export/cellyellowhyper
+ cost = 120 //Takes a lot to make and is really good
+ unit_name = "hyper slime power cell"
+ export_types = list(/obj/item/stock_parts/cell/high/slime/hypercharged)
\ No newline at end of file
diff --git a/code/modules/cargo/exports/sheets.dm b/code/modules/cargo/exports/sheets.dm
index 708eb34133..8397a7dc1f 100644
--- a/code/modules/cargo/exports/sheets.dm
+++ b/code/modules/cargo/exports/sheets.dm
@@ -1,5 +1,6 @@
/datum/export/stack
unit_name = "sheet"
+ k_elasticity = 0
/datum/export/stack/get_amount(obj/O)
var/obj/item/stack/S = O
@@ -9,47 +10,52 @@
// Hides
+/datum/export/stack/leather
+ cost = 30
+ unit_name = "leather"
+ export_types = list(/obj/item/stack/sheet/leather)
+
/datum/export/stack/skin/monkey
- cost = 50
+ cost = 30
unit_name = "monkey hide"
export_types = list(/obj/item/stack/sheet/animalhide/monkey)
/datum/export/stack/skin/human
- cost = 100
+ cost = 70
export_category = EXPORT_CONTRABAND
unit_name = "piece"
message = "of human skin"
export_types = list(/obj/item/stack/sheet/animalhide/human)
/datum/export/stack/skin/goliath_hide
- cost = 200
+ cost = 160
unit_name = "goliath hide"
export_types = list(/obj/item/stack/sheet/animalhide/goliath_hide)
/datum/export/stack/skin/cat
- cost = 150
+ cost = 120
export_category = EXPORT_CONTRABAND
unit_name = "cat hide"
export_types = list(/obj/item/stack/sheet/animalhide/cat)
/datum/export/stack/skin/corgi
- cost = 200
+ cost = 140
export_category = EXPORT_CONTRABAND
unit_name = "corgi hide"
export_types = list(/obj/item/stack/sheet/animalhide/corgi)
/datum/export/stack/skin/lizard
- cost = 150
+ cost = 50
unit_name = "lizard hide"
export_types = list(/obj/item/stack/sheet/animalhide/lizard)
/datum/export/stack/skin/gondola
- cost = 5000
+ cost = 1000
unit_name = "gondola hide"
export_types = list(/obj/item/stack/sheet/animalhide/gondola)
/datum/export/stack/skin/xeno
- cost = 500
+ cost = 300
unit_name = "alien hide"
export_types = list(/obj/item/stack/sheet/animalhide/xeno)
@@ -57,23 +63,23 @@
// For base materials, see materials.dm
/datum/export/stack/plasteel
- cost = 155 // 2000u of plasma + 2000u of metal.
+ cost = 105 // 2000u of plasma + 2000u of metal.
message = "of plasteel"
export_types = list(/obj/item/stack/sheet/plasteel)
// 1 glass + 0.5 metal, cost is rounded up.
/datum/export/stack/rglass
- cost = 8
+ cost = 6
message = "of reinforced glass"
export_types = list(/obj/item/stack/sheet/rglass)
/datum/export/stack/bscrystal
- cost = 300
+ cost = 150
message = "of bluespace crystals"
export_types = list(/obj/item/stack/sheet/bluespace_crystal)
/datum/export/stack/wood
- cost = 30
+ cost = 15
unit_name = "wood plank"
export_types = list(/obj/item/stack/sheet/mineral/wood)
@@ -93,16 +99,50 @@
unit_name = "cable piece"
export_types = list(/obj/item/stack/cable_coil)
+/datum/export/stack/cloth
+ cost = 10
+ unit_name = "sheets"
+ message = "of cloth"
+ export_types = list(/obj/item/stack/sheet/cloth)
+
+/datum/export/stack/duracloth
+ cost = 40
+ unit_name = "sheets"
+ message = "of duracloth"
+ export_types = list(/obj/item/stack/sheet/durathread)
+
// Weird Stuff
/datum/export/stack/abductor
- cost = 1000
+ cost = 400
message = "of alien alloy"
export_types = list(/obj/item/stack/sheet/mineral/abductor)
/datum/export/stack/adamantine
unit_name = "bar"
- cost = 500
+ cost = 250
message = "of adamantine"
export_types = list(/obj/item/stack/sheet/mineral/adamantine)
+/datum/export/stack/bone
+ cost = 20
+ message = "of bones"
+ export_types = list(/obj/item/stack/sheet/bone)
+
+/datum/export/stack/bronze
+ unit_name = "tiles"
+ cost = 5
+ message = "of brozne"
+ export_types = list(/obj/item/stack/tile/bronze)
+
+/datum/export/stack/brass
+ unit_name = "tiles"
+ cost = 50
+ message = "of brass"
+ export_types = list(/obj/item/stack/tile/brass)
+
+/datum/export/stack/paper
+ unit_name = "sheets"
+ cost = 30
+ message = "of paperframes"
+ export_types = list(/obj/item/stack/sheet/paperframes)
\ No newline at end of file
diff --git a/code/modules/cargo/exports/tools.dm b/code/modules/cargo/exports/tools.dm
index 9e58e4ba95..4984bfe9b9 100644
--- a/code/modules/cargo/exports/tools.dm
+++ b/code/modules/cargo/exports/tools.dm
@@ -1,5 +1,5 @@
/datum/export/toolbox
- cost = 4
+ cost = 6
unit_name = "toolbox"
export_types = list(/obj/item/storage/toolbox)
@@ -8,7 +8,80 @@
// electrical toolbox: 36cr
// robust: priceless
+// Adv tools
+
+/datum/export/gear/powerdrill
+ cost = 25
+ k_elasticity = 1/40 //Market can only take so much
+ unit_name = "power tool"
+ export_types = list(/obj/item/crowbar/power, /obj/item/screwdriver/power, \
+ /obj/item/weldingtool/experimental, /obj/item/wirecutters/power, /obj/item/wrench/power)
+ include_subtypes = TRUE
+
+/datum/export/gear/advtool
+ cost = 175
+ k_elasticity = 0 //Only known to be made by 2 station, market is hungery for it
+ unit_name = "adv tool"
+ export_types = list(/obj/item/crowbar/advanced, /obj/item/crowbar/abductor, /obj/item/screwdriver/abductor, /obj/item/screwdriver/advanced, \
+ /obj/item/weldingtool/abductor, /obj/item/weldingtool/advanced, /obj/item/wirecutters/abductor, /obj/item/wirecutters/advanced, \
+ /obj/item/wrench/abductor, /obj/item/wrench/advanced)
+ include_subtypes = TRUE
+
+// Lights/Eletronic
+
+/datum/export/lights
+ cost = 10
+ unit_name = "light fixer"
+ export_types = list(/obj/item/wallframe/light_fixture)
+ include_subtypes = TRUE
+
+/datum/export/apc_board
+ cost = 5
+ unit_name = "apc electronics"
+ export_types = list(/obj/item/electronics/apc)
+ include_subtypes = TRUE
+
+/datum/export/apc_frame
+ cost = 3
+ unit_name = "apc frame"
+ export_types = list(/obj/item/wallframe/apc)
+ include_subtypes = TRUE
+
+/datum/export/floodlights
+ cost = 15
+ unit_name = "floodlight fixer"
+ export_types = list(/obj/structure/floodlight_frame)
+ include_subtypes = TRUE
+
+/datum/export/bolbstubes
+ cost = 1 //Time
+ unit_name = "light replacement"
+ export_types = list(/obj/item/light/tube, /obj/item/light/bulb)
+
+/datum/export/lightreplacer
+ cost = 20
+ unit_name = "lightreplacer"
+ export_types = list(/obj/item/lightreplacer)
+
// Basic tools
+/datum/export/basicmining
+ cost = 20
+ unit_name = "basic mining tool"
+ export_types = list(/obj/item/pickaxe, /obj/item/pickaxe/mini, /obj/item/shovel, /obj/item/resonator)
+ include_subtypes = FALSE
+
+/datum/export/upgradedmining
+ cost = 50
+ unit_name = "mining tool"
+ export_types = list(/obj/item/pickaxe/silver, /obj/item/pickaxe/drill, /obj/item/gun/energy/plasmacutter, /obj/item/resonator/upgraded)
+ include_subtypes = FALSE
+
+/datum/export/advdmining
+ cost = 150
+ unit_name = "advanced mining tool"
+ export_types = list(/obj/item/pickaxe/diamond, /obj/item/pickaxe/drill/diamonddrill, /obj/item/pickaxe/drill/jackhammer, /obj/item/gun/energy/plasmacutter/adv)
+ include_subtypes = FALSE
+
/datum/export/screwdriver
cost = 2
unit_name = "screwdriver"
@@ -31,7 +104,6 @@
message = "of wirecutters"
export_types = list(/obj/item/wirecutters)
-
/datum/export/weldingtool
cost = 5
unit_name = "welding tool"
@@ -48,9 +120,8 @@
unit_name = "industrial welding tool"
export_types = list(/obj/item/weldingtool/largetank, /obj/item/weldingtool/hugetank)
-
/datum/export/extinguisher
- cost = 15
+ cost = 10
unit_name = "fire extinguisher"
export_types = list(/obj/item/extinguisher)
include_subtypes = FALSE
@@ -60,9 +131,8 @@
unit_name = "pocket fire extinguisher"
export_types = list(/obj/item/extinguisher/mini)
-
/datum/export/flashlight
- cost = 5
+ cost = 3
unit_name = "flashlight"
export_types = list(/obj/item/flashlight)
include_subtypes = FALSE
@@ -73,11 +143,10 @@
export_types = list(/obj/item/flashlight/flare)
/datum/export/flashlight/seclite
- cost = 10
+ cost = 5
unit_name = "seclite"
export_types = list(/obj/item/flashlight/seclite)
-
/datum/export/analyzer
cost = 5
unit_name = "analyzer"
@@ -88,14 +157,12 @@
unit_name = "t-ray scanner"
export_types = list(/obj/item/t_scanner)
-
/datum/export/radio
cost = 5
unit_name = "radio"
export_types = list(/obj/item/radio)
exclude_types = list(/obj/item/radio/mech)
-
/datum/export/rcd
cost = 100
unit_name = "rapid construction device"
@@ -111,6 +178,21 @@
unit_name = "rapid piping device"
export_types = list(/obj/item/pipe_dispenser)
+/datum/export/rld
+ cost = 150
+ unit_name = "rapid light device"
+ export_types = list(/obj/item/construction/rld)
+
+/datum/export/rped
+ cost = 100
+ unit_name = "rapid part exchange device"
+ export_types = list(/obj/item/storage/part_replacer)
+
+/datum/export/bsrped
+ cost = 200
+ unit_name = "blue space part exchange device"
+ export_types = list(/obj/item/storage/part_replacer/bluespace)
+
/datum/export/singulo //failsafe in case someone decides to ship a live singularity to CentCom without the corresponding bounty
cost = 1
unit_name = "singularity"
diff --git a/code/modules/cargo/exports/weapons.dm b/code/modules/cargo/exports/weapons.dm
index bad221c3ac..97dd9c10aa 100644
--- a/code/modules/cargo/exports/weapons.dm
+++ b/code/modules/cargo/exports/weapons.dm
@@ -3,6 +3,26 @@
/datum/export/weapon
include_subtypes = FALSE
+/datum/export/weapon/makeshift_shield
+ cost = 30
+ unit_name = "unknown shield"
+ export_types = list(/obj/item/shield/riot, /obj/item/shield/riot/roman, /obj/item/shield/riot/buckler, /obj/item/shield/makeshift)
+
+/datum/export/weapon/riot_shield
+ cost = 50
+ unit_name = "riot shield"
+ export_types = list(/obj/item/shield/riot, /obj/item/shield/riot/tower)
+
+/datum/export/weapon/riot_shield
+ cost = 70
+ unit_name = "flash shield"
+ export_types = list(/obj/item/assembly/flash/shield)
+
+/datum/export/weapon/tele_shield
+ cost = 100
+ unit_name = "tele shield"
+ export_types = list(/obj/item/shield/riot/tele, /obj/item/shield/energy)
+
/datum/export/weapon/baton
cost = 100
unit_name = "stun baton"
@@ -15,7 +35,6 @@
unit_name = "combat knife"
export_types = list(/obj/item/kitchen/knife/combat)
-
/datum/export/weapon/taser
cost = 200
unit_name = "advanced taser"
@@ -27,26 +46,25 @@
export_types = list(/obj/item/gun/energy/laser)
/datum/export/weapon/disabler
- cost = 100
+ cost = 50
unit_name = "disabler"
export_types = list(/obj/item/gun/energy/disabler)
/datum/export/weapon/energy_gun
- cost = 300
+ cost = 200
unit_name = "energy gun"
export_types = list(/obj/item/gun/energy/e_gun)
/datum/export/weapon/wt550
- cost = 300
+ cost = 130
unit_name = "WT-550 automatic rifle"
export_types = list(/obj/item/gun/ballistic/automatic/wt550)
/datum/export/weapon/shotgun
- cost = 300
+ cost = 200
unit_name = "combat shotgun"
export_types = list(/obj/item/gun/ballistic/shotgun/automatic/combat)
-
/datum/export/weapon/flashbang
cost = 5
unit_name = "flashbang grenade"
@@ -57,7 +75,6 @@
unit_name = "tear gas grenade"
export_types = list(/obj/item/grenade/chem_grenade/teargas)
-
/datum/export/weapon/flash
cost = 5
unit_name = "handheld flash"
@@ -69,3 +86,271 @@
unit_name = "pair"
message = "of handcuffs"
export_types = list(/obj/item/restraints/handcuffs)
+
+//////////////
+//RND Guns////
+//////////////
+
+/datum/export/weapon/lasercarbine
+ cost = 120
+ unit_name = "laser carbine"
+ export_types = list(/obj/item/gun/energy/laser/carbine)
+ include_subtypes = TRUE
+
+/datum/export/weapon/teslagun
+ cost = 130
+ unit_name = "tesla revolver"
+ export_types = list(/obj/item/gun/energy/tesla_revolver)
+
+/datum/export/weapon/aeg
+ cost = 200 //Endless power
+ unit_name = "advance engery gun"
+ export_types = list(/obj/item/gun/energy/e_gun/nuclear)
+
+/datum/export/weapon/deconer
+ cost = 600
+ unit_name = "deconer"
+ export_types = list(/obj/item/gun/energy/decloner)
+
+/datum/export/weapon/ntsniper
+ cost = 500
+ unit_name = "beam rifle"
+ export_types = list(/obj/item/gun/energy/beam_rifle)
+
+/datum/export/weapon/needle_gun
+ cost = 50
+ unit_name = "syringe revolver"
+ export_types = list(/obj/item/gun/syringe/rapidsyringe)
+
+/datum/export/weapon/temp_gun
+ cost = 175 //Its just smaller
+ unit_name = "small temperature gun"
+ k_elasticity = 1/5 //Its just a smaller temperature gun, easy to mass make
+ export_types = list(/obj/item/gun/energy/temperature)
+
+/datum/export/weapon/flowergun
+ cost = 100
+ unit_name = "floral somatoray"
+ export_types = list(/obj/item/gun/energy/floragun)
+
+/datum/export/weapon/xraygun
+ cost = 300 //Wall hacks
+ unit_name = "x ray gun"
+ export_types = list(/obj/item/gun/energy/xray)
+
+/datum/export/weapon/ioncarbine
+ cost = 200
+ k_elasticity = 1/5 //Its just a smaller temperature gun, easy to mass make
+ unit_name = "ion carbine"
+ export_types = list(/obj/item/gun/energy/ionrifle/carbine)
+
+/datum/export/weapon/largeebow
+ cost = 500
+ unit_name = "crossbow"
+ export_types = list(/obj/item/gun/energy/kinetic_accelerator/crossbow/large)
+
+/datum/export/weapon/largebomb
+ cost = 20
+ unit_name = "large grenade"
+ export_types = list(/obj/item/grenade/chem_grenade/large)
+
+/datum/export/weapon/gravworm
+ cost = 150
+ unit_name = "bluespace weapon"
+ export_types = list(/obj/item/gun/energy/wormhole_projector, /obj/item/gun/energy/gravity_gun)
+
+/datum/export/weapon/cryopryo
+ cost = 70
+ unit_name = "heat based grenade"
+ export_types = list(/obj/item/grenade/chem_grenade/pyro, /obj/item/grenade/chem_grenade/cryo)
+
+/datum/export/weapon/advgrenade
+ cost = 80
+ unit_name = "advanced grenade"
+ export_types = list(/obj/item/grenade/chem_grenade/adv_release)
+
+/////////////////
+//Ammo and Pins//
+/////////////////
+
+/datum/export/weapon/wtammo
+ cost = 10
+ unit_name = "WT-550 automatic rifle ammo"
+ export_types = list(/obj/item/ammo_box/magazine/wt550m9, /obj/item/ammo_box/magazine/wt550m9/wtrubber)
+
+/datum/export/weapon/wtammo/advanced
+ cost = 30
+ unit_name = "advanced WT-550 automatic rifle ammo"
+ export_types = list( /obj/item/ammo_box/magazine/wt550m9/wtap, /obj/item/ammo_box/magazine/wt550m9/wttx, /obj/item/ammo_box/magazine/wt550m9/wtic)
+
+/datum/export/weapon/mindshield
+ cost = 80
+ unit_name = "mindshield locked pin"
+ export_types = list(/obj/item/firing_pin/implant/mindshield)
+
+/datum/export/weapon/testrange
+ cost = 20
+ unit_name = "test range pin"
+ export_types = list(/obj/item/firing_pin/test_range)
+
+/datum/export/weapon/techslug
+ cost = 15
+ k_elasticity = 0
+ unit_name = "advanced shotgun shell"
+ export_types = list(/obj/item/ammo_casing/shotgun/dragonsbreath, /obj/item/ammo_casing/shotgun/meteorslug, /obj/item/ammo_casing/shotgun/pulseslug, /obj/item/ammo_casing/shotgun/frag12, /obj/item/ammo_casing/shotgun/ion, /obj/item/ammo_casing/shotgun/laserslug)
+
+/////////////////////////
+//The Traitor Sell Outs//
+/////////////////////////
+
+/datum/export/weapon/pistol
+ cost = 120
+ unit_name = "illegal firearm"
+ export_types = list(/obj/item/gun/ballistic/automatic/pistol)
+
+/datum/export/weapon/revolver
+ cost = 200
+ unit_name = "large handgun"
+ export_types = list(/obj/item/gun/ballistic/revolver/syndie)
+
+/datum/export/weapon/rocketlauncher
+ cost = 1000
+ unit_name = "rocketlauncher"
+ export_types = list(/obj/item/gun/ballistic/rocketlauncher)
+
+/datum/export/weapon/antitank
+ cost = 300
+ unit_name = "hand cannon"
+ export_types = list(/obj/item/gun/ballistic/automatic/pistol/antitank/syndicate)
+
+/datum/export/weapon/clownstuff
+ cost = 500
+ unit_name = "clown war tech"
+ export_types = list(/obj/item/pneumatic_cannon/pie/selfcharge, /obj/item/shield/energy/bananium, /obj/item/melee/transforming/energy/sword/bananium, )
+
+/datum/export/weapon/bulldog
+ cost = 400
+ unit_name = "drum loaded shotgun"
+ export_types = list(/obj/item/gun/ballistic/automatic/shotgun/bulldog)
+
+/datum/export/weapon/smg
+ cost = 350
+ unit_name = "automatic c-20r"
+ export_types = list(/obj/item/gun/ballistic/automatic/c20r)
+
+/datum/export/weapon/duelsaber
+ cost = 360 //Get it?
+ unit_name = "energy saber"
+ export_types = list(/obj/item/twohanded/dualsaber)
+
+/datum/export/weapon/esword
+ cost = 130
+ unit_name = "energy sword"
+ export_types = list(/obj/item/melee/transforming/energy/sword/cx/traitor, /obj/item/melee/transforming/energy/sword/saber)
+
+/datum/export/weapon/rapier
+ cost = 150
+ unit_name = "rapier"
+ export_types = list(/obj/item/storage/belt/sabre/rapier)
+
+/datum/export/weapon/flamer
+ cost = 20 //welder + some rods cheap
+ unit_name = "flamethrower"
+ export_types = list(/obj/item/flamethrower)
+
+/datum/export/weapon/gloves
+ cost = 90
+ unit_name = "star struck gloves"
+ export_types = list(/obj/item/clothing/gloves/rapid)
+
+/datum/export/weapon/l6
+ cost = 500
+ unit_name = "law 6 saw"
+ export_types = list(/obj/item/gun/ballistic/automatic/l6_saw)
+
+/datum/export/weapon/m90
+ cost = 400
+ unit_name = "assault class weapon"
+ export_types = list(/obj/item/gun/ballistic/automatic/m90)
+
+/datum/export/weapon/powerglove
+ cost = 100
+ unit_name = "hydraulic glove"
+ export_types = list(/obj/item/melee/powerfist)
+
+/datum/export/weapon/sniper
+ cost = 750
+ unit_name = ".50 sniper"
+ export_types = list(/obj/item/gun/ballistic/automatic/sniper_rifle/syndicate)
+
+/datum/export/weapon/ebow
+ cost = 600
+ unit_name = "mini crossbow"
+ export_types = list(/obj/item/gun/energy/kinetic_accelerator/crossbow)
+
+/datum/export/weapon/m10mm
+ cost = 10
+ unit_name = "10mm magazine"
+ export_types = list(/obj/item/ammo_box/magazine/m10mm)
+ include_subtypes = TRUE
+
+/datum/export/weapon/dj_a_bomb
+ cost = 100
+ unit_name = "40mm shell"
+ export_types = list(/obj/item/ammo_casing/a40mm)
+
+/datum/export/weapon/point50mags
+ cost = 50
+ unit_name = ".50 magazine"
+ export_types = list(/obj/item/ammo_box/magazine/sniper_rounds)
+ include_subtypes = TRUE
+
+/datum/export/weapon/smg_mag
+ cost = 45
+ unit_name = "smg magazine"
+ export_types = list(/obj/item/ammo_box/magazine/smgm45, /obj/item/ammo_box/magazine/m556)
+
+/datum/export/weapon/l6sawammo
+ cost = 60
+ unit_name = "law 6 saw ammo box"
+ export_types = list(/obj/item/ammo_box/magazine/mm195x129)
+ include_subtypes = TRUE
+
+/datum/export/weapon/rocket
+ cost = 120
+ unit_name = "rocket"
+ export_types = list(/obj/item/ammo_casing/caseless/rocket)
+ include_subtypes = TRUE
+
+/datum/export/weapon/ninemmammo
+ cost = 20
+ unit_name = "9mm ammo magazine"
+ export_types = list(/obj/item/ammo_box/magazine/pistolm9mm)
+
+/datum/export/weapon/fletcher_ammo
+ cost = 60
+ unit_name = "illegal ammo magazines"
+ export_types = list(/obj/item/ammo_box/magazine/flechette)
+ include_subtypes = TRUE
+
+/datum/export/weapon/dj_a_pizzabomb
+ cost = -6000
+ unit_name = "Repair Costs"
+ export_types = list(/obj/item/pizzabox/bomb, /obj/item/sbeacondrop/bomb)
+
+/datum/export/weapon/real_toolbox
+ cost = 600
+ unit_name = "golden toolbox"
+ export_types = list(/obj/item/storage/toolbox/gold_real)
+
+/datum/export/weapon/melee
+ cost = 30
+ unit_name = "unlisted weapon"
+ export_types = list(/obj/item/melee)
+ include_subtypes = TRUE
+
+/datum/export/weapon/gun
+ cost = 30
+ unit_name = "unlisted weapon"
+ export_types = list(/obj/item/gun)
+ include_subtypes = TRUE
\ No newline at end of file
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index 8d845badd4..89c463f3e3 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -36,2844 +36,3 @@
else
for(var/item in contains)
new item(C)
-
-// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Emergency ///////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/emergency
- group = "Emergency"
-
-/datum/supply_pack/emergency/vehicle
- name = "Biker Gang Kit" //TUNNEL SNAKES OWN THIS TOWN
- desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!"
- cost = 2000
- contraband = TRUE
- contains = list(/obj/vehicle/ridden/atv,
- /obj/item/key,
- /obj/item/clothing/suit/jacket/leather/overcoat,
- /obj/item/clothing/gloves/color/black,
- /obj/item/clothing/head/soft,
- /obj/item/clothing/mask/bandana/skull)//so you can properly #cargoniabikergang
- crate_name = "Biker Kit"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/emergency/equipment
- name = "Emergency Bot/Internals Crate"
- desc = "Explosions got you down? These supplies are guaranteed to patch up holes, in stations and people alike! Comes with two floorbots, two medbots, five oxygen masks and five small oxygen tanks."
- cost = 3500
- contains = list(/mob/living/simple_animal/bot/floorbot,
- /mob/living/simple_animal/bot/floorbot,
- /mob/living/simple_animal/bot/medbot,
- /mob/living/simple_animal/bot/medbot,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas)
- crate_name = "emergency crate"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/radiatione_emergency
- name = "Emergenc Radiation Protection Crate"
- desc = "Survive the Nuclear Apocalypse and Supermatter Engine alike with two sets of Radiation suits. Each set contains a helmet, suit, and Geiger counter. We'll even throw in a few pill bottles that are able to handles radiation and the affects of the poisoning."
- cost = 2500
- contains = list(/obj/item/clothing/head/radiation,
- /obj/item/clothing/head/radiation,
- /obj/item/clothing/suit/radiation,
- /obj/item/clothing/suit/radiation,
- /obj/item/geiger_counter,
- /obj/item/geiger_counter,
- /obj/item/storage/pill_bottle/mutarad,
- /obj/item/storage/firstaid/radbgone)
- crate_name = "radiation protection crate"
- crate_type = /obj/structure/closet/crate/radiation
-
-/datum/supply_pack/emergency/rcds
- name = "Emergency RCDs"
- desc = "Bombs going off on station? SME blown and now you need to fix the hole it left behind? Well this crate has a pare of Rcds to be able to easily fix up any problem you may have!"
- cost = 1500
- contains = list(/obj/item/construction/rcd,
- /obj/item/construction/rcd)
- crate_name = "emergency rcds"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/soft_suit
- name = "Emergency Space Suit "
- desc = "Is there bombs going off left and right? Is there meteors shooting around the station? Well we have two fragile space suit for emergencys as well as air and masks."
- cost = 1000
- contains = list(/obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/suit/space/fragile,
- /obj/item/clothing/suit/space/fragile,
- /obj/item/clothing/head/helmet/space/fragile,
- /obj/item/clothing/head/helmet/space/fragile)
- crate_name = "emergency crate"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/firefighting
- name = "Firefighting Crate"
- desc = "Only you can prevent station fires. Partner up with two firefighter suits, gas masks, flashlights, large oxygen tanks, extinguishers, and hardhats!"
- cost = 1000
- contains = list(/obj/item/clothing/suit/fire/firefighter,
- /obj/item/clothing/suit/fire/firefighter,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/flashlight,
- /obj/item/flashlight,
- /obj/item/tank/internals/oxygen/red,
- /obj/item/tank/internals/oxygen/red,
- /obj/item/extinguisher/advanced,
- /obj/item/extinguisher/advanced,
- /obj/item/clothing/head/hardhat/red,
- /obj/item/clothing/head/hardhat/red)
- crate_name = "firefighting crate"
-
-/datum/supply_pack/emergency/atmostank
- name = "Firefighting Tank Backpack"
- desc = "Mow down fires with this high-capacity fire fighting tank backpack. Requires Atmospherics access to open."
- cost = 1000
- access = ACCESS_ATMOSPHERICS
- contains = list(/obj/item/watertank/atmos)
- crate_name = "firefighting backpack crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/emergency/internals
- name = "Internals Crate"
- desc = "Master your life energy and control your breathing with three breath masks, three emergency oxygen tanks and three large air tanks."//IS THAT A
- cost = 1000
- contains = list(/obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/breath,
- /obj/item/clothing/mask/breath,
- /obj/item/clothing/mask/breath,
- /obj/item/tank/internals/emergency_oxygen,
- /obj/item/tank/internals/emergency_oxygen,
- /obj/item/tank/internals/emergency_oxygen,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air)
- crate_name = "internals crate"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/metalfoam
- name = "Metal Foam Grenade Crate"
- desc = "Seal up those pesky hull breaches with 14 Metal Foam Grenades."
- cost = 2000
- contains = list(/obj/item/storage/box/metalfoam,
- /obj/item/storage/box/metalfoam)
- crate_name = "metal foam grenade crate"
-
-/datum/supply_pack/emergency/syndicate
- name = "NULL_ENTRY"
- desc = "(#@&^$THIS PACKAGE CONTAINS 30TC WORTH OF SOME RANDOM SYNDICATE GEAR WE HAD LYING AROUND THE WAREHOUSE. GIVE EM HELL, OPERATIVE@&!*() "
- hidden = TRUE
- cost = 20000
- contains = list()
- crate_name = "emergency crate"
- crate_type = /obj/structure/closet/crate/internals
- dangerous = TRUE
-
-/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
- var/crate_value = 30
- var/list/uplink_items = get_uplink_items(SSticker.mode)
- while(crate_value)
- var/category = pick(uplink_items)
- var/item = pick(uplink_items[category])
- var/datum/uplink_item/I = uplink_items[category][item]
- if(!I.surplus_nullcrates || prob(100 - I.surplus_nullcrates))
- continue
- if(crate_value < I.cost)
- continue
- crate_value -= I.cost
- new I.item(C)
-
-/datum/supply_pack/emergency/plasma_spacesuit
- name = "Plasmaman Space Envirosuits"
- desc = "Contains two space-worthy envirosuits for Plasmamen. Order now and we'll throw in two free helmets! Requires EVA access to open."
- cost = 4000
- access = ACCESS_EVA
- contains = list(/obj/item/clothing/suit/space/eva/plasmaman,
- /obj/item/clothing/suit/space/eva/plasmaman,
- /obj/item/clothing/head/helmet/space/plasmaman,
- /obj/item/clothing/head/helmet/space/plasmaman)
- crate_name = "plasmaman EVA crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/emergency/plasmaman
- name = "Plasmaman Supply Kit"
- desc = "Keep those Plasmamen alive with two sets of Plasmaman outfits. Each set contains a plasmaman jumpsuit, internals tank, and helmet."
- cost = 2000
- contains = list(/obj/item/clothing/under/plasmaman,
- /obj/item/clothing/under/plasmaman,
- /obj/item/tank/internals/plasmaman/belt/full,
- /obj/item/tank/internals/plasmaman/belt/full,
- /obj/item/clothing/head/helmet/space/plasmaman,
- /obj/item/clothing/head/helmet/space/plasmaman)
- crate_name = "plasmaman supply kit"
-
-/datum/supply_pack/emergency/radiation
- name = "Radiation Protection Crate"
- desc = "Survive the Nuclear Apocalypse and Supermatter Engine alike with two sets of Radiation suits. Each set contains a helmet, suit, and Geiger counter. We'll even throw in a bottle of vodka and some glasses too, considering the life-expectancy of people who order this."
- cost = 1000
- contains = list(/obj/item/clothing/head/radiation,
- /obj/item/clothing/head/radiation,
- /obj/item/clothing/suit/radiation,
- /obj/item/clothing/suit/radiation,
- /obj/item/geiger_counter,
- /obj/item/geiger_counter,
- /obj/item/reagent_containers/food/drinks/bottle/vodka,
- /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
- crate_name = "radiation protection crate"
- crate_type = /obj/structure/closet/crate/radiation
-
-/datum/supply_pack/emergency/spacesuit
- name = "Space Suit Crate"
- desc = "Contains two aging suits from Space-Goodwill. Requires EVA access to open."
- cost = 3000
- access = ACCESS_EVA
- contains = list(/obj/item/clothing/suit/space,
- /obj/item/clothing/suit/space,
- /obj/item/clothing/head/helmet/space,
- /obj/item/clothing/head/helmet/space,
- /obj/item/clothing/mask/breath,
- /obj/item/clothing/mask/breath)
- crate_name = "space suit crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/emergency/spacejets
- name = "Spare EVA Jetpacks"
- desc = "Contains three EVA grade jectpaks. Requires EVA access to open."
- cost = 2000
- access = ACCESS_EVA
- contains = list(/obj/item/tank/jetpack/carbondioxide/eva,
- /obj/item/tank/jetpack/carbondioxide/eva,
- /obj/item/tank/jetpack/carbondioxide/eva)
- crate_name = "eva jetpacks crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/emergency/specialops
- name = "Special Ops Supplies"
- desc = "(*!&@#TOO CHEAP FOR THAT NULL_ENTRY, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN STILL HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, AND A \"SLEEPY PEN\" FULL OF NICE TOXINS!#@*$"
- hidden = TRUE
- cost = 2000
- contains = list(/obj/item/storage/box/emps,
- /obj/item/grenade/smokebomb,
- /obj/item/grenade/smokebomb,
- /obj/item/grenade/smokebomb,
- /obj/item/pen/sleepy,
- /obj/item/grenade/chem_grenade/incendiary)
- crate_name = "emergency crate"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/weedcontrol
- name = "Weed Control Crate"
- desc = "Keep those invasive species OUT. Contains a scythe, gasmask, two sprays of Plant-B-Gone, and two anti-weed chemical grenades. Warranty void if used on ambrosia. Requires Hydroponics access to open."
- cost = 1500
- access = ACCESS_HYDROPONICS
- contains = list(/obj/item/scythe,
- /obj/item/clothing/mask/gas,
- /obj/item/grenade/chem_grenade/antiweed,
- /obj/item/grenade/chem_grenade/antiweed,
- /obj/item/reagent_containers/spray/plantbgone,
- /obj/item/reagent_containers/spray/plantbgone)
- crate_name = "weed control crate"
- crate_type = /obj/structure/closet/crate/secure/hydroponics
-
-/datum/supply_pack/medical/anitvirus
- name = "Virus Containment Crate"
- desc = "Viro let out a death plague Mk II again? Someone didnt wash there hands? Old plagues born anew? Well this crate is for you! Hope you cure it before it brakes out of the station... This crate needs medical access to open and has two bio suits, a box of needles and beakers, five spaceacillin needles, and a medibot."
- cost = 3000
- access = ACCESS_MEDICAL
- contains = list(/mob/living/simple_animal/bot/medbot,
- /obj/item/clothing/head/bio_hood,
- /obj/item/clothing/head/bio_hood,
- /obj/item/clothing/suit/bio_suit,
- /obj/item/clothing/suit/bio_suit,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/storage/box/syringes,
- /obj/item/storage/box/beakers)
- crate_name = "virus containment unit crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Security ////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/security
- group = "Security"
- access = ACCESS_SECURITY
- crate_type = /obj/structure/closet/crate/secure/gear
-
-/datum/supply_pack/security/armor
- name = "Armor Crate"
- desc = "Three vests of well-rounded, decently-protective armor. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/clothing/suit/armor/vest,
- /obj/item/clothing/suit/armor/vest,
- /obj/item/clothing/suit/armor/vest)
- crate_name = "armor crate"
-
-/datum/supply_pack/security/disabler
- name = "Disabler Crate"
- desc = "Three stamina-draining disabler weapons. Requires Security access to open."
- cost = 1500
- contains = list(/obj/item/gun/energy/disabler,
- /obj/item/gun/energy/disabler,
- /obj/item/gun/energy/disabler)
- crate_name = "disabler crate"
-
-/datum/supply_pack/security/forensics
- name = "Forensics Crate"
- desc = "Stay hot on the criminal's heels with Nanotrasen's Detective Essentials(tm). Contains a forensics scanner, six evidence bags, camera, tape recorder, white crayon, and of course, a fedora. Requires Security access to open."
- cost = 2000
- contains = list(/obj/item/detective_scanner,
- /obj/item/storage/box/evidence,
- /obj/item/camera,
- /obj/item/taperecorder,
- /obj/item/toy/crayon/white,
- /obj/item/clothing/head/fedora/det_hat)
- crate_name = "forensics crate"
-
-/datum/supply_pack/security/helmets
- name = "Helmets Crate"
- desc = "Contains three standard-issue brain buckets. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/clothing/head/helmet/sec,
- /obj/item/clothing/head/helmet/sec,
- /obj/item/clothing/head/helmet/sec)
- crate_name = "helmet crate"
-
-/datum/supply_pack/security/laser
- name = "Lasers Crate"
- desc = "Contains three lethal, high-energy laser guns. Requires Security access to open."
- cost = 2000
- contains = list(/obj/item/gun/energy/laser,
- /obj/item/gun/energy/laser,
- /obj/item/gun/energy/laser)
- crate_name = "laser crate"
-
-/datum/supply_pack/security/russianclothing
- name = "Russian Surplus Clothing"
- desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!"
- contraband = TRUE
- cost = 5000 // Its basicly sec suits, good boots/gloves
- contains = list(/obj/item/clothing/suit/security/officer/russian,
- /obj/item/clothing/suit/security/officer/russian,
- /obj/item/clothing/shoes/combat,
- /obj/item/clothing/shoes/combat,
- /obj/item/clothing/head/ushanka,
- /obj/item/clothing/head/ushanka,
- /obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/gloves/combat,
- /obj/item/clothing/gloves/combat,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas)
- crate_name = "surplus russian clothing"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/security/russianmosin
- name = "Russian Minutemen Gear"
- desc = "An old russian Minutemen crate, comes with a full russian outfit, a mosin and a stripper clip."
- contraband = TRUE
- access = FALSE
- cost = 5000 //
- contains = list(/obj/item/clothing/suit/security/officer/russian,
- /obj/item/clothing/shoes/combat,
- /obj/item/clothing/head/ushanka,
- /obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/gloves/combat,
- /obj/item/clothing/mask/gas,
- /obj/item/gun/ballistic/shotgun/boltaction,
- /obj/item/ammo_box/a762)
- crate_name = "surplus russian gear"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/security/sechardsuit
- name = "Sec Hardsuit"
- desc = "One Sec Hardsuit with a small air tank and mask."
- cost = 3000 // half of SWAT gear for have the armor and half the gear
- contains = list(/obj/item/clothing/suit/space/hardsuit/security,
- /obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas)
- crate_name = "sec hardsuit crate"
-
-/datum/supply_pack/security/securitybarriers
- name = "Security Barrier Grenades"
- desc = "Stem the tide with four Security Barrier grenades. Requires Security access to open."
- contains = list(/obj/item/grenade/barrier,
- /obj/item/grenade/barrier,
- /obj/item/grenade/barrier,
- /obj/item/grenade/barrier)
- cost = 2000
- crate_name = "security barriers crate"
-
-/datum/supply_pack/security/securityclothes
- name = "Security Clothing Crate"
- desc = "Contains appropriate outfits for the station's private security force. Contains outfits for the Warden, Head of Security, and two Security Officers. Each outfit comes with a rank-appropriate jumpsuit, suit, and beret. Requires Security access to open."
- cost = 3000
- contains = list(/obj/item/clothing/under/rank/security/navyblue,
- /obj/item/clothing/under/rank/security/navyblue,
- /obj/item/clothing/suit/security/officer,
- /obj/item/clothing/suit/security/officer,
- /obj/item/clothing/head/beret/sec/navyofficer,
- /obj/item/clothing/head/beret/sec/navyofficer,
- /obj/item/clothing/under/rank/warden/navyblue,
- /obj/item/clothing/suit/security/warden,
- /obj/item/clothing/head/beret/sec/navywarden,
- /obj/item/clothing/under/rank/head_of_security/navyblue,
- /obj/item/clothing/suit/security/hos,
- /obj/item/clothing/head/beret/sec/navyhos)
- crate_name = "security clothing crate"
-
-/datum/supply_pack/security/supplies
- name = "Security Supplies Crate"
- desc = "Contains seven flashbangs, seven teargas grenades, six flashes, and seven handcuffs. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/storage/box/flashbangs,
- /obj/item/storage/box/teargas,
- /obj/item/storage/box/flashes,
- /obj/item/storage/box/handcuffs)
- crate_name = "security supply crate"
-
-/datum/supply_pack/security/firingpins
- name = "Standard Firing Pins Crate"
- desc = "Upgrade your arsenal with 10 standard firing pins. Requires Security access to open."
- cost = 2000
- contains = list(/obj/item/storage/box/firingpins,
- /obj/item/storage/box/firingpins)
- crate_name = "firing pins crate"
-
-/datum/supply_pack/security/justiceinbound
- name = "Standard Justice Enforcer Crate"
- desc = "This is it. The Bee's Knees. The Creme of the Crop. The Pick of the Litter. The best of the best of the best. The Crown Jewel of Nanotrasen. The Alpha and the Omega of security headwear. Guaranteed to strike fear into the hearts of each and every criminal aboard the station. Also comes with a security gasmask. Requires Security access to open."
- cost = 6000 //justice comes at a price. An expensive, noisy price.
- contraband = TRUE
- contains = list(/obj/item/clothing/head/helmet/justice,
- /obj/item/clothing/mask/gas/sechailer)
- crate_name = "security clothing crate"
-
-/datum/supply_pack/security/baton
- name = "Stun Batons Crate"
- desc = "Arm the Civil Protection Forces with three stun batons. Batteries included. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/melee/baton/loaded,
- /obj/item/melee/baton/loaded,
- /obj/item/melee/baton/loaded)
- crate_name = "stun baton crate"
-
-/datum/supply_pack/security/taser
- name = "Taser Crate"
- desc = "From the depths of stunbased combat, this order rises above, supreme. Contains three hybrid tasers, capable of firing both electrodes and disabling shots. Requires Security access to open."
- cost = 3000
- contains = list(/obj/item/gun/energy/e_gun/advtaser,
- /obj/item/gun/energy/e_gun/advtaser,
- /obj/item/gun/energy/e_gun/advtaser)
- crate_name = "taser crate"
-
-/datum/supply_pack/security/wall_flash
- name = "Wall-Mounted Flash Crate"
- desc = "Contains four wall-mounted flashes. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/storage/box/wall_flash,
- /obj/item/storage/box/wall_flash,
- /obj/item/storage/box/wall_flash,
- /obj/item/storage/box/wall_flash)
- crate_name = "wall-mounted flash crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Armory //////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/security/armory
- group = "Armory"
- access = ACCESS_ARMORY
- crate_type = /obj/structure/closet/crate/secure/weapon
-
-/datum/supply_pack/security/armory/bulletarmor
- name = "Bulletproof Armor Crate"
- desc = "Contains three sets of bulletproof armor. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/suit/armor/bulletproof)
- crate_name = "bulletproof armor crate"
-
-/datum/supply_pack/security/armory/bullethelmets
- name = "Bulletproof Helmet Crate"
- desc = "Contains three sets of bulletproof helmets. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/head/helmet/alt)
- crate_name = "bulletproof helmet crate"
-
-/datum/supply_pack/security/armory/chemimp
- name = "Chemical Implants Crate"
- desc = "Contains five Remote Chemical implants. Requires Armory access to open."
- cost = 2000
- contains = list(/obj/item/storage/box/chemimp)
- crate_name = "chemical implant crate"
-
-/datum/supply_pack/security/armory/combatknives
- name = "Combat Knives Crate"
- desc = "Contains three sharpened combat knives. Each knife guaranteed to fit snugly inside any Nanotrasen-standard boot. Requires Armory access to open."
- cost = 3000
- contains = list(/obj/item/kitchen/knife/combat,
- /obj/item/kitchen/knife/combat,
- /obj/item/kitchen/knife/combat)
- crate_name = "combat knife crate"
-
-/datum/supply_pack/security/armory/ballistic
- name = "Combat Shotguns Crate"
- desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, with three Shotgun Bandoliers, as well as seven buchshot and 12g shotgun slugs. Requires Armory access to open."
- cost = 8000
- contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat,
- /obj/item/gun/ballistic/shotgun/automatic/combat,
- /obj/item/gun/ballistic/shotgun/automatic/combat,
- /obj/item/storage/belt/bandolier,
- /obj/item/storage/belt/bandolier,
- /obj/item/storage/belt/bandolier,
- /obj/item/storage/box/lethalshot,
- /obj/item/storage/box/lethalslugs)
- crate_name = "combat shotguns crate"
-
-/datum/supply_pack/security/armory/dragnetgun
- name = "DRAGnet gun Crate"
- desc = "Contains two DRAGnet gun. A Dynamic Rapid-Apprehension of the Guilty net the revolution in law enforcement technology that YOU Want! Requires Armory access to open."
- cost = 3500
- contains = list(/obj/item/gun/energy/e_gun/dragnet,
- /obj/item/gun/energy/e_gun/dragnet)
- crate_name = "anti riot net guns crate"
-
-/datum/supply_pack/security/armory/energy
- name = "Energy Guns Crate"
- desc = "Contains three Energy Guns, capable of firing both nonlethal and lethal blasts of light. Requires Armory access to open."
- cost = 3500
- contains = list(/obj/item/gun/energy/e_gun,
- /obj/item/gun/energy/e_gun,
- /obj/item/gun/energy/e_gun)
- crate_name = "energy gun crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-/datum/supply_pack/security/armory/exileimp // Theres boxes in 2 lockers as well as gateway never realy being used sad
- name = "Exile Implants Crate"
- desc = "Contains five Exile implants. Requires Armory access to open."
- cost = 1000
- contains = list(/obj/item/storage/box/exileimp)
- crate_name = "exile implant crate"
-
-/datum/supply_pack/security/armory/mindshield
- name = "Mindshield Implants Crate"
- desc = "Prevent against radical thoughts with three Mindshield implants. Requires Armory access to open."
- cost = 4000
- contains = list(/obj/item/storage/lockbox/loyalty)
- crate_name = "mindshield implant crate"
-
-/datum/supply_pack/security/armory/trackingimp
- name = "Tracking Implants Crate"
- desc = "Contains four tracking implants. Requires Armory access to open."
- cost = 1000
- contains = list(/obj/item/storage/box/trackimp)
- crate_name = "tracking implant crate"
-
-/datum/supply_pack/security/armory/fire
- name = "Incendiary Weapons Crate"
- desc = "Burn, baby burn. Contains three incendiary grenades, seven incendiary slugs, three plasma canisters, and a flamethrower. Requires Brige access to open."
- cost = 1500
- access = ACCESS_HEADS
- contains = list(/obj/item/flamethrower/full,
- /obj/item/tank/internals/plasma,
- /obj/item/tank/internals/plasma,
- /obj/item/tank/internals/plasma,
- /obj/item/grenade/chem_grenade/incendiary,
- /obj/item/grenade/chem_grenade/incendiary,
- /obj/item/grenade/chem_grenade/incendiary,
- /obj/item/storage/box/fireshot)
- crate_name = "incendiary weapons crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
- dangerous = TRUE
-
-/datum/supply_pack/security/armory/miniguns
- name = "Personal Miniature Energy Guns"
- desc = "Contains three miniature energy guns. Each gun has a disabler and a lethal option. Requires Armory access to open."
- cost = 5000
- contains = list(/obj/item/gun/energy/e_gun/mini,
- /obj/item/gun/energy/e_gun/mini,
- /obj/item/gun/energy/e_gun/mini)
- crate_name = "personal energy guns crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-/datum/supply_pack/security/armory/laserarmor
- name = "Reflector Vest Crate"
- desc = "Contains two vests of highly reflective material. Each armor piece diffuses a laser's energy by over half, as well as offering a good chance to reflect the laser entirely. Requires Armory access to open."
- cost = 2000
- contains = list(/obj/item/clothing/suit/armor/laserproof,
- /obj/item/clothing/suit/armor/laserproof)
- crate_name = "reflector vest crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-/datum/supply_pack/security/armory/riotarmor
- name = "Riot Armor Crate"
- desc = "Contains three sets of heavy body armor. Advanced padding protects against close-ranged weaponry, making melee attacks feel only half as potent to the user. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/suit/armor/riot,
- /obj/item/clothing/suit/armor/riot,
- /obj/item/clothing/suit/armor/riot)
- crate_name = "riot armor crate"
-
-/datum/supply_pack/security/armory/riothelmets
- name = "Riot Helmets Crate"
- desc = "Contains three riot helmets. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/head/helmet/riot,
- /obj/item/clothing/head/helmet/riot,
- /obj/item/clothing/head/helmet/riot)
- crate_name = "riot helmets crate"
-
-/datum/supply_pack/security/armory/riotshields
- name = "Riot Shields Crate"
- desc = "For when the greytide gets really uppity. Contains three riot shields. Requires Armory access to open."
- cost = 2000
- contains = list(/obj/item/shield/riot,
- /obj/item/shield/riot,
- /obj/item/shield/riot)
- crate_name = "riot shields crate"
-
-/datum/supply_pack/security/armory/riotshotguns
- name = "Riot Shotgun Crate"
- desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open."
- cost = 6000
- contains = list(/obj/item/gun/ballistic/shotgun/riot,
- /obj/item/gun/ballistic/shotgun/riot,
- /obj/item/gun/ballistic/shotgun/riot,
- /obj/item/storage/box/rubbershot,
- /obj/item/storage/box/beanbag)
- crate_name = "riot shotgun crate"
-
-/datum/supply_pack/security/armory/swat
- name = "SWAT Crate"
- desc = "Contains two fullbody sets of tough, fireproof, pressurized suits designed in a joint effort by IS-ERI and Nanotrasen. Each set contains a suit, helmet, mask, combat belt, and combat gloves. Requires Armory access to open."
- cost = 6000
- contains = list(/obj/item/clothing/head/helmet/swat/nanotrasen,
- /obj/item/clothing/head/helmet/swat/nanotrasen,
- /obj/item/clothing/suit/space/swat,
- /obj/item/clothing/suit/space/swat,
- /obj/item/clothing/mask/gas/sechailer/swat,
- /obj/item/clothing/mask/gas/sechailer/swat,
- /obj/item/storage/belt/military/assault,
- /obj/item/storage/belt/military/assault,
- /obj/item/clothing/gloves/combat,
- /obj/item/clothing/gloves/combat)
- crate_name = "swat crate"
-
-/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
- name = "SWAT tatical tasers Crate"
- desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
- cost = 8000
- contains = list(/obj/item/gun/energy/e_gun/stun,
- /obj/item/gun/energy/e_gun/stun)
- crate_name = "swat taser crate"
-
-/datum/supply_pack/security/armory/woodstock
- name = "Classic WoodStock Shotguns Crate"
- desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open."
- cost = 3500
- contains = list(/obj/item/gun/ballistic/shotgun,
- /obj/item/gun/ballistic/shotgun,
- /obj/item/gun/ballistic/shotgun)
- crate_name = "woodstock shotguns crate"
-
-/datum/supply_pack/security/armory/wt550
- name = "WT-550 Semi-Auto Rifle Crate"
- desc = "Contains two high-powered, semiautomatic rifles chambered in 4.6x30mm. Requires Armory access to open."
- cost = 3500
- contains = list(/obj/item/gun/ballistic/automatic/wt550,
- /obj/item/gun/ballistic/automatic/wt550)
- crate_name = "auto rifle crate"
-
-/datum/supply_pack/security/armory/wt550ammo
- name = "WT-550 Semi-Auto SMG Ammo Crate"
- desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
- cost = 2500
- contains = list(/obj/item/ammo_box/magazine/wt550m9,
- /obj/item/ammo_box/magazine/wt550m9,
- /obj/item/ammo_box/magazine/wt550m9,
- /obj/item/ammo_box/magazine/wt550m9)
- crate_name = "auto rifle ammo crate"
-
-/datum/supply_pack/security/armory/wt550ammo_nonlethal // Takes around 12 shots to stun crit someone
- name = "WT-550 Semi-Auto SMG Non-Lethal Ammo Crate"
- desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/ammo_box/magazine/wt550m9/wtrubber,
- /obj/item/ammo_box/magazine/wt550m9/wtrubber,
- /obj/item/ammo_box/magazine/wt550m9/wtrubber,
- /obj/item/ammo_box/magazine/wt550m9/wtrubber)
- crate_name = "auto rifle ammo crate"
-
-/datum/supply_pack/security/armory/wt550ammo_special
- name = "WT-550 Semi-Auto SMG Special Ammo Crate"
- desc = "Contains 2 20-round Armour Piercing and Incendiary magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
- cost = 4500
- contains = list(/obj/item/ammo_box/magazine/wt550m9/wtap,
- /obj/item/ammo_box/magazine/wt550m9/wtap,
- /obj/item/ammo_box/magazine/wt550m9/wtic,
- /obj/item/ammo_box/magazine/wt550m9/wtic)
- crate_name = "auto rifle ammo crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Engineering /////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/engineering
- group = "Engineering"
- crate_type = /obj/structure/closet/crate/engineering
-
-/datum/supply_pack/engineering/shieldgen
- name = "Anti-breach Shield Projector Crate"
- desc = "Hull breaches again? Say no more with the Nanotrasen Anti-Breach Shield Projector! Uses forcefield technology to keep the air in, and the space out. Contains two shield projectors."
- cost = 2500
- contains = list(/obj/machinery/shieldgen,
- /obj/machinery/shieldgen)
- crate_name = "anti-breach shield projector crate"
-
-/datum/supply_pack/engineering/conveyor
- name = "Conveyor Assembly Crate"
- desc = "Keep production moving along with six conveyor belts. Conveyor switch included. If you have any questions, check out the enclosed instruction book."
- cost = 750
- contains = list(/obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_switch_construct,
- /obj/item/paper/guides/conveyor)
- crate_name = "conveyor assembly crate"
-
-/datum/supply_pack/engineering/engiequipment
- name = "Engineering Gear Crate"
- desc = "Gear up with three toolbelts, high-visibility vests, welding helmets, hardhats, and two pairs of meson goggles!"
- cost = 1300
- contains = list(/obj/item/storage/belt/utility,
- /obj/item/storage/belt/utility,
- /obj/item/storage/belt/utility,
- /obj/item/clothing/suit/hazardvest,
- /obj/item/clothing/suit/hazardvest,
- /obj/item/clothing/suit/hazardvest,
- /obj/item/clothing/head/welding,
- /obj/item/clothing/head/welding,
- /obj/item/clothing/head/welding,
- /obj/item/clothing/head/hardhat,
- /obj/item/clothing/head/hardhat,
- /obj/item/clothing/head/hardhat,
- /obj/item/clothing/glasses/meson/engine,
- /obj/item/clothing/glasses/meson/engine)
- crate_name = "engineering gear crate"
-
-/datum/supply_pack/engineering/engihardsuit
- name = "Engineering Hardsuit"
- desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!"
- cost = 2500
- contains = list(/obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/suit/space/hardsuit/engine)
- crate_name = "engineering hardsuit"
-
-/datum/supply_pack/engineering/atmoshardsuit
- name = "Atmospherics Hardsuit"
- desc = "Too many techs and not enough hardsuits? Time to buy some more! Comes with gas mask and air tank. Ask the CE to open."
- cost = 5000
- access = ACCESS_CE
- contains = list(/obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/suit/space/hardsuit/engine/atmos)
- crate_name = "atmospherics hardsuit"
- crate_type = /obj/structure/closet/crate/secure/engineering
-
-/datum/supply_pack/engineering/industrialrcd
- name = "Industrial RCD"
- desc = "A industrial RCD in case the station has gone through more then one meteor storm and the CE needs to bring out the somthing a bit more reliable. Dose not contain spare ammo for the industrial RCD or any other RCD modles."
- cost = 4500
- access = ACCESS_CE
- contains = list(/obj/item/construction/rcd/industrial)
- crate_name = "industrial rcd"
- crate_type = /obj/structure/closet/crate/secure/engineering
-
-/datum/supply_pack/engineering/powergamermitts
- name = "Insulated Gloves Crate"
- desc = "The backbone of modern society. Barely ever ordered for actual engineering. Contains three insulated gloves."
- cost = 2000 //Made of pure-grade bullshittinium
- contains = list(/obj/item/clothing/gloves/color/yellow,
- /obj/item/clothing/gloves/color/yellow,
- /obj/item/clothing/gloves/color/yellow)
- crate_name = "insulated gloves crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/obj/item/stock_parts/cell/inducer_supply
- maxcharge = 5000
- charge = 5000
-
-/datum/supply_pack/engineering/inducers
- name = "NT-75 Electromagnetic Power Inducers Crate"
- desc = "No rechargers? No problem, with the NT-75 EPI, you can recharge any standard cell-based equipment anytime, anywhere. Contains two Inducers."
- cost = 2000
- contains = list(/obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}, /obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}) //FALSE doesn't work in modified type paths apparently.
- crate_name = "inducer crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engineering/pacman
- name = "P.A.C.M.A.N Generator Crate"
- desc = "Engineers can't set up the engine? Not an issue for you, once you get your hands on this P.A.C.M.A.N. Generator! Takes in plasma and spits out sweet sweet energy."
- cost = 2500
- contains = list(/obj/machinery/power/port_gen/pacman)
- crate_name = "PACMAN generator crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engineering/power
- name = "Power Cell Crate"
- desc = "Looking for power overwhelming? Look no further. Contains three high-voltage power cells."
- cost = 1000
- contains = list(/obj/item/stock_parts/cell/high,
- /obj/item/stock_parts/cell/high,
- /obj/item/stock_parts/cell/high)
- crate_name = "power cell crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engineering/shuttle_engine
- name = "Shuttle Engine Crate"
- desc = "Through advanced bluespace-shenanigans, our engineers have managed to fit an entire shuttle engine into one tiny little crate. Requires CE access to open."
- cost = 5000
- access = ACCESS_CE
- contains = list(/obj/structure/shuttle/engine/propulsion/burst/cargo)
- crate_name = "shuttle engine crate"
- crate_type = /obj/structure/closet/crate/secure/engineering
- special = TRUE
-
-/datum/supply_pack/engineering/tools
- name = "Toolbox Crate"
- desc = "Any robust spaceman is never far from their trusty toolbox. Contains three electrical toolboxes and three mechanical toolboxes."
- contains = list(/obj/item/storage/toolbox/electrical,
- /obj/item/storage/toolbox/electrical,
- /obj/item/storage/toolbox/electrical,
- /obj/item/storage/toolbox/mechanical,
- /obj/item/storage/toolbox/mechanical,
- /obj/item/storage/toolbox/mechanical)
- cost = 1000
- crate_name = "toolbox crate"
-
-/datum/supply_pack/engineering/bsa
- name = "Bluespace Artillery Parts"
- desc = "The pride of Nanotrasen Naval Command. The legendary Bluespace Artillery Cannon is a devastating feat of human engineering and testament to wartime determination. Highly advanced research is required for proper construction. "
- cost = 15000
- special = TRUE
- contains = list(/obj/item/circuitboard/machine/bsa/front,
- /obj/item/circuitboard/machine/bsa/middle,
- /obj/item/circuitboard/machine/bsa/back,
- /obj/item/circuitboard/computer/bsa_control
- )
- crate_name= "bluespace artillery parts crate"
-
-/datum/supply_pack/engineering/dna_vault
- name = "DNA Vault Parts"
- desc = "Secure the longevity of the current state of humanity within this massive library of scientific knowledge, capable of granting superhuman powers and abilities. Highly advanced research is required for proper construction. Also contains five DNA probes."
- cost = 12000
- special = TRUE
- contains = list(
- /obj/item/circuitboard/machine/dna_vault,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe
- )
- crate_name= "dna vault parts crate"
-
-/datum/supply_pack/engineering/dna_probes
- name = "DNA Vault Samplers"
- desc = "Contains five DNA probes for use in the DNA vault."
- cost = 3000
- special = TRUE
- contains = list(/obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe
- )
- crate_name= "dna samplers crate"
-
-
-/datum/supply_pack/engineering/shield_sat
- name = "Shield Generator Satellite"
- desc = "Protect the very existence of this station with these Anti-Meteor defenses. Contains three Shield Generator Satellites."
- cost = 4000
- contains = list(
- /obj/machinery/satellite/meteor_shield,
- /obj/machinery/satellite/meteor_shield,
- /obj/machinery/satellite/meteor_shield
- )
- crate_name= "shield sat crate"
-
-/datum/supply_pack/engineering/shield_sat_control
- name = "Shield System Control Board"
- desc = "A control system for the Shield Generator Satellite system."
- cost = 4000
- contains = list(/obj/item/circuitboard/computer/sat_control)
- crate_name= "shield control board crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////// Engine Construction /////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/engine
- group = "Engine Construction"
- crate_type = /obj/structure/closet/crate/engineering
-
-/datum/supply_pack/engine/am_jar
- name = "Antimatter Containment Jar Crate"
- desc = "Two Antimatter containment jars stuffed into a single crate."
- cost = 2000
- contains = list(/obj/item/am_containment,
- /obj/item/am_containment)
- crate_name = "antimatter jar crate"
-
-/datum/supply_pack/engine/am_core
- name = "Antimatter Control Crate"
- desc = "The brains of the Antimatter engine, this device is sure to teach the station's powergrid the true meaning of real power."
- cost = 5000
- contains = list(/obj/machinery/power/am_control_unit)
- crate_name = "antimatter control crate"
-
-/datum/supply_pack/engine/am_shielding
- name = "Antimatter Shielding Crate"
- desc = "Contains ten Antimatter shields, somehow crammed into a crate."
- cost = 2000
- contains = list(/obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container) //10 shields: 3x3 containment and a core
- crate_name = "antimatter shielding crate"
-
-/datum/supply_pack/engine/emitter
- name = "Emitter Crate"
- desc = "Useful for powering forcefield generators while destroying locked crates and intruders alike. Contains two high-powered energy emitters. Requires CE access to open."
- cost = 1500
- access = ACCESS_CE
- contains = list(/obj/machinery/power/emitter,
- /obj/machinery/power/emitter)
- crate_name = "emitter crate"
- crate_type = /obj/structure/closet/crate/secure/engineering
- dangerous = TRUE
-
-/datum/supply_pack/engine/field_gen
- name = "Field Generator Crate"
- desc = "Typically the only thing standing between the station and a messy death. Powered by emitters. Contains two field generators."
- cost = 1500
- contains = list(/obj/machinery/field/generator,
- /obj/machinery/field/generator)
- crate_name = "field generator crate"
-
-/datum/supply_pack/engine/grounding_rods
- name = "Grounding Rod Crate"
- desc = "Four grounding rods guaranteed to keep any uppity tesla's lightning under control."
- cost = 1700
- contains = list(/obj/machinery/power/grounding_rod,
- /obj/machinery/power/grounding_rod,
- /obj/machinery/power/grounding_rod,
- /obj/machinery/power/grounding_rod)
- crate_name = "grounding rod crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engine/mason
- name = "M.A.S.O.N RIG Crate"
- desc = "The rare M.A.S.O.N RIG. Requires CE access to open."
- cost = 15000
- access = ACCESS_CE
- contains = list(/obj/item/clothing/suit/space/hardsuit/ancient/mason)
- crate_name = "M.A.S.O.N Rig"
- crate_type = /obj/structure/closet/crate/secure/engineering
-
-/datum/supply_pack/engine/PA
- name = "Particle Accelerator Crate"
- desc = "A supermassive black hole or hyper-powered teslaball are the perfect way to spice up any party! This \"My First Apocalypse\" kit contains everything you need to build your own Particle Accelerator! Ages 10 and up."
- cost = 3000
- contains = list(/obj/structure/particle_accelerator/fuel_chamber,
- /obj/machinery/particle_accelerator/control_box,
- /obj/structure/particle_accelerator/particle_emitter/center,
- /obj/structure/particle_accelerator/particle_emitter/left,
- /obj/structure/particle_accelerator/particle_emitter/right,
- /obj/structure/particle_accelerator/power_box,
- /obj/structure/particle_accelerator/end_cap)
- crate_name = "particle accelerator crate"
-
-/datum/supply_pack/engine/collector
- name = "Radiation Collector Crate"
- desc = "Contains three radiation collectors. Useful for collecting energy off nearby Supermatter Crystals, Singularities or Teslas!"
- cost = 2500
- contains = list(/obj/machinery/power/rad_collector,
- /obj/machinery/power/rad_collector,
- /obj/machinery/power/rad_collector)
- crate_name = "collector crate"
-
-/datum/supply_pack/engine/sing_gen
- name = "Singularity Generator Crate"
- desc = "The key to unlocking the power of Lord Singuloth. Particle Accelerator not included."
- cost = 5000
- contains = list(/obj/machinery/the_singularitygen)
- crate_name = "singularity generator crate"
-
-/datum/supply_pack/engine/solar
- name = "Solar Panel Crate"
- desc = "Go green with this DIY advanced solar array. Contains twenty one solar assemblies, a solar-control circuit board, and tracker. If you have any questions, please check out the enclosed instruction book."
- cost = 2000
- contains = list(/obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/circuitboard/computer/solar_control,
- /obj/item/electronics/tracker,
- /obj/item/paper/guides/jobs/engi/solars)
- crate_name = "solar panel crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engine/supermatter_shard
- name = "Supermatter Shard Crate"
- desc = "The power of the heavens condensed into a single crystal. Requires CE access to open."
- cost = 10000
- access = ACCESS_CE
- contains = list(/obj/machinery/power/supermatter_crystal/shard)
- crate_name = "supermatter shard crate"
- crate_type = /obj/structure/closet/crate/secure/engineering
- dangerous = TRUE
-
-/datum/supply_pack/engine/tesla_coils
- name = "Tesla Coil Crate"
- desc = "Whether it's high-voltage executions, creating research points, or just plain old power generation: This pack of four Tesla coils can do it all!"
- cost = 2500
- contains = list(/obj/machinery/power/tesla_coil,
- /obj/machinery/power/tesla_coil,
- /obj/machinery/power/tesla_coil,
- /obj/machinery/power/tesla_coil)
- crate_name = "tesla coil crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engine/tesla_gen
- name = "Tesla Generator Crate"
- desc = "The key to unlocking the power of the Tesla energy ball. Particle Accelerator not included."
- cost = 5000
- contains = list(/obj/machinery/the_singularitygen/tesla)
- crate_name = "tesla generator crate"
-
-//////////////////////////////////////////////////////////////////////////////
-/////////////////////// Canisters & Materials ////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/materials
- group = "Canisters & Materials"
-
-/datum/supply_pack/materials/cardboard50
- name = "50 Cardboard Sheets"
- desc = "Create a bunch of boxes."
- cost = 1000
- contains = list(/obj/item/stack/sheet/cardboard/fifty)
- crate_name = "cardboard sheets crate"
-
-/datum/supply_pack/materials/glass50
- name = "50 Glass Sheets"
- desc = "Let some nice light in with fifty glass sheets!"
- cost = 1000
- contains = list(/obj/item/stack/sheet/glass/fifty)
- crate_name = "glass sheets crate"
-
-/datum/supply_pack/materials/metal50
- name = "50 Metal Sheets"
- desc = "Any construction project begins with a good stack of fifty metal sheets!"
- cost = 1000
- contains = list(/obj/item/stack/sheet/metal/fifty)
- crate_name = "metal sheets crate"
-
-/datum/supply_pack/materials/plasteel20
- name = "20 Plasteel Sheets"
- desc = "Reinforce the station's integrity with twenty plasteel sheets!"
- cost = 7500
- contains = list(/obj/item/stack/sheet/plasteel/twenty)
- crate_name = "plasteel sheets crate"
-
-/datum/supply_pack/materials/plasteel50
- name = "50 Plasteel Sheets"
- desc = "For when you REALLY have to reinforce something."
- cost = 16500
- contains = list(/obj/item/stack/sheet/plasteel/fifty)
- crate_name = "plasteel sheets crate"
-
-/datum/supply_pack/materials/plastic50
- name = "50 Plastic Sheets"
- desc = "Build a limitless amount of toys with fifty plastic sheets!"
- cost = 1000
- contains = list(/obj/item/stack/sheet/plastic/fifty)
- crate_name = "plastic sheets crate"
-
-/datum/supply_pack/materials/sandstone30
- name = "30 Sandstone Blocks"
- desc = "Neither sandy nor stoney, these thirty blocks will still get the job done."
- cost = 1000
- contains = list(/obj/item/stack/sheet/mineral/sandstone/thirty)
- crate_name = "sandstone blocks crate"
-
-/datum/supply_pack/materials/wood50
- name = "50 Wood Planks"
- desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with fifty wooden planks!"
- cost = 2000
- contains = list(/obj/item/stack/sheet/mineral/wood/fifty)
- crate_name = "wood planks crate"
-
-/datum/supply_pack/materials/rcdammo
- name = "Spare RDC ammo"
- desc = "This crate contains sixteen RCD ammo packs, to help with any holes or projects people mite be working on."
- cost = 3750
- contains = list(/obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo)
- crate_name = "rcd ammo"
-
-/datum/supply_pack/materials/bz
- name = "BZ Canister Crate"
- desc = "Contains a canister of BZ. Requires Toxins access to open."
- cost = 7500 // Costs 3 credits more than what you can get for selling it.
- access = ACCESS_TOX_STORAGE
- contains = list(/obj/machinery/portable_atmospherics/canister/bz)
- crate_name = "BZ canister crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/materials/carbon_dio
- name = "Carbon Dioxide Canister"
- desc = "Contains a canister of Carbon Dioxide."
- cost = 3000
- contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide)
- crate_name = "carbon dioxide canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/nitrogen
- name = "Nitrogen Canister"
- desc = "Contains a canister of Nitrogen."
- cost = 2000
- contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen)
- crate_name = "nitrogen canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/nitrous_oxide_canister
- name = "Nitrous Oxide Canister"
- desc = "Contains a canister of Nitrous Oxide. Requires Atmospherics access to open."
- cost = 3000
- access = ACCESS_ATMOSPHERICS
- contains = list(/obj/machinery/portable_atmospherics/canister/nitrous_oxide)
- crate_name = "nitrous oxide canister crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/materials/oxygen
- name = "Oxygen Canister"
- desc = "Contains a canister of Oxygen. Canned in Druidia."
- cost = 1500
- contains = list(/obj/machinery/portable_atmospherics/canister/oxygen)
- crate_name = "oxygen canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/water_vapor
- name = "Water Vapor Canister"
- desc = "Contains a canister of Water Vapor. I swear to god if you open this in the halls..."
- cost = 2500
- contains = list(/obj/machinery/portable_atmospherics/canister/water_vapor)
- crate_name = "water vapor canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/fueltank
- name = "Fuel Tank Crate"
- desc = "Contains a welding fuel tank. Caution, highly flammable."
- cost = 800
- contains = list(/obj/structure/reagent_dispensers/fueltank)
- crate_name = "fuel tank crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/watertank
- name = "Water Tank Crate"
- desc = "Contains a tank of dihydrogen monoxide... sounds dangerous."
- cost = 600
- contains = list(/obj/structure/reagent_dispensers/watertank)
- crate_name = "water tank crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/foamtank
- name = "Firefighting Foam Tank Crate"
- desc = "Contains a tank of firefighting foam. Also known as \"plasmaman's bane\"."
- cost = 1500
- contains = list(/obj/structure/reagent_dispensers/foamtank)
- crate_name = "foam tank crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/hightank
- name = "Large Water Tank Crate"
- desc = "Contains a high-capacity water tank. Useful for botany or other service jobs."
- cost = 1200
- contains = list(/obj/structure/reagent_dispensers/watertank/high)
- crate_name = "high-capacity water tank crate"
- crate_type = /obj/structure/closet/crate/large
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Medical /////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/medical
- group = "Medical"
- crate_type = /obj/structure/closet/crate/medical
-
-/datum/supply_pack/medical/firstaidbruises
- name = "Bruise Treatment Kit Crate"
- desc = "Contains three first aid kits focused on healing bruises and broken bones."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/brute,
- /obj/item/storage/firstaid/brute,
- /obj/item/storage/firstaid/brute)
- crate_name = "brute treatment kit crate"
-
-/datum/supply_pack/medical/firstaidburns
- name = "Burn Treatment Kit Crate"
- desc = "Contains three first aid kits focused on healing severe burns."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/fire,
- /obj/item/storage/firstaid/fire,
- /obj/item/storage/firstaid/fire)
- crate_name = "burn treatment kit crate"
-
-/datum/supply_pack/medical/bloodpacks
- name = "Blood Pack Variety Crate"
- desc = "Contains eight different blood packs for reintroducing blood to patients."
- cost = 3000
- contains = list(/obj/item/reagent_containers/blood,
- /obj/item/reagent_containers/blood,
- /obj/item/reagent_containers/blood/APlus,
- /obj/item/reagent_containers/blood/AMinus,
- /obj/item/reagent_containers/blood/BPlus,
- /obj/item/reagent_containers/blood/BMinus,
- /obj/item/reagent_containers/blood/OPlus,
- /obj/item/reagent_containers/blood/OMinus,
- /obj/item/reagent_containers/blood/lizard)
- crate_name = "blood freezer"
- crate_type = /obj/structure/closet/crate/freezer
-
-/datum/supply_pack/medical/defibs
- name = "Defibrillator Crate"
- desc = "Contains two defibrillators for bringing the recently deceased back to life."
- cost = 2500
- contains = list(/obj/item/defibrillator/loaded,
- /obj/item/defibrillator/loaded)
- crate_name = "defibrillator crate"
-
-/datum/supply_pack/medical/firstaid
- name = "First Aid Kit Crate"
- desc = "Contains four first aid kits for healing most types of wounds."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/regular,
- /obj/item/storage/firstaid/regular,
- /obj/item/storage/firstaid/regular,
- /obj/item/storage/firstaid/regular)
- crate_name = "first aid kit crate"
-
-/datum/supply_pack/medical/iv_drip
- name = "IV Drip Crate"
- desc = "Contains a single IV drip stand for intravenous delivery."
- cost = 700
- contains = list(/obj/machinery/iv_drip)
- crate_name = "iv drip crate"
-
-/datum/supply_pack/science/adv_surgery_tools
- name = "Med-Co Advanced surgery tools"
- desc = "A full set of Med-Co advanced surgery tools, this crate also comes with a spay of synth flesh as well as a can of . Requires Surgery access to open."
- cost = 5000
- access = ACCESS_SURGERY
- contains = list(/obj/item/storage/belt/medical/surgery_belt_adv,
- /obj/item/reagent_containers/medspray/synthflesh,
- /obj/item/reagent_containers/medspray/sterilizine)
- crate_name = "medco newest surgery tools"
- crate_type = /obj/structure/closet/crate/medical
-
-/datum/supply_pack/medical/medicalhardsuit
- name = "Medical Hardsuit"
- desc = "Got people being spaced left and right? Hole in the same room as the dead body of Hos or cap? Fear not, now you can buy one medical hardsuit with a mask and air tank to save your fellow crewmembers."
- cost = 2500
- contains = list(/obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/suit/space/hardsuit/medical)
- crate_name = "medical hardsuit"
-
-/datum/supply_pack/medical/supplies
- name = "Medical Supplies Crate"
- desc = "Contains seven beakers, syringes, and bodybags. Three morphine bottles, four insulin pills. Two charcoal bottles, epinephrine bottles, antitoxin bottles, and large beakers. Finally, a single roll of medical gauze, as well as a bottle of stimulant pills for long, hard work days. German doctor not included."
- cost = 2500
- contains = list(/obj/item/reagent_containers/glass/bottle/charcoal,
- /obj/item/reagent_containers/glass/bottle/charcoal,
- /obj/item/reagent_containers/glass/bottle/epinephrine,
- /obj/item/reagent_containers/glass/bottle/epinephrine,
- /obj/item/reagent_containers/glass/bottle/morphine,
- /obj/item/reagent_containers/glass/bottle/morphine,
- /obj/item/reagent_containers/glass/bottle/morphine,
- /obj/item/reagent_containers/glass/bottle/toxin,
- /obj/item/reagent_containers/glass/bottle/toxin,
- /obj/item/reagent_containers/glass/beaker/large,
- /obj/item/reagent_containers/glass/beaker/large,
- /obj/item/reagent_containers/pill/insulin,
- /obj/item/reagent_containers/pill/insulin,
- /obj/item/reagent_containers/pill/insulin,
- /obj/item/reagent_containers/pill/insulin,
- /obj/item/stack/medical/gauze,
- /obj/item/storage/box/beakers,
- /obj/item/storage/box/medsprays,
- /obj/item/storage/box/syringes,
- /obj/item/storage/box/bodybags,
- /obj/item/storage/pill_bottle/stimulant)
- crate_name = "medical supplies crate"
-
-/datum/supply_pack/medical/vending
- name = "Medical Vending Crate"
- desc = "Contains refills for medical vending machines."
- cost = 2000
- contains = list(/obj/item/vending_refill/medical,
- /obj/item/vending_refill/wallmed)
- crate_name = "medical vending crate"
-
-/datum/supply_pack/medical/sprays
- name = "Medical Sprays"
- desc = "Contains two cans of Styptic Spray, Silver Sulfadiazine Spray, Synthflesh Spray and Sterilizer Compound Spray."
- cost = 2500
- contains = list(/obj/item/reagent_containers/medspray/styptic,
- /obj/item/reagent_containers/medspray/styptic,
- /obj/item/reagent_containers/medspray/silver_sulf,
- /obj/item/reagent_containers/medspray/silver_sulf,
- /obj/item/reagent_containers/medspray/synthflesh,
- /obj/item/reagent_containers/medspray/synthflesh,
- /obj/item/reagent_containers/medspray/sterilizine,
- /obj/item/reagent_containers/medspray/sterilizine)
- crate_name = "medical supplies crate"
-
-/datum/supply_pack/medical/firstaidmixed
- name = "Mixed Medical Kits"
- desc = "Contains one of each medical kits for dealing with a variety of injured crewmembers."
- cost = 1500
- contains = list(/obj/item/storage/firstaid/toxin,
- /obj/item/storage/firstaid/o2,
- /obj/item/storage/firstaid/brute,
- /obj/item/storage/firstaid/fire,
- /obj/item/storage/firstaid/regular)
- crate_name = "medical supplies crate"
-
-/datum/supply_pack/medical/firstaidoxygen
- name = "Oxygen Deprivation Kit Crate"
- desc = "Contains three first aid kits focused on helping oxygen deprivation victims."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/o2,
- /obj/item/storage/firstaid/o2,
- /obj/item/storage/firstaid/o2)
- crate_name = "oxygen deprivation kit crate"
-
-/datum/supply_pack/medical/advrad
- name = "Radiation Treatment Crate Deluxe"
- desc = "A crate for when radiation is out of hand... Contains two rad-b-gone kits, one bottle of anti radiation deluxe pill bottle, as well as a radiation treatment deluxe pill bottle!"
- cost = 3500
- contains = list(/obj/item/storage/pill_bottle/antirad_plus,
- /obj/item/storage/pill_bottle/mutarad,
- /obj/item/storage/firstaid/radbgone,
- /obj/item/storage/firstaid/radbgone,
- /obj/item/geiger_counter,
- /obj/item/geiger_counter)
- crate_name = "radiation protection crate"
- crate_type = /obj/structure/closet/crate/radiation
-
-/datum/supply_pack/medical/surgery
- name = "Surgical Supplies Crate"
- desc = "Do you want to perform surgery, but don't have one of those fancy shmancy degrees? Just get started with this crate containing a medical duffelbag, Sterilizine spray and collapsible roller bed."
- cost = 1000
- contains = list(/obj/item/storage/backpack/duffelbag/med/surgery,
- /obj/item/reagent_containers/medspray/sterilizine,
- /obj/item/roller)
- crate_name = "surgical supplies crate"
-
-/datum/supply_pack/medical/firstaidtoxins
- name = "Toxin Treatment Kit Crate"
- desc = "Contains three first aid kits focused on healing damage dealt by heavy toxins."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/toxin,
- /obj/item/storage/firstaid/toxin,
- /obj/item/storage/firstaid/toxin)
- crate_name = "toxin treatment kit crate"
-
-/datum/supply_pack/medical/virus
- name = "Virus Crate"
- desc = "Contains twelve different bottles, containing several viral samples for virology research. Also includes seven beakers and syringes. Balled-up jeans not included. Requires CMO access to open."
- cost = 2500
- access = ACCESS_CMO
- contains = list(/obj/item/reagent_containers/glass/bottle/flu_virion,
- /obj/item/reagent_containers/glass/bottle/cold,
- /obj/item/reagent_containers/glass/bottle/random_virus,
- /obj/item/reagent_containers/glass/bottle/random_virus,
- /obj/item/reagent_containers/glass/bottle/random_virus,
- /obj/item/reagent_containers/glass/bottle/random_virus,
- /obj/item/reagent_containers/glass/bottle/fake_gbs,
- /obj/item/reagent_containers/glass/bottle/magnitis,
- /obj/item/reagent_containers/glass/bottle/pierrot_throat,
- /obj/item/reagent_containers/glass/bottle/brainrot,
- /obj/item/reagent_containers/glass/bottle/anxiety,
- /obj/item/reagent_containers/glass/bottle/beesease,
- /obj/item/storage/box/syringes,
- /obj/item/storage/box/beakers,
- /obj/item/reagent_containers/glass/bottle/mutagen)
- crate_name = "virus crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
- dangerous = TRUE
-
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Science /////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/science
- group = "Science"
- crate_type = /obj/structure/closet/crate/science
-
-/datum/supply_pack/science/robotics/mecha_odysseus
- name = "Circuit Crate (Odysseus)"
- desc = "Ever wanted to build your own giant medical robot? Well, now you can! Contains the Odysseus main control board and Odysseus peripherals board. Requires Robotics access to open."
- cost = 2500
- access = ACCESS_ROBOTICS
- contains = list(/obj/item/circuitboard/mecha/odysseus/peripherals,
- /obj/item/circuitboard/mecha/odysseus/main)
- crate_name = "\improper Odysseus circuit crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/science/robotics/mecha_ripley
- name = "Circuit Crate (Ripley APLU)"
- desc = "Rip apart rocks and xenomorphs alike with the Ripley APLU. Contains the Main Ripley control board, as well as the Ripley Peripherals board. Requires Robotics access to open."
- cost = 3000
- access = ACCESS_ROBOTICS
- contains = list(/obj/item/book/manual/ripley_build_and_repair,
- /obj/item/circuitboard/mecha/ripley/main,
- /obj/item/circuitboard/mecha/ripley/peripherals)
- crate_name = "\improper APLU Ripley circuit crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/science/circuitry
- name = "Circuitry Starter Pack Crate"
- desc = "Journey into the mysterious world of Circuitry with this starter pack. Contains a circuit printer, analyzer, debugger and wirer. Power cells not included."
- cost = 1000
- contains = list(/obj/item/integrated_electronics/analyzer,
- /obj/item/integrated_circuit_printer,
- /obj/item/integrated_electronics/debugger,
- /obj/item/integrated_electronics/wirer)
- crate_name = "circuitry starter pack crate"
-
-/datum/supply_pack/science/plasma
- name = "Plasma Assembly Crate"
- desc = "Everything you need to burn something to the ground, this contains three plasma assembly sets. Each set contains a plasma tank, igniter, proximity sensor, and timer! Warranty void if exposed to high temperatures. Requires Toxins access to open."
- cost = 1000
- access = ACCESS_TOX_STORAGE
- contains = list(/obj/item/tank/internals/plasma,
- /obj/item/tank/internals/plasma,
- /obj/item/tank/internals/plasma,
- /obj/item/assembly/igniter,
- /obj/item/assembly/igniter,
- /obj/item/assembly/igniter,
- /obj/item/assembly/prox_sensor,
- /obj/item/assembly/prox_sensor,
- /obj/item/assembly/prox_sensor,
- /obj/item/assembly/timer,
- /obj/item/assembly/timer,
- /obj/item/assembly/timer)
- crate_name = "plasma assembly crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-/datum/supply_pack/science/robotics
- name = "Robotics Assembly Crate"
- desc = "The tools you need to replace those finicky humans with a loyal robot army! Contains three proximity sensors, two high-powered cells, six flashes, and an electrical toolbox. Requires Robotics access to open."
- cost = 1000
- access = ACCESS_ROBOTICS
- contains = list(/obj/item/assembly/prox_sensor,
- /obj/item/assembly/prox_sensor,
- /obj/item/assembly/prox_sensor,
- /obj/item/storage/toolbox/electrical,
- /obj/item/storage/box/flashes,
- /obj/item/stock_parts/cell/high,
- /obj/item/stock_parts/cell/high)
- crate_name = "robotics assembly crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/science/shieldwalls
- name = "Shield Generator Crate"
- desc = "These high powered Shield Wall Generators are guaranteed to keep any unwanted lifeforms on the outside, where they belong! Contains four shield wall generators. Requires Teleporter access to open."
- cost = 2000
- access = ACCESS_TELEPORTER
- contains = list(/obj/machinery/shieldwallgen,
- /obj/machinery/shieldwallgen,
- /obj/machinery/shieldwallgen,
- /obj/machinery/shieldwallgen)
- crate_name = "shield generators crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/science/tablets
- name = "Tablet Crate"
- desc = "What's a computer? Contains five cargo tablets."
- cost = 5000
- contains = list(/obj/item/modular_computer/tablet/preset/cargo,
- /obj/item/modular_computer/tablet/preset/cargo,
- /obj/item/modular_computer/tablet/preset/cargo,
- /obj/item/modular_computer/tablet/preset/cargo,
- /obj/item/modular_computer/tablet/preset/cargo)
- crate_name = "tablet crate"
-
-/datum/supply_pack/science/transfer_valves
- name = "Tank Transfer Valves Crate"
- desc = "The key ingredient for making a lot of people very angry very fast. Contains two tank transfer valves. Requires RD access to open."
- cost = 6000
- access = ACCESS_RD
- contains = list(/obj/item/transfer_valve,
- /obj/item/transfer_valve)
- crate_name = "tank transfer valves crate"
- crate_type = /obj/structure/closet/crate/secure/science
- dangerous = TRUE
-
-/datum/supply_pack/science/tech_slugs
- name = "Tech Slug Ammo Shells"
- desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all."
- cost = 1000
- contains = list(/obj/item/storage/box/techsslug,
- /obj/item/storage/box/techsslug)
- crate_name = "tech slug crate"
-
-
-//////////////////////////////////////////////////////////////////////////////
-/////////////////////////////// Service //////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/service
- group = "Service"
-
-/datum/supply_pack/service/advlighting
- name = "Advanced Lighting crate"
- desc = "Thanks to advanced lighting tech we here at the Lamp Factory have be able to produce more lamps and lamp items! This crate has three lamps, a box of lights and a state of the art rapid-light-device!"
- cost = 2500 //Fair
- contains = list(/obj/item/construction/rld,
- /obj/item/flashlight/lamp,
- /obj/item/flashlight/lamp,
- /obj/item/flashlight/lamp/green,
- /obj/item/storage/box/lights/mixed)
- crate_name = "advanced lighting crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/service/cargo_supples
- name = "Cargo Supplies Crate"
- desc = "Sold everything that wasn't bolted down? You can get right back to work with this crate containing stamps, an export scanner, destination tagger, hand labeler and some package wrapping."
- cost = 1000
- contains = list(/obj/item/stamp,
- /obj/item/stamp/denied,
- /obj/item/export_scanner,
- /obj/item/destTagger,
- /obj/item/hand_labeler,
- /obj/item/stack/packageWrap)
- crate_name = "cargo supplies crate"
-
-/datum/supply_pack/service/food_cart
- name = "Food Cart Crate"
- desc = "Want to sell food on the go? Cook lost their cart? Well we just so happen to have a few carts to spare!"
- cost = 1000
- contains = list(/obj/machinery/food_cart)
- crate_name = "food cart crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/noslipfloor
- name = "High-traction Floor Tiles"
- desc = "Make slipping a thing of the past with sixty industrial-grade anti-slip floortiles!"
- cost = 2000
- contains = list(/obj/item/stack/tile/noslip/thirty,
- /obj/item/stack/tile/noslip/thirty)
- crate_name = "high-traction floor tiles crate"
-
-/datum/supply_pack/service/icecream_cart
- name = "Ice Cream Cart Crate"
- desc = "Plasma fire a to hot for you, want a nice treat after a hard days work? Well now we have the cart for you! This Ice Cream Vat has everthing you need to make you and your friends so ice cream treats! This cart comes stocked with some ingredients for each type of scoopable icecream."
- cost = 2750 //Comes prestocked with basic ingredients
- contains = list(/obj/machinery/icecream_vat)
- crate_name = "ice cream vat crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/janitor
- name = "Janitorial Supplies Crate"
- desc = "Fight back against dirt and grime with Nanotrasen's Janitorial Essentials(tm)! Contains three buckets, caution signs, and cleaner grenades. Also has a single mop, spray cleaner, rag, NT soap and a trash bag."
- cost = 1000
- contains = list(/obj/item/reagent_containers/glass/bucket,
- /obj/item/reagent_containers/glass/bucket,
- /obj/item/reagent_containers/glass/bucket,
- /obj/item/mop,
- /obj/item/caution,
- /obj/item/caution,
- /obj/item/caution,
- /obj/item/storage/bag/trash,
- /obj/item/reagent_containers/spray/cleaner,
- /obj/item/reagent_containers/rag,
- /obj/item/grenade/chem_grenade/cleaner,
- /obj/item/grenade/chem_grenade/cleaner,
- /obj/item/grenade/chem_grenade/cleaner,
- /obj/item/soap/nanotrasen)
- crate_name = "janitorial supplies crate"
-
-/datum/supply_pack/service/janitor/janicart
- name = "Janitorial Cart and Galoshes Crate"
- desc = "The keystone to any successful janitor. As long as you have feet, this pair of galoshes will keep them firmly planted on the ground. Also contains a janitorial cart."
- cost = 2000
- contains = list(/obj/structure/janitorialcart,
- /obj/item/clothing/shoes/galoshes)
- crate_name = "janitorial cart crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/service/janitor/janitank
- name = "Janitor Backpack Crate"
- desc = "Call forth divine judgement upon dirt and grime with this high capacity janitor backpack. Contains 500 units of station-cleansing cleaner. Requires janitor access to open."
- cost = 1000
- access = ACCESS_JANITOR
- contains = list(/obj/item/watertank/janitor)
- crate_name = "janitor backpack crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/service/janitor/janpremium
- name = "Janitor Premium Supplies"
- desc = "Do to the union for better supplies, we have desided to make a deal for you, In this crate you can get a brand new chem, Drying Angent this stuff is the work of slimes or magic! This crate also contains a rag to test out the Drying Angent magic, three wet floor signs, and some spare bottles of ammonia."
- cost = 1750
- access = ACCESS_JANITOR
- contains = list(/obj/item/caution,
- /obj/item/caution,
- /obj/item/caution,
- /obj/item/reagent_containers/rag,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/reagent_containers/spray/drying_agent)
- crate_name = "janitor backpack crate"
-
-/datum/supply_pack/service/janitor/janpimp
- name = "Custodial Cruiser"
- desc = "Clown steal your ride? Assistant lock it in the dorms? Order a new one and get back to cleaning in style!"
- cost = 3000
- access = ACCESS_JANITOR
- contains = list(/obj/vehicle/ridden/janicart,
- /obj/item/key/janitor)
- crate_name = "janitor ride crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/service/mule
- name = "MULEbot Crate"
- desc = "Pink-haired Quartermaster not doing her job? Replace her with this tireless worker, today!"
- cost = 2000
- contains = list(/mob/living/simple_animal/bot/mulebot)
- crate_name = "\improper MULEbot Crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/service/party
- name = "Party Equipment"
- desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, and a bottle of patron, goldschlager, and shaker!"
- cost = 2000
- contains = list(/obj/item/storage/box/drinkingglasses,
- /obj/item/reagent_containers/food/drinks/shaker,
- /obj/item/reagent_containers/food/drinks/bottle/patron,
- /obj/item/reagent_containers/food/drinks/bottle/goldschlager,
- /obj/item/reagent_containers/food/drinks/ale,
- /obj/item/reagent_containers/food/drinks/ale,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/flashlight/glowstick,
- /obj/item/flashlight/glowstick/red,
- /obj/item/flashlight/glowstick/blue,
- /obj/item/flashlight/glowstick/cyan,
- /obj/item/flashlight/glowstick/orange,
- /obj/item/flashlight/glowstick/yellow,
- /obj/item/flashlight/glowstick/pink)
- crate_name = "party equipment crate"
-
-/datum/supply_pack/service/carpet
- name = "Premium Carpet Crate"
- desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains the classics."
- cost = 1000
- contains = list(/obj/item/stack/tile/carpet/fifty,
- /obj/item/stack/tile/carpet/fifty,
- /obj/item/stack/tile/carpet/black/fifty,
- /obj/item/stack/tile/carpet/black/fifty)
- crate_name = "premium carpet crate"
-
-/datum/supply_pack/service/carpet_exotic
- name = "Exotic Carpet Crate"
- desc = "Exotic carpets straight from Space Russia, for all your decorating needs. Contains 100 tiles each of 10 different flooring patterns."
- cost = 4000
- contains = list(/obj/item/stack/tile/carpet/blue/fifty,
- /obj/item/stack/tile/carpet/blue/fifty,
- /obj/item/stack/tile/carpet/cyan/fifty,
- /obj/item/stack/tile/carpet/cyan/fifty,
- /obj/item/stack/tile/carpet/green/fifty,
- /obj/item/stack/tile/carpet/green/fifty,
- /obj/item/stack/tile/carpet/orange/fifty,
- /obj/item/stack/tile/carpet/orange/fifty,
- /obj/item/stack/tile/carpet/purple/fifty,
- /obj/item/stack/tile/carpet/purple/fifty,
- /obj/item/stack/tile/carpet/red/fifty,
- /obj/item/stack/tile/carpet/red/fifty,
- /obj/item/stack/tile/carpet/royalblue/fifty,
- /obj/item/stack/tile/carpet/royalblue/fifty,
- /obj/item/stack/tile/carpet/royalblack/fifty,
- /obj/item/stack/tile/carpet/royalblack/fifty,
- /obj/item/stack/tile/carpet/blackred/fifty,
- /obj/item/stack/tile/carpet/blackred/fifty,
- /obj/item/stack/tile/carpet/monochrome/fifty,
- /obj/item/stack/tile/carpet/monochrome/fifty)
- crate_name = "exotic carpet crate"
-
-/datum/supply_pack/service/lightbulbs
- name = "Replacement Lights"
- desc = "May the light of Aether shine upon this station! Or at least, the light of forty two light tubes and twenty one light bulbs as well as a light replacer."
- cost = 1200
- contains = list(/obj/item/storage/box/lights/mixed,
- /obj/item/storage/box/lights/mixed,
- /obj/item/storage/box/lights/mixed,
- /obj/item/lightreplacer)
- crate_name = "replacement lights"
-
-/datum/supply_pack/service/minerkit
- name = "Shaft Miner Starter Kit"
- desc = "All the miners died too fast? Assistant wants to get a taste of life off-station? Either way, this kit is the best way to turn a regular crewman into an ore-producing, monster-slaying machine. Contains meson goggles, a pickaxe, advanced mining scanner, cargo headset, ore bag, gasmask, and explorer suit. Requires QM access to open."
- cost = 2500
- access = ACCESS_QM
- contains = list(/obj/item/pickaxe/mini,
- /obj/item/clothing/glasses/meson,
- /obj/item/t_scanner/adv_mining_scanner/lesser,
- /obj/item/radio/headset/headset_cargo/mining,
- /obj/item/storage/bag/ore,
- /obj/item/clothing/suit/hooded/explorer/standard,
- /obj/item/clothing/mask/gas/explorer)
- crate_name = "shaft miner starter kit"
- crate_type = /obj/structure/closet/crate/secure
-
-//////////////////////////////////////////////////////////////////////////////
-/////////////////////////// Vending Restocks /////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/service/vending/bartending
- name = "Bartending Supply Crate"
- desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!"
- cost = 2000
- contains = list(/obj/item/vending_refill/boozeomat,
- /obj/item/vending_refill/coffee,
- /obj/item/book/granter/action/drink_fling)
- crate_name = "bartending supply crate"
-
-/datum/supply_pack/service/vending/cigarette
- name = "Cigarette Supply Crate"
- desc = "Don't believe the reports - smoke today! Contains a cigarette vending machine refill."
- cost = 1500
- contains = list(/obj/item/vending_refill/cigarette)
- crate_name = "cigarette supply crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/vending/games
- name = "Games Supply Crate"
- desc = "Get your game on with this game vending machine refill."
- cost = 1000
- contains = list(/obj/item/vending_refill/games)
- crate_name = "games supply crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/vending/snack
- name = "Snack Supply Crate"
- desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!"
- cost = 1500
- contains = list(/obj/item/vending_refill/snack)
- crate_name = "snacks supply crate"
-
-/datum/supply_pack/service/vending/cola
- name = "Softdrinks Supply Crate"
- desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with this soda machine refill, today!"
- cost = 1500
- contains = list(/obj/item/vending_refill/cola)
- crate_name = "soft drinks supply crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Organic /////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/organic
- group = "Food & Hydroponics"
- crate_type = /obj/structure/closet/crate/freezer
-
-/datum/supply_pack/organic/hydroponics/beekeeping_suits
- name = "Beekeeper Suit Crate"
- desc = "Bee business booming? Better be benevolent and boost botany by bestowing bi-Beekeeper-suits! Contains two beekeeper suits and matching headwear."
- cost = 1000
- contains = list(/obj/item/clothing/head/beekeeper_head,
- /obj/item/clothing/suit/beekeeper_suit,
- /obj/item/clothing/head/beekeeper_head,
- /obj/item/clothing/suit/beekeeper_suit)
- crate_name = "beekeeper suits"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/hydroponics/beekeeping_fullkit
- name = "Beekeeping Starter Crate"
- desc = "BEES BEES BEES. Contains three honey frames, a beekeeper suit and helmet, flyswatter, bee house, and, of course, a pure-bred Nanotrasen-Standardized Queen Bee!"
- cost = 1500
- contains = list(/obj/structure/beebox/unwrenched,
- /obj/item/honey_frame,
- /obj/item/honey_frame,
- /obj/item/honey_frame,
- /obj/item/queen_bee/bought,
- /obj/item/clothing/head/beekeeper_head,
- /obj/item/clothing/suit/beekeeper_suit,
- /obj/item/melee/flyswatter)
- crate_name = "beekeeping starter crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/candy
- name = "Candy Crate"
- desc = "For people that have a insatiable sweet tooth! Has ten candies to be eaten up.."
- cost = 2500
- var/num_contained = 10 //number of items picked to be contained in a randomised crate
- contains = list(/obj/item/reagent_containers/food/snacks/candy,
- /obj/item/reagent_containers/food/snacks/lollipop,
- /obj/item/reagent_containers/food/snacks/gumball,
- /obj/item/reagent_containers/food/snacks/chocolateegg,
- /obj/item/reagent_containers/food/snacks/donut,
- /obj/item/reagent_containers/food/snacks/cookie,
- /obj/item/reagent_containers/food/snacks/sugarcookie,
- /obj/item/reagent_containers/food/snacks/chococornet,
- /obj/item/reagent_containers/food/snacks/mint,
- /obj/item/reagent_containers/food/snacks/spiderlollipop,
- /obj/item/reagent_containers/food/snacks/chococoin,
- /obj/item/reagent_containers/food/snacks/fudgedice,
- /obj/item/reagent_containers/food/snacks/chocoorange,
- /obj/item/reagent_containers/food/snacks/honeybar,
- /obj/item/reagent_containers/food/snacks/tinychocolate,
- /obj/item/reagent_containers/food/snacks/spacetwinkie,
- /obj/item/reagent_containers/food/snacks/syndicake,
- /obj/item/reagent_containers/food/snacks/cheesiehonkers,
- /obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull,
- /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin,
- /obj/item/reagent_containers/food/snacks/candy_corn,
- /obj/item/reagent_containers/food/snacks/candiedapple,
- /obj/item/reagent_containers/food/snacks/chocolatebar,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/storage/fancy/heart_box,
- /obj/item/storage/fancy/donut_box)
- crate_name = "candy crate"
-
-/datum/supply_pack/organic/cutlery
- name = "Kitchen Cutlery Deluxe Set"
- desc = "Need to slice and dice away those ''Tomatos'' well we got what you need! From a nice set of knifes, forks, plates, glasses, and a whetstone for when you got some grizzle that is a bit harder to slice then normal."
- cost = 10000
- contraband = TRUE
- contains = list(/obj/item/sharpener,
- /obj/item/kitchen/fork,
- /obj/item/kitchen/fork,
- /obj/item/kitchen/knife,
- /obj/item/kitchen/knife,
- /obj/item/kitchen/knife,
- /obj/item/kitchen/knife,
- /obj/item/kitchen/knife/butcher,
- /obj/item/kitchen/knife/butcher,
- /obj/item/kitchen/rollingpin, //Deluxe for a reason
- /obj/item/trash/plate,
- /obj/item/trash/plate,
- /obj/item/trash/plate,
- /obj/item/trash/plate,
- /obj/item/reagent_containers/food/drinks/drinkingglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
- crate_name = "kitchen cutlery deluxe set"
-
-/datum/supply_pack/organic/food
- name = "Food Crate"
- desc = "Get things cooking with this crate full of useful ingredients! Contains a two dozen eggs, three bananas, and two bags of flour and rice, two cartons of milk, soymilk, as well as salt and pepper shakers, a enzyme and sugar bottle, and three slabs of monkeymeat."
- cost = 1000
- contains = list(/obj/item/reagent_containers/food/condiment/flour,
- /obj/item/reagent_containers/food/condiment/flour,
- /obj/item/reagent_containers/food/condiment/rice,
- /obj/item/reagent_containers/food/condiment/rice,
- /obj/item/reagent_containers/food/condiment/milk,
- /obj/item/reagent_containers/food/condiment/milk,
- /obj/item/reagent_containers/food/condiment/soymilk,
- /obj/item/reagent_containers/food/condiment/saltshaker,
- /obj/item/reagent_containers/food/condiment/peppermill,
- /obj/item/storage/fancy/egg_box,
- /obj/item/storage/fancy/egg_box,
- /obj/item/reagent_containers/food/condiment/enzyme,
- /obj/item/reagent_containers/food/condiment/sugar,
- /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
- /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
- /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
- /obj/item/reagent_containers/food/snacks/grown/banana,
- /obj/item/reagent_containers/food/snacks/grown/banana,
- /obj/item/reagent_containers/food/snacks/grown/banana)
- crate_name = "food crate"
-
-/datum/supply_pack/organic/cream_piee
- name = "High-yield Clown-grade Cream Pie Crate"
- desc = "Designed by Aussec's Advanced Warfare Research Division, these high-yield, Clown-grade cream pies are powered by a synergy of performance and efficiency. Guaranteed to provide maximum results."
- cost = 6000
- contains = list(/obj/item/storage/backpack/duffelbag/clown/cream_pie)
- crate_name = "party equipment crate"
- contraband = TRUE
- access = ACCESS_THEATRE
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/organic/hunting
- name = "Huntting gear"
- desc = "Even in space, we can fine prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a huntting shotgun. "
- cost = 3500
- contraband = TRUE
- contains = list(/obj/item/clothing/head/flatcap,
- /obj/item/clothing/suit/hooded/wintercoat/captain,
- /obj/item/reagent_containers/food/drinks/bottle/cognac,
- /obj/item/storage/fancy/cigarettes/cigars/havana,
- /obj/item/clothing/gloves/color/white,
- /obj/item/clothing/under/rank/curator,
- /obj/item/gun/ballistic/shotgun/lethal)
- access = ACCESS_ARMORY
- crate_name = "sporting crate"
- crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:(
-
-/datum/supply_pack/organic/hydroponics
- name = "Hydroponics Crate"
- desc = "Supplies for growing a great garden! Contains two bottles of ammonia, two Plant-B-Gone spray bottles, a hatchet, cultivator, plant analyzer, as well as a pair of leather gloves and a botanist's apron."
- cost = 1500
- contains = list(/obj/item/reagent_containers/spray/plantbgone,
- /obj/item/reagent_containers/spray/plantbgone,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/hatchet,
- /obj/item/cultivator,
- /obj/item/plant_analyzer,
- /obj/item/clothing/gloves/botanic_leather,
- /obj/item/clothing/suit/apron)
- crate_name = "hydroponics crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/hydroponics/hydrotank
- name = "Hydroponics Backpack Crate"
- desc = "Bring on the flood with this high-capacity backpack crate. Contains 500 units of life-giving H2O. Requires hydroponics access to open."
- cost = 1000
- access = ACCESS_HYDROPONICS
- contains = list(/obj/item/watertank)
- crate_name = "hydroponics backpack crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/organic/mre
- name = "MRE supply kit (emergency rations)"
- desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank."
- cost = 2000
- contains = list(/obj/item/storage/box/mre/menu1/safe,
- /obj/item/storage/box/mre/menu1/safe,
- /obj/item/storage/box/mre/menu2/safe,
- /obj/item/storage/box/mre/menu2/safe,
- /obj/item/storage/box/mre/menu3,
- /obj/item/storage/box/mre/menu4/safe)
- crate_name = "MRE crate (emergency rations)"
-
-/datum/supply_pack/organic/pizza
- name = "Pizza Crate"
- desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!"
- cost = 6000 // Best prices this side of the galaxy.
- contains = list(/obj/item/pizzabox/margherita,
- /obj/item/pizzabox/mushroom,
- /obj/item/pizzabox/meat,
- /obj/item/pizzabox/vegetable,
- /obj/item/pizzabox/pineapple)
- crate_name = "pizza crate"
- var/static/anomalous_box_provided = FALSE
-
-/datum/supply_pack/organic/pizza/fill(obj/structure/closet/crate/C)
- . = ..()
- if(!anomalous_box_provided)
- for(var/obj/item/pizzabox/P in C)
- if(prob(1)) //1% chance for each box, so 4% total chance per order
- var/obj/item/pizzabox/infinite/fourfiveeight = new(C)
- fourfiveeight.boxtag = P.boxtag
- qdel(P)
- anomalous_box_provided = TRUE
- log_game("An anomalous pizza box was provided in a pizza crate at during cargo delivery")
- if(prob(50))
- addtimer(CALLBACK(src, .proc/anomalous_pizza_report), rand(300, 1800))
- else
- message_admins("An anomalous pizza box was silently created with no command report in a pizza crate delivery.")
- break
-
-/datum/supply_pack/organic/pizza/proc/anomalous_pizza_report()
- print_command_report("[station_name()], our anomalous materials divison has reported a missing object that is highly likely to have been sent to your station during a routine cargo \
- delivery. Please search all crates and manifests provided with the delivery and return the object if is located. The object resembles a standard \[DATA EXPUNGED\] and is to be \
- considered \[REDACTED\] and returned at your leisure. Note that objects the anomaly produces are specifically attuned exactly to the individual opening the anomaly; regardless \
- of species, the individual will find the object edible and it will taste great according to their personal definitions, which vary significantly based on person and species.")
-
-/datum/supply_pack/organic/potted_plants
- name = "Potted Plants Crate"
- desc = "Spruce up the station with these lovely plants! Contains a random assortment of five potted plants from Nanotrasen's potted plant research division. Warranty void if thrown."
- cost = 700
- contains = list(/obj/item/twohanded/required/kirbyplants/random,
- /obj/item/twohanded/required/kirbyplants/random,
- /obj/item/twohanded/required/kirbyplants/random,
- /obj/item/twohanded/required/kirbyplants/random,
- /obj/item/twohanded/required/kirbyplants/random)
- crate_name = "potted plants crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/seeds
- name = "Seeds Crate"
- desc = "Big things have small beginnings. Contains thirteen different seeds."
- cost = 1000
- contains = list(/obj/item/seeds/chili,
- /obj/item/seeds/berry,
- /obj/item/seeds/corn,
- /obj/item/seeds/eggplant,
- /obj/item/seeds/tomato,
- /obj/item/seeds/soya,
- /obj/item/seeds/wheat,
- /obj/item/seeds/wheat/rice,
- /obj/item/seeds/carrot,
- /obj/item/seeds/sunflower,
- /obj/item/seeds/chanter,
- /obj/item/seeds/potato,
- /obj/item/seeds/sugarcane)
- crate_name = "seeds crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/vday
- name = "Surplus Valentine Crate"
- desc = "Turns out we got warehouses of this love-y dove-y crap. Were sending out small barged buddle of Valentine gear. This crate has two boxes of chocolate, three poppy flowers, five candy hearts, and three cards."
- cost = 3000
- contraband = TRUE
- contains = list(/obj/item/storage/fancy/heart_box,
- /obj/item/storage/fancy/heart_box,
- /obj/item/reagent_containers/food/snacks/grown/poppy,
- /obj/item/reagent_containers/food/snacks/grown/poppy,
- /obj/item/reagent_containers/food/snacks/grown/poppy,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/valentine,
- /obj/item/valentine,
- /obj/item/valentine)
- crate_name = "valentine crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/organic/exoticseeds
- name = "Exotic Seeds Crate"
- desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!"
- cost = 1500
- contains = list(/obj/item/seeds/nettle,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/plump,
- /obj/item/seeds/liberty,
- /obj/item/seeds/amanita,
- /obj/item/seeds/reishi,
- /obj/item/seeds/banana,
- /obj/item/seeds/eggplant/eggy,
- /obj/item/seeds/random,
- /obj/item/seeds/random)
- crate_name = "exotic seeds crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-//////////////////////////////////////////////////////////////////////////////
-////////////////////////////// Livestock /////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/critter
- group = "Livestock"
- crate_type = /obj/structure/closet/crate/critter
-
-/datum/supply_pack/critter/butterfly
- name = "Butterflies Crate"
- desc = "Not a very dangerous insect, but they do give off a better image than, say, flies or cockroaches."//is that a motherfucking worm reference
- contraband = TRUE
- cost = 5000
- contains = list(/mob/living/simple_animal/butterfly)
- crate_name = "entomology samples crate"
-
-/datum/supply_pack/critter/butterfly/generate()
- . = ..()
- for(var/i in 1 to 49)
- new /mob/living/simple_animal/butterfly(.)
-
-/datum/supply_pack/critter/cat
- name = "Cat Crate"
- desc = "The cat goes meow! Comes with a collar and a nice cat toy! Cheeseburger not included."//i can't believe im making this reference
- cost = 5000 //Cats are worth as much as corgis.
- contains = list(/mob/living/simple_animal/pet/cat,
- /obj/item/clothing/neck/petcollar,
- /obj/item/toy/cattoy)
- crate_name = "cat crate"
-
-/datum/supply_pack/critter/cat/generate()
- . = ..()
- if(prob(50))
- var/mob/living/simple_animal/pet/cat/C = locate() in .
- qdel(C)
- new /mob/living/simple_animal/pet/cat/Proc(.)
-
-/datum/supply_pack/critter/chick
- name = "Chicken Crate"
- desc = "The chicken goes bwaak!"
- cost = 2000
- contains = list( /mob/living/simple_animal/chick)
- crate_name = "chicken crate"
-
-/datum/supply_pack/critter/crab
- name = "Crab Rocket"
- desc = "CRAAAAAAB ROCKET. CRAB ROCKET. CRAB ROCKET. CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB ROCKET. CRAFT. ROCKET. BUY. CRAFT ROCKET. CRAB ROOOCKET. CRAB ROOOOCKET. CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB ROOOOOOOOOOOOOOOOOOOOOOCK EEEEEEEEEEEEEEEEEEEEEEEEE EEEETTTTTTTTTTTTAAAAAAAAA AAAHHHHHHHHHHHHH. CRAB ROCKET. CRAAAB ROCKEEEEEEEEEGGGGHHHHTT CRAB CRAB CRAABROCKET CRAB ROCKEEEET."//fun fact: i actually spent like 10 minutes and transcribed the entire video.
- cost = 5000
- contains = list(/mob/living/simple_animal/crab)
- crate_name = "look sir free crabs"
- DropPodOnly = TRUE
-
-/datum/supply_pack/critter/crab/generate()
- . = ..()
- for(var/i in 1 to 49)
- new /mob/living/simple_animal/crab(.)
-
-/datum/supply_pack/critter/corgi
- name = "Corgi Crate"
- desc = "Considered the optimal dog breed by thousands of research scientists, this Corgi is but one dog from the millions of Ian's noble bloodline. Comes with a cute collar!"
- cost = 5000
- contains = list(/mob/living/simple_animal/pet/dog/corgi,
- /obj/item/clothing/neck/petcollar)
- crate_name = "corgi crate"
-
-/datum/supply_pack/critter/corgi/generate()
- . = ..()
- if(prob(50))
- var/mob/living/simple_animal/pet/dog/corgi/D = locate() in .
- if(D.gender == FEMALE)
- qdel(D)
- new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
-
-/datum/supply_pack/critter/corgis/exotic
- name = "Exotic Corgi Crate"
- desc = "Corgis fit for a king, these corgis come in a unique color to signify their superiority. Comes with a cute collar!"
- cost = 5500
- contains = list(/mob/living/simple_animal/pet/dog/corgi/exoticcorgi,
- /obj/item/clothing/neck/petcollar)
- crate_name = "exotic corgi crate"
-
-/datum/supply_pack/critter/cow
- name = "Cow Crate"
- desc = "The cow goes moo!"
- cost = 3000
- contains = list(/mob/living/simple_animal/cow)
- crate_name = "cow crate"
-
-/datum/supply_pack/critter/fox
- name = "Fox Crate"
- desc = "The fox goes...? Comes with a collar!"//what does the fox say
- cost = 5000
- contains = list(/mob/living/simple_animal/pet/fox,
- /obj/item/clothing/neck/petcollar)
- crate_name = "fox crate"
-
-/datum/supply_pack/critter/goat
- name = "Goat Crate"
- desc = "The goat goes baa! Warranty void if used as a replacement for Pete."
- cost = 2500
- contains = list(/mob/living/simple_animal/hostile/retaliate/goat)
- crate_name = "goat crate"
-
-/datum/supply_pack/critter/goose
- name = "Goose Crate"
- desc = "Angry and violent birds. Evil, evil creatures."
- cost = 2500
- contains = list(/mob/living/simple_animal/hostile/retaliate/goose)
- crate_name = "goose crate"
-
-/datum/supply_pack/critter/monkey
- name = "Monkey Cube Crate"
- desc = "Stop monkeying around! Contains seven monkey cubes. Just add water!"
- cost = 2000
- contains = list (/obj/item/storage/box/monkeycubes)
- crate_name = "monkey cube crate"
-
-/datum/supply_pack/critter/pug
- name = "Pug Crate"
- desc = "Like a normal dog, but... squished. Comes with a nice collar!"
- cost = 5000
- contains = list(/mob/living/simple_animal/pet/dog/pug,
- /obj/item/clothing/neck/petcollar)
- crate_name = "pug crate"
-
-/datum/supply_pack/organic/critter/kiwi
- name = "Space kiwi Crate"
- cost = 2000
- contains = list( /mob/living/simple_animal/kiwi)
- crate_name = "space kiwi crate"
-
-/datum/supply_pack/critter/snake
- name = "Snake Crate"
- desc = "Tired of these MOTHER FUCKING snakes on this MOTHER FUCKING space station? Then this isn't the crate for you. Contains three poisonous snakes."
- cost = 3000
- contains = list(/mob/living/simple_animal/hostile/retaliate/poison/snake,
- /mob/living/simple_animal/hostile/retaliate/poison/snake,
- /mob/living/simple_animal/hostile/retaliate/poison/snake)
- crate_name = "snake crate"
-
-/datum/supply_pack/critter/secbat
- name = "Security Bat Crate"
- desc = "Contains five security bats, perfect to Bat-up any security officer."
- cost = 2500
- contains = list(/mob/living/simple_animal/hostile/retaliate/bat/secbat,
- /mob/living/simple_animal/hostile/retaliate/bat/secbat,
- /mob/living/simple_animal/hostile/retaliate/bat/secbat,
- /mob/living/simple_animal/hostile/retaliate/bat/secbat,
- /mob/living/simple_animal/hostile/retaliate/bat/secbat)
- crate_name = "security bat crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Costumes & Toys /////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/costumes_toys
- group = "Costumes & Toys"
-
-/datum/supply_pack/costumes_toys/randomised
- name = "Collectable Hats Crate"
- desc = "Flaunt your status with three unique, highly-collectable hats!"
- cost = 20000
- var/num_contained = 3 //number of items picked to be contained in a randomised crate
- contains = list(/obj/item/clothing/head/collectable/chef,
- /obj/item/clothing/head/collectable/paper,
- /obj/item/clothing/head/collectable/tophat,
- /obj/item/clothing/head/collectable/captain,
- /obj/item/clothing/head/collectable/beret,
- /obj/item/clothing/head/collectable/welding,
- /obj/item/clothing/head/collectable/flatcap,
- /obj/item/clothing/head/collectable/pirate,
- /obj/item/clothing/head/collectable/kitty,
- /obj/item/clothing/head/collectable/rabbitears,
- /obj/item/clothing/head/collectable/wizard,
- /obj/item/clothing/head/collectable/hardhat,
- /obj/item/clothing/head/collectable/HoS,
- /obj/item/clothing/head/collectable/HoP,
- /obj/item/clothing/head/collectable/thunderdome,
- /obj/item/clothing/head/collectable/swat,
- /obj/item/clothing/head/collectable/slime,
- /obj/item/clothing/head/collectable/police,
- /obj/item/clothing/head/collectable/slime,
- /obj/item/clothing/head/collectable/xenom,
- /obj/item/clothing/head/collectable/petehat)
- crate_name = "collectable hats crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/randomised/contraband
- name = "Contraband Crate"
- desc = "Psst.. bud... want some contraband? I can get you a poster, some nice cigs, dank, even some sponsored items...you know, the good stuff. Just keep it away from the cops, kay?"
- contraband = TRUE
- cost = 3000
- num_contained = 5 //SOME
- contains = list(/obj/item/poster/random_contraband,
- /obj/item/poster/random_contraband,
- /obj/item/reagent_containers/food/snacks/grown/cannabis,
- /obj/item/reagent_containers/food/snacks/grown/cannabis/rainbow,
- /obj/item/reagent_containers/food/snacks/grown/cannabis/white,
- /obj/item/storage/pill_bottle/zoom,
- /obj/item/storage/pill_bottle/happy,
- /obj/item/storage/pill_bottle/lsd,
- /obj/item/storage/pill_bottle/aranesp,
- /obj/item/storage/pill_bottle/stimulant,
- /obj/item/toy/cards/deck/syndicate,
- /obj/item/reagent_containers/food/drinks/bottle/absinthe,
- /obj/item/clothing/under/syndicate/tacticool,
- /obj/item/storage/fancy/cigarettes/cigpack_syndicate,
- /obj/item/storage/fancy/cigarettes/cigpack_shadyjims,
- /obj/item/clothing/mask/gas/syndicate,
- /obj/item/clothing/neck/necklace/dope,
- /obj/item/vending_refill/donksoft,
- /obj/item/circuitboard/computer/arcade/amputation)
- crate_name = "crate"
-
-/datum/supply_pack/costumes_toys/foamforce
- name = "Foam Force Crate"
- desc = "Break out the big guns with eight Foam Force shotguns!"
- cost = 1000
- contains = list(/obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy)
- crate_name = "foam force crate"
-
-/datum/supply_pack/costumes_toys/foamforce/bonus
- name = "Foam Force Pistols Crate"
- desc = "Psst.. hey bud... remember those old foam force pistols that got discontinued for being too cool? Well I got two of those right here with your name on em. I'll even throw in a spare mag for each, waddya say?"
- contraband = TRUE
- cost = 4000
- contains = list(/obj/item/gun/ballistic/automatic/toy/pistol,
- /obj/item/gun/ballistic/automatic/toy/pistol,
- /obj/item/ammo_box/magazine/toy/pistol,
- /obj/item/ammo_box/magazine/toy/pistol)
- crate_name = "foam force crate"
-
-/datum/supply_pack/costumes_toys/formalwear
- name = "Formalwear Crate"
- desc = "You're gonna like the way you look, I guaranteed it. Contains an asston of fancy clothing."
- cost = 3000 //Lots of very expensive items. You gotta pay up to look good!
- contains = list(/obj/item/clothing/under/blacktango,
- /obj/item/clothing/under/assistantformal,
- /obj/item/clothing/under/assistantformal,
- /obj/item/clothing/under/lawyer/bluesuit,
- /obj/item/clothing/suit/toggle/lawyer,
- /obj/item/clothing/under/lawyer/purpsuit,
- /obj/item/clothing/suit/toggle/lawyer/purple,
- /obj/item/clothing/under/lawyer/blacksuit,
- /obj/item/clothing/suit/toggle/lawyer/black,
- /obj/item/clothing/accessory/waistcoat,
- /obj/item/clothing/neck/tie/blue,
- /obj/item/clothing/neck/tie/red,
- /obj/item/clothing/neck/tie/black,
- /obj/item/clothing/head/bowler,
- /obj/item/clothing/head/fedora,
- /obj/item/clothing/head/flatcap,
- /obj/item/clothing/head/beret,
- /obj/item/clothing/head/that,
- /obj/item/clothing/shoes/laceup,
- /obj/item/clothing/shoes/laceup,
- /obj/item/clothing/shoes/laceup,
- /obj/item/clothing/under/suit_jacket/charcoal,
- /obj/item/clothing/under/suit_jacket/navy,
- /obj/item/clothing/under/suit_jacket/burgundy,
- /obj/item/clothing/under/suit_jacket/checkered,
- /obj/item/clothing/under/suit_jacket/tan,
- /obj/item/lipstick/random)
- crate_name = "formalwear crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/clownpin
- name = "Hilarious Firing Pin Crate"
- desc = "I uh... I'm not really sure what this does. Wanna buy it?"
- cost = 5000
- contraband = TRUE
- contains = list(/obj/item/firing_pin/clown)
- crate_name = "toy crate" // It's /technically/ a toy. For the clown, at least.
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/lasertag
- name = "Laser Tag Crate"
- desc = "Foam Force is for boys. Laser Tag is for men. Contains three sets of red suits, blue suits, matching helmets, and matching laser tag guns."
- cost = 1500
- contains = list(/obj/item/gun/energy/laser/redtag,
- /obj/item/gun/energy/laser/redtag,
- /obj/item/gun/energy/laser/redtag,
- /obj/item/gun/energy/laser/bluetag,
- /obj/item/gun/energy/laser/bluetag,
- /obj/item/gun/energy/laser/bluetag,
- /obj/item/clothing/suit/redtag,
- /obj/item/clothing/suit/redtag,
- /obj/item/clothing/suit/redtag,
- /obj/item/clothing/suit/bluetag,
- /obj/item/clothing/suit/bluetag,
- /obj/item/clothing/suit/bluetag,
- /obj/item/clothing/head/helmet/redtaghelm,
- /obj/item/clothing/head/helmet/redtaghelm,
- /obj/item/clothing/head/helmet/redtaghelm,
- /obj/item/clothing/head/helmet/bluetaghelm,
- /obj/item/clothing/head/helmet/bluetaghelm,
- /obj/item/clothing/head/helmet/bluetaghelm)
- crate_name = "laser tag crate"
-
-/datum/supply_pack/costumes_toys/lasertag/pins
- name = "Laser Tag Firing Pins Crate"
- desc = "Three laser tag firing pins used in laser-tag units to ensure users are wearing their vests."
- cost = 3000
- contraband = TRUE
- contains = list(/obj/item/storage/box/lasertagpins)
- crate_name = "laser tag crate"
-
-/datum/supply_pack/costumes_toys/costume_original
- name = "Original Costume Crate"
- desc = "Reenact Shakespearean plays with this assortment of outfits. Contains eight different costumes!"
- cost = 1000
- contains = list(/obj/item/clothing/head/snowman,
- /obj/item/clothing/suit/snowman,
- /obj/item/clothing/head/chicken,
- /obj/item/clothing/suit/chickensuit,
- /obj/item/clothing/mask/gas/monkeymask,
- /obj/item/clothing/suit/monkeysuit,
- /obj/item/clothing/head/cardborg,
- /obj/item/clothing/suit/cardborg,
- /obj/item/clothing/head/xenos,
- /obj/item/clothing/suit/xenos,
- /obj/item/clothing/suit/hooded/ian_costume,
- /obj/item/clothing/suit/hooded/carp_costume,
- /obj/item/clothing/suit/hooded/bee_costume)
- crate_name = "original costume crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/costume
- name = "Standard Costume Crate"
- desc = "Supply the station's entertainers with the equipment of their trade with these Nanotrasen-approved costumes! Contains a full clown and mime outfit, along with a bike horn and a bottle of nothing."
- cost = 1000
- access = ACCESS_THEATRE
- contains = list(/obj/item/storage/backpack/clown,
- /obj/item/clothing/shoes/clown_shoes,
- /obj/item/clothing/mask/gas/clown_hat,
- /obj/item/clothing/under/rank/clown,
- /obj/item/bikehorn,
- /obj/item/clothing/under/rank/mime,
- /obj/item/clothing/shoes/sneakers/black,
- /obj/item/clothing/gloves/color/white,
- /obj/item/clothing/mask/gas/mime,
- /obj/item/clothing/head/beret,
- /obj/item/clothing/suit/suspenders,
- /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing,
- /obj/item/storage/backpack/mime)
- crate_name = "standard costume crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/randomised/toys
- name = "Toy Crate"
- desc = "Who cares about pride and accomplishment? Skip the gaming and get straight to the sweet rewards with this product! Contains five random toys. Warranty void if used to prank research directors."
- cost = 1500 // or play the arcade machines ya lazy bum
- num_contained = 5
- contains = list(/obj/item/storage/box/snappops,
- /obj/item/toy/talking/AI,
- /obj/item/toy/talking/codex_gigas,
- /obj/item/clothing/under/syndicate/tacticool,
- /obj/item/toy/sword ,
- /obj/item/toy/gun,
- /obj/item/gun/ballistic/shotgun/toy/crossbow,
- /obj/item/storage/box/fakesyndiesuit,
- /obj/item/storage/crayons,
- /obj/item/toy/spinningtoy,
- /obj/item/toy/prize/ripley,
- /obj/item/toy/prize/fireripley,
- /obj/item/toy/prize/deathripley,
- /obj/item/toy/prize/gygax,
- /obj/item/toy/prize/durand,
- /obj/item/toy/prize/honk,
- /obj/item/toy/prize/marauder,
- /obj/item/toy/prize/seraph,
- /obj/item/toy/prize/mauler,
- /obj/item/toy/prize/odysseus,
- /obj/item/toy/prize/phazon,
- /obj/item/toy/prize/reticence,
- /obj/item/toy/cards/deck,
- /obj/item/toy/nuke,
- /obj/item/toy/minimeteor,
- /obj/item/toy/redbutton,
- /obj/item/toy/talking/owl,
- /obj/item/toy/talking/griffin,
- /obj/item/coin/antagtoken,
- /obj/item/stack/tile/fakespace/loaded,
- /obj/item/stack/tile/fakepit/loaded,
- /obj/item/toy/toy_xeno,
- /obj/item/storage/box/actionfigure,
- /obj/item/restraints/handcuffs/fake,
- /obj/item/grenade/chem_grenade/glitter/pink,
- /obj/item/grenade/chem_grenade/glitter/blue,
- /obj/item/grenade/chem_grenade/glitter/white,
- /obj/item/toy/eightball,
- /obj/item/toy/windupToolbox,
- /obj/item/toy/clockwork_watch,
- /obj/item/toy/toy_dagger,
- /obj/item/extendohand/acme,
- /obj/item/hot_potato/harmless/toy,
- /obj/item/card/emagfake,
- /obj/item/clothing/shoes/wheelys,
- /obj/item/clothing/shoes/kindleKicks,
- /obj/item/storage/belt/military/snack,
- /obj/item/toy/eightball,
- /obj/item/vending_refill/donksoft)
- crate_name = "toy crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/randomised/plush
- name = "Plush Crate"
- desc = "Plush tide station wide. Contains 5 random plushies for you to love. Warranty void if your love violates the terms of use."
- cost = 1500 // or play the arcade machines ya lazy bum
- num_contained = 5
- contains = list(/obj/item/toy/plush/random,
- /obj/item/toy/plush/random,
- /obj/item/toy/plush/random,
- /obj/item/toy/plush/random,
- /obj/item/toy/plush/random) //I'm lazy
- crate_name = "plushie crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/wizard
- name = "Wizard Costume Crate"
- desc = "Pretend to join the Wizard Federation with this full wizard outfit! Nanotrasen would like to remind its employees that actually joining the Wizard Federation is subject to termination of job and life."
- cost = 2000
- contains = list(/obj/item/staff,
- /obj/item/clothing/suit/wizrobe/fake,
- /obj/item/clothing/shoes/sandal,
- /obj/item/clothing/head/wizard/fake)
- crate_name = "wizard costume crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/randomised/fill(obj/structure/closet/crate/C)
- var/list/L = contains.Copy()
- for(var/i in 1 to num_contained)
- var/item = pick_n_take(L)
- new item(C)
-
-/datum/supply_pack/costumes_toys/wardrobes/autodrobe
- name = "Autodrobe Supply Crate"
- desc = "Autodrobe missing your favorite dress? Solve that issue today with this autodrobe refill."
- cost = 1500
- contains = list(/obj/item/vending_refill/autodrobe)
- crate_name = "autodrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/cargo
- name = "Cargo Wardrobe Supply Crate"
- desc = "This crate contains a refill for the CargoDrobe."
- cost = 750
- contains = list(/obj/item/vending_refill/wardrobe/cargo_wardrobe)
- crate_name = "cargo department supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/engineering
- name = "Engineering Wardrobe Supply Crate"
- desc = "This crate contains refills for the EngiDrobe and AtmosDrobe."
- cost = 1500
- contains = list(/obj/item/vending_refill/wardrobe/engi_wardrobe,
- /obj/item/vending_refill/wardrobe/atmos_wardrobe)
- crate_name = "engineering department wardrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/general
- name = "General Wardrobes Supply Crate"
- desc = "This crate contains refills for the CuraDrobe, BarDrobe, ChefDrobe, JaniDrobe, ChapDrobe."
- cost = 3750
- contains = list(/obj/item/vending_refill/wardrobe/curator_wardrobe,
- /obj/item/vending_refill/wardrobe/bar_wardrobe,
- /obj/item/vending_refill/wardrobe/chef_wardrobe,
- /obj/item/vending_refill/wardrobe/jani_wardrobe,
- /obj/item/vending_refill/wardrobe/chap_wardrobe)
- crate_name = "general wardrobes vendor refills"
-
-/datum/supply_pack/costumes_toys/wardrobes/hydroponics
- name = "Hydrobe Supply Crate"
- desc = "This crate contains a refill for the Hydrobe."
- cost = 750
- contains = list(/obj/item/vending_refill/wardrobe/hydro_wardrobe)
- crate_name = "hydrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/medical
- name = "Medical Wardrobe Supply Crate"
- desc = "This crate contains refills for the MediDrobe, ChemDrobe, GeneDrobe, and ViroDrobe."
- cost = 3000
- contains = list(/obj/item/vending_refill/wardrobe/medi_wardrobe,
- /obj/item/vending_refill/wardrobe/chem_wardrobe,
- /obj/item/vending_refill/wardrobe/gene_wardrobe,
- /obj/item/vending_refill/wardrobe/viro_wardrobe)
- crate_name = "medical department wardrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/science
- name = "Science Wardrobe Supply Crate"
- desc = "This crate contains refills for the SciDrobe and RoboDrobe."
- cost = 1500
- contains = list(/obj/item/vending_refill/wardrobe/robo_wardrobe,
- /obj/item/vending_refill/wardrobe/science_wardrobe)
- crate_name = "science department wardrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/security
- name = "Security Wardrobe Supply Crate"
- desc = "This crate contains refills for the SecDrobe and LawDrobe."
- cost = 1500
- contains = list(/obj/item/vending_refill/wardrobe/sec_wardrobe,
- /obj/item/vending_refill/wardrobe/law_wardrobe)
- crate_name = "security department supply crate"
-
-/datum/supply_pack/costumes_toys/kinkmate
- name = "Kinkmate construction kit"
- cost = 2000
- contraband = TRUE
- contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate)
- crate_name = "Kinkmate construction kit"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Miscellaneous ///////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/misc
- group = "Miscellaneous Supplies"
-
-/datum/supply_pack/misc/artsupply
- name = "Art Supplies"
- desc = "Make some happy little accidents with six canvasses, two easels, two boxes of crayons, and a rainbow crayon!"
- cost = 800
- contains = list(/obj/structure/easel,
- /obj/structure/easel,
- /obj/item/canvas/nineteenXnineteen,
- /obj/item/canvas/nineteenXnineteen,
- /obj/item/canvas/twentythreeXnineteen,
- /obj/item/canvas/twentythreeXnineteen,
- /obj/item/canvas/twentythreeXtwentythree,
- /obj/item/canvas/twentythreeXtwentythree,
- /obj/item/storage/crayons,
- /obj/item/storage/crayons,
- /obj/item/toy/crayon/rainbow,
- /obj/item/toy/crayon/white,
- /obj/item/toy/crayon/white)
- crate_name = "art supply crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/misc/captain_pen
- name = "Captain Pen"
- desc = "A spare Captain fountain pen."
- access = ACCESS_CAPTAIN
- cost = 10000
- contains = list(/obj/item/pen/fountain/captain)
- crate_name = "captain pen"
- crate_type = /obj/structure/closet/crate/secure/weapon //It is a combat pen
-
-/datum/supply_pack/misc/bicycle
- name = "Bicycle"
- desc = "Nanotrasen reminds all employees to never toy with powers outside their control."
- cost = 1000000
- contains = list(/obj/vehicle/ridden/bicycle)
- crate_name = "Bicycle Crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/misc/bigband
- name = "Big Band Instrument Collection"
- desc = "Get your sad station movin' and groovin' with this fine collection! Contains nine different instruments!"
- cost = 5000
- crate_name = "Big band musical instruments collection"
- contains = list(/obj/item/instrument/violin,
- /obj/item/instrument/guitar,
- /obj/item/instrument/glockenspiel,
- /obj/item/instrument/accordion,
- /obj/item/instrument/saxophone,
- /obj/item/instrument/trombone,
- /obj/item/instrument/recorder,
- /obj/item/instrument/harmonica,
- /obj/structure/piano/unanchored)
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/misc/book_crate
- name = "Book Crate"
- desc = "Surplus from the Nanotrasen Archives, these five books are sure to be good reads."
- cost = 1500
- contains = list(/obj/item/book/codex_gigas,
- /obj/item/book/manual/random/,
- /obj/item/book/manual/random/,
- /obj/item/book/manual/random/,
- /obj/item/book/random/triple)
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/misc/paper
- name = "Bureaucracy Crate"
- desc = "High stacks of papers on your desk Are a big problem - make it Pea-sized with these bureaucratic supplies! Contains five pens, some camera film, hand labeler supplies, a paper bin, three folders, two clipboards and two stamps as well as a briefcase."//that was too forced
- cost = 1500
- contains = list(/obj/structure/filingcabinet/chestdrawer/wheeled,
- /obj/item/camera_film,
- /obj/item/hand_labeler,
- /obj/item/hand_labeler_refill,
- /obj/item/hand_labeler_refill,
- /obj/item/paper_bin,
- /obj/item/pen/fourcolor,
- /obj/item/pen/fourcolor,
- /obj/item/pen,
- /obj/item/pen/blue,
- /obj/item/pen/red,
- /obj/item/folder/blue,
- /obj/item/folder/red,
- /obj/item/folder/yellow,
- /obj/item/clipboard,
- /obj/item/clipboard,
- /obj/item/stamp,
- /obj/item/stamp/denied,
- /obj/item/storage/briefcase)
- crate_name = "bureaucracy crate"
-
-/datum/supply_pack/misc/fountainpens
- name = "Calligraphy Crate"
- desc = "Sign death warrants in style with these seven executive fountain pens."
- cost = 700
- contains = list(/obj/item/storage/box/fountainpens,
- /obj/item/paper_bin)
- crate_type = /obj/structure/closet/crate/wooden
- crate_name = "calligraphy crate"
-
-/datum/supply_pack/misc/wrapping_paper
- name = "Festive Wrapping Paper Crate"
- desc = "Want to mail your loved ones gift-wrapped chocolates, stuffed animals, the Clown's severed head? You can do all that, with this crate full of wrapping paper."
- cost = 1000
- contains = list(/obj/item/stack/wrapping_paper)
- crate_type = /obj/structure/closet/crate/wooden
- crate_name = "festive wrapping paper crate"
-
-/datum/supply_pack/misc/paper_work
- name = "Freelance Paper work"
- desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (10) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up.
- cost = 700 // Net of 0 credits
- contains = list(/obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/pen/fountain,
- /obj/item/pen/fountain,
- /obj/item/pen/fountain,
- /obj/item/pen/fountain,
- /obj/item/pen/fountain)
- crate_name = "Paperwork"
-
-/datum/supply_pack/misc/funeral
- name = "Funeral Supply crate"
- desc = "At the end of the day, someone's gonna want someone dead. Give them a proper send-off with these funeral supplies! Contains a coffin with burial garmets and flowers."
- cost = 600
- contains = list(/obj/item/clothing/under/burial,
- /obj/item/reagent_containers/food/snacks/grown/harebell,
- /obj/item/reagent_containers/food/snacks/grown/poppy/geranium
- )
- crate_name = "coffin"
- crate_type = /obj/structure/closet/crate/coffin
-
-/datum/supply_pack/misc/jukebox
- name = "Jukebox"
- cost = 35000
- contains = list(/obj/machinery/jukebox)
- crate_name = "Jukebox"
-
-/datum/supply_pack/misc/lewd
- name = "Lewd Crate" // OwO
- desc = "Psss want to have a good time with your sluts? Well I got what you want maid clothing, dildos, collars and more!"
- cost = 5000
- contraband = TRUE
- contains = list(/obj/item/dildo/custom,
- /obj/item/dildo/custom,
- /obj/item/vending_refill/kink,
- /obj/item/vending_refill/kink,
- /obj/item/clothing/under/maid,
- /obj/item/clothing/under/maid,
- /obj/item/electropack/shockcollar,
- /obj/item/electropack/shockcollar,
- /obj/item/restraints/handcuffs/fake/kinky,
- /obj/item/restraints/handcuffs/fake/kinky,
- /obj/item/clothing/head/kitty/genuine, // Why its illegal
- /obj/item/clothing/head/kitty/genuine,
- /obj/item/storage/pill_bottle/penis_enlargement,
- /obj/structure/reagent_dispensers/keg/aphro)
- crate_name = "lewd kit"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/misc/lewdkeg
- name = "Lewd Deluxe Keg"
- desc = "That other stuff not getting you ready? Well I have a Chemslut making tons of the good stuff."
- cost = 7000 //It can be a weapon
- contraband = TRUE
- contains = list(/obj/structure/reagent_dispensers/keg/aphro/strong)
- crate_name = "deluxe keg"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/misc/religious_supplies
- name = "Religious Supplies Crate"
- desc = "Keep your local chaplain happy and well-supplied, lest they call down judgement upon your cargo bay. Contains two bottles of holywater, bibles, chaplain robes, and burial garmets."
- cost = 4000 // it costs so much because the Space Church is ran by Space Jews
- contains = list(/obj/item/reagent_containers/food/drinks/bottle/holywater,
- /obj/item/reagent_containers/food/drinks/bottle/holywater,
- /obj/item/storage/book/bible/booze,
- /obj/item/storage/book/bible/booze,
- /obj/item/clothing/suit/hooded/chaplain_hoodie,
- /obj/item/clothing/suit/hooded/chaplain_hoodie
- )
- crate_name = "religious supplies crate"
-
-/datum/supply_pack/misc/randomised/promiscuous
- name = "Promiscuous Organs"
- desc = "Do YOU want to have more genital? Well we have just the thing for you~. This crate has two autosurgeon, that will let you have a new sex, organ to impress that hot stud and or chick."
- cost = 4000 //Only get 2!
- contraband = TRUE
- var/num_contained = 2
- contains = list(/obj/item/autosurgeon/penis,
- /obj/item/autosurgeon/testicles,
- /obj/item/autosurgeon/vagina,
- /obj/item/autosurgeon/breasts,
- /obj/item/autosurgeon/womb)
- crate_name = "promiscuous organs"
-
-/datum/supply_pack/misc/toner
- name = "Toner Crate"
- desc = "Spent too much ink printing butt pictures? Fret not, with these six toner refills, you'll be printing butts 'till the cows come home!'"
- cost = 1000
- contains = list(/obj/item/toner,
- /obj/item/toner,
- /obj/item/toner,
- /obj/item/toner,
- /obj/item/toner,
- /obj/item/toner)
- crate_name = "toner crate"
diff --git a/code/modules/cargo/packs/armory.dm b/code/modules/cargo/packs/armory.dm
new file mode 100644
index 0000000000..11aae8a054
--- /dev/null
+++ b/code/modules/cargo/packs/armory.dm
@@ -0,0 +1,244 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Armory //////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/security/armory
+ group = "Armory"
+ access = ACCESS_ARMORY
+ crate_type = /obj/structure/closet/crate/secure/weapon
+
+/datum/supply_pack/security/armory/bulletarmor
+ name = "Bulletproof Armor Crate"
+ desc = "Contains three sets of bulletproof armor. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
+ cost = 1250
+ contains = list(/obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/suit/armor/bulletproof)
+ crate_name = "bulletproof armor crate"
+
+/datum/supply_pack/security/armory/bullethelmets
+ name = "Bulletproof Helmet Crate"
+ desc = "Contains three sets of bulletproof helmets. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
+ cost = 1250
+ contains = list(/obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/head/helmet/alt)
+ crate_name = "bulletproof helmet crate"
+
+/datum/supply_pack/security/armory/chemimp
+ name = "Chemical Implants Crate"
+ desc = "Contains five Remote Chemical implants. Requires Armory access to open."
+ cost = 1700
+ contains = list(/obj/item/storage/box/chemimp)
+ crate_name = "chemical implant crate"
+
+/datum/supply_pack/security/armory/combatknives
+ name = "Combat Knives Crate"
+ desc = "Contains three sharpened combat knives. Each knife guaranteed to fit snugly inside any Nanotrasen-standard boot. Requires Armory access to open."
+ cost = 3200
+ contains = list(/obj/item/kitchen/knife/combat,
+ /obj/item/kitchen/knife/combat,
+ /obj/item/kitchen/knife/combat)
+ crate_name = "combat knife crate"
+
+/datum/supply_pack/security/armory/ballistic
+ name = "Combat Shotguns Crate"
+ desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, with three Shotgun Bandoliers, as well as seven buchshot and 12g shotgun slugs. Requires Armory access to open."
+ cost = 8000
+ contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat,
+ /obj/item/gun/ballistic/shotgun/automatic/combat,
+ /obj/item/gun/ballistic/shotgun/automatic/combat,
+ /obj/item/storage/belt/bandolier,
+ /obj/item/storage/belt/bandolier,
+ /obj/item/storage/belt/bandolier,
+ /obj/item/storage/box/lethalshot,
+ /obj/item/storage/box/lethalslugs)
+ crate_name = "combat shotguns crate"
+
+/datum/supply_pack/security/armory/dragnetgun
+ name = "DRAGnet gun Crate"
+ desc = "Contains two DRAGnet gun. A Dynamic Rapid-Apprehension of the Guilty net the revolution in law enforcement technology that YOU Want! Requires Armory access to open."
+ cost = 3250
+ contains = list(/obj/item/gun/energy/e_gun/dragnet,
+ /obj/item/gun/energy/e_gun/dragnet)
+ crate_name = "anti riot net guns crate"
+
+/datum/supply_pack/security/armory/energy
+ name = "Energy Guns Crate"
+ desc = "Contains three Energy Guns, capable of firing both nonlethal and lethal blasts of light. Requires Armory access to open."
+ cost = 3250
+ contains = list(/obj/item/gun/energy/e_gun,
+ /obj/item/gun/energy/e_gun,
+ /obj/item/gun/energy/e_gun)
+ crate_name = "energy gun crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+
+/datum/supply_pack/security/armory/exileimp // Theres boxes in 2 lockers as well as gateway never realy being used sad
+ name = "Exile Implants Crate"
+ desc = "Contains five Exile implants. Requires Armory access to open."
+ cost = 1050 //stops endless points
+ contains = list(/obj/item/storage/box/exileimp)
+ crate_name = "exile implant crate"
+
+/datum/supply_pack/security/armory/mindshield
+ name = "Mindshield Implants Crate"
+ desc = "Prevent against radical thoughts with three Mindshield implants. Requires Armory access to open."
+ cost = 3000 //Lowered untill cargo rework MK II is done
+ contains = list(/obj/item/storage/lockbox/loyalty)
+ crate_name = "mindshield implant crate"
+
+/datum/supply_pack/security/armory/trackingimp
+ name = "Tracking Implants Crate"
+ desc = "Contains four tracking implants. Requires Armory access to open."
+ cost = 1050
+ contains = list(/obj/item/storage/box/trackimp)
+ crate_name = "tracking implant crate"
+
+/datum/supply_pack/security/armory/fire
+ name = "Incendiary Weapons Crate"
+ desc = "Burn, baby burn. Contains three incendiary grenades, seven incendiary slugs, three plasma canisters, and a flamethrower. Requires Brige access to open."
+ cost = 1750
+ access = ACCESS_HEADS
+ contains = list(/obj/item/flamethrower/full,
+ /obj/item/tank/internals/plasma,
+ /obj/item/tank/internals/plasma,
+ /obj/item/tank/internals/plasma,
+ /obj/item/grenade/chem_grenade/incendiary,
+ /obj/item/grenade/chem_grenade/incendiary,
+ /obj/item/grenade/chem_grenade/incendiary,
+ /obj/item/storage/box/fireshot)
+ crate_name = "incendiary weapons crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+ dangerous = TRUE
+
+/datum/supply_pack/security/armory/miniguns
+ name = "Personal Miniature Energy Guns"
+ desc = "Contains three miniature energy guns. Each gun has a disabler and a lethal option. Requires Armory access to open."
+ cost = 3000
+ contains = list(/obj/item/gun/energy/e_gun/mini,
+ /obj/item/gun/energy/e_gun/mini,
+ /obj/item/gun/energy/e_gun/mini)
+ crate_name = "personal energy guns crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+
+/datum/supply_pack/security/armory/laserarmor
+ name = "Reflector Vest Crate"
+ desc = "Contains two vests of highly reflective material. Each armor piece diffuses a laser's energy by over half, as well as offering a good chance to reflect the laser entirely. Requires Armory access to open."
+ cost = 2000
+ contains = list(/obj/item/clothing/suit/armor/laserproof,
+ /obj/item/clothing/suit/armor/laserproof)
+ crate_name = "reflector vest crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+
+/datum/supply_pack/security/armory/riotarmor
+ name = "Riot Armor Crate"
+ desc = "Contains three sets of heavy body armor. Advanced padding protects against close-ranged weaponry, making melee attacks feel only half as potent to the user. Requires Armory access to open."
+ cost = 1750
+ contains = list(/obj/item/clothing/suit/armor/riot,
+ /obj/item/clothing/suit/armor/riot,
+ /obj/item/clothing/suit/armor/riot)
+ crate_name = "riot armor crate"
+
+/datum/supply_pack/security/armory/riothelmets
+ name = "Riot Helmets Crate"
+ desc = "Contains three riot helmets. Requires Armory access to open."
+ cost = 1750
+ contains = list(/obj/item/clothing/head/helmet/riot,
+ /obj/item/clothing/head/helmet/riot,
+ /obj/item/clothing/head/helmet/riot)
+ crate_name = "riot helmets crate"
+
+/datum/supply_pack/security/armory/riotshields
+ name = "Riot Shields Crate"
+ desc = "For when the greytide gets really uppity. Contains three riot shields. Requires Armory access to open."
+ cost = 2200
+ contains = list(/obj/item/shield/riot,
+ /obj/item/shield/riot,
+ /obj/item/shield/riot)
+ crate_name = "riot shields crate"
+
+/datum/supply_pack/security/armory/riotshotguns
+ name = "Riot Shotgun Crate"
+ desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open."
+ cost = 6500
+ contains = list(/obj/item/gun/ballistic/shotgun/riot,
+ /obj/item/gun/ballistic/shotgun/riot,
+ /obj/item/gun/ballistic/shotgun/riot,
+ /obj/item/storage/box/rubbershot,
+ /obj/item/storage/box/beanbag)
+ crate_name = "riot shotgun crate"
+
+/datum/supply_pack/security/armory/swat
+ name = "SWAT Crate"
+ desc = "Contains two fullbody sets of tough, fireproof, pressurized suits designed in a joint effort by IS-ERI and Nanotrasen. Each set contains a suit, helmet, mask, combat belt, and combat gloves. Requires Armory access to open."
+ cost = 6000
+ contains = list(/obj/item/clothing/head/helmet/swat/nanotrasen,
+ /obj/item/clothing/head/helmet/swat/nanotrasen,
+ /obj/item/clothing/suit/space/swat,
+ /obj/item/clothing/suit/space/swat,
+ /obj/item/clothing/mask/gas/sechailer/swat,
+ /obj/item/clothing/mask/gas/sechailer/swat,
+ /obj/item/storage/belt/military/assault,
+ /obj/item/storage/belt/military/assault,
+ /obj/item/clothing/gloves/combat,
+ /obj/item/clothing/gloves/combat)
+ crate_name = "swat crate"
+
+/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
+ name = "SWAT tatical tasers Crate"
+ desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
+ cost = 7000
+ contains = list(/obj/item/gun/energy/e_gun/stun,
+ /obj/item/gun/energy/e_gun/stun)
+ crate_name = "swat taser crate"
+
+/datum/supply_pack/security/armory/woodstock
+ name = "Classic WoodStock Shotguns Crate"
+ desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open."
+ cost = 3000
+ contains = list(/obj/item/gun/ballistic/shotgun,
+ /obj/item/gun/ballistic/shotgun,
+ /obj/item/gun/ballistic/shotgun)
+ crate_name = "woodstock shotguns crate"
+
+/datum/supply_pack/security/armory/wt550
+ name = "WT-550 Semi-Auto Rifle Crate"
+ desc = "Contains two high-powered, semiautomatic rifles chambered in 4.6x30mm. Requires Armory access to open."
+ cost = 2550
+ contains = list(/obj/item/gun/ballistic/automatic/wt550,
+ /obj/item/gun/ballistic/automatic/wt550)
+ crate_name = "auto rifle crate"
+
+/datum/supply_pack/security/armory/wt550ammo
+ name = "WT-550 Semi-Auto SMG Ammo Crate"
+ desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
+ cost = 1750
+ contains = list(/obj/item/ammo_box/magazine/wt550m9,
+ /obj/item/ammo_box/magazine/wt550m9,
+ /obj/item/ammo_box/magazine/wt550m9,
+ /obj/item/ammo_box/magazine/wt550m9)
+ crate_name = "auto rifle ammo crate"
+
+/datum/supply_pack/security/armory/wt550ammo_nonlethal // Takes around 12 shots to stun crit someone
+ name = "WT-550 Semi-Auto SMG Non-Lethal Ammo Crate"
+ desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
+ cost = 1000
+ contains = list(/obj/item/ammo_box/magazine/wt550m9/wtrubber,
+ /obj/item/ammo_box/magazine/wt550m9/wtrubber,
+ /obj/item/ammo_box/magazine/wt550m9/wtrubber,
+ /obj/item/ammo_box/magazine/wt550m9/wtrubber)
+ crate_name = "auto rifle ammo crate"
+
+/datum/supply_pack/security/armory/wt550ammo_special
+ name = "WT-550 Semi-Auto SMG Special Ammo Crate"
+ desc = "Contains 2 20-round Armour Piercing and Incendiary magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
+ cost = 3000
+ contains = list(/obj/item/ammo_box/magazine/wt550m9/wtap,
+ /obj/item/ammo_box/magazine/wt550m9/wtap,
+ /obj/item/ammo_box/magazine/wt550m9/wtic,
+ /obj/item/ammo_box/magazine/wt550m9/wtic)
+ crate_name = "auto rifle ammo crate"
diff --git a/code/modules/cargo/packs/costumes_toys.dm b/code/modules/cargo/packs/costumes_toys.dm
new file mode 100644
index 0000000000..40d21e4505
--- /dev/null
+++ b/code/modules/cargo/packs/costumes_toys.dm
@@ -0,0 +1,369 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Costumes & Toys /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/costumes_toys
+ group = "Costumes & Toys"
+
+/datum/supply_pack/costumes_toys/randomised
+ name = "Collectable Hats Crate"
+ desc = "Flaunt your status with three unique, highly-collectable hats!"
+ cost = 20000
+ var/num_contained = 3 //number of items picked to be contained in a randomised crate
+ contains = list(/obj/item/clothing/head/collectable/chef,
+ /obj/item/clothing/head/collectable/paper,
+ /obj/item/clothing/head/collectable/tophat,
+ /obj/item/clothing/head/collectable/captain,
+ /obj/item/clothing/head/collectable/beret,
+ /obj/item/clothing/head/collectable/welding,
+ /obj/item/clothing/head/collectable/flatcap,
+ /obj/item/clothing/head/collectable/pirate,
+ /obj/item/clothing/head/collectable/kitty,
+ /obj/item/clothing/head/collectable/rabbitears,
+ /obj/item/clothing/head/collectable/wizard,
+ /obj/item/clothing/head/collectable/hardhat,
+ /obj/item/clothing/head/collectable/HoS,
+ /obj/item/clothing/head/collectable/HoP,
+ /obj/item/clothing/head/collectable/thunderdome,
+ /obj/item/clothing/head/collectable/swat,
+ /obj/item/clothing/head/collectable/slime,
+ /obj/item/clothing/head/collectable/police,
+ /obj/item/clothing/head/collectable/slime,
+ /obj/item/clothing/head/collectable/xenom,
+ /obj/item/clothing/head/collectable/petehat)
+ crate_name = "collectable hats crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/randomised/contraband
+ name = "Contraband Crate"
+ desc = "Psst.. bud... want some contraband? I can get you a poster, some nice cigs, dank, even some sponsored items...you know, the good stuff. Just keep it away from the cops, kay?"
+ contraband = TRUE
+ cost = 3000
+ num_contained = 5 //SOME
+ contains = list(/obj/item/poster/random_contraband,
+ /obj/item/poster/random_contraband,
+ /obj/item/reagent_containers/food/snacks/grown/cannabis,
+ /obj/item/reagent_containers/food/snacks/grown/cannabis/rainbow,
+ /obj/item/reagent_containers/food/snacks/grown/cannabis/white,
+ /obj/item/storage/pill_bottle/zoom,
+ /obj/item/storage/pill_bottle/happy,
+ /obj/item/storage/pill_bottle/lsd,
+ /obj/item/storage/pill_bottle/aranesp,
+ /obj/item/storage/pill_bottle/stimulant,
+ /obj/item/toy/cards/deck/syndicate,
+ /obj/item/reagent_containers/food/drinks/bottle/absinthe,
+ /obj/item/clothing/under/syndicate/tacticool,
+ /obj/item/clothing/under/syndicate,
+ /obj/item/suppressor,
+ /obj/item/storage/fancy/cigarettes/cigpack_syndicate,
+ /obj/item/storage/fancy/cigarettes/cigpack_shadyjims,
+ /obj/item/clothing/mask/gas/syndicate,
+ /obj/item/clothing/neck/necklace/dope,
+ /obj/item/vending_refill/donksoft,
+ /obj/item/circuitboard/computer/arcade/amputation)
+ crate_name = "crate"
+
+/datum/supply_pack/costumes_toys/foamforce
+ name = "Foam Force Crate"
+ desc = "Break out the big guns with eight Foam Force shotguns!"
+ cost = 1000
+ contains = list(/obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy)
+ crate_name = "foam force crate"
+
+/datum/supply_pack/costumes_toys/foamforce/bonus
+ name = "Foam Force Pistols Crate"
+ desc = "Psst.. hey bud... remember those old foam force pistols that got discontinued for being too cool? Well I got two of those right here with your name on em. I'll even throw in a spare mag for each, waddya say?"
+ contraband = TRUE
+ cost = 4000
+ contains = list(/obj/item/gun/ballistic/automatic/toy/pistol,
+ /obj/item/gun/ballistic/automatic/toy/pistol,
+ /obj/item/ammo_box/magazine/toy/pistol,
+ /obj/item/ammo_box/magazine/toy/pistol)
+ crate_name = "foam force crate"
+
+/datum/supply_pack/costumes_toys/formalwear
+ name = "Formalwear Crate"
+ desc = "You're gonna like the way you look, I guaranteed it. Contains an asston of fancy clothing."
+ cost = 4750 //Lots of fancy clothing that can be sold back!
+ contains = list(/obj/item/clothing/under/blacktango,
+ /obj/item/clothing/under/assistantformal,
+ /obj/item/clothing/under/assistantformal,
+ /obj/item/clothing/under/lawyer/bluesuit,
+ /obj/item/clothing/suit/toggle/lawyer,
+ /obj/item/clothing/under/lawyer/purpsuit,
+ /obj/item/clothing/suit/toggle/lawyer/purple,
+ /obj/item/clothing/under/lawyer/blacksuit,
+ /obj/item/clothing/suit/toggle/lawyer/black,
+ /obj/item/clothing/accessory/waistcoat,
+ /obj/item/clothing/neck/tie/blue,
+ /obj/item/clothing/neck/tie/red,
+ /obj/item/clothing/neck/tie/black,
+ /obj/item/clothing/head/bowler,
+ /obj/item/clothing/head/fedora,
+ /obj/item/clothing/head/flatcap,
+ /obj/item/clothing/head/beret,
+ /obj/item/clothing/head/that,
+ /obj/item/clothing/shoes/laceup,
+ /obj/item/clothing/shoes/laceup,
+ /obj/item/clothing/shoes/laceup,
+ /obj/item/clothing/under/suit_jacket/charcoal,
+ /obj/item/clothing/under/suit_jacket/navy,
+ /obj/item/clothing/under/suit_jacket/burgundy,
+ /obj/item/clothing/under/suit_jacket/checkered,
+ /obj/item/clothing/under/suit_jacket/tan,
+ /obj/item/lipstick/random)
+ crate_name = "formalwear crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/clownpin
+ name = "Hilarious Firing Pin Crate"
+ desc = "I uh... I'm not really sure what this does. Wanna buy it?"
+ cost = 5000
+ contraband = TRUE
+ contains = list(/obj/item/firing_pin/clown)
+ crate_name = "toy crate" // It's /technically/ a toy. For the clown, at least.
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/lasertag
+ name = "Laser Tag Crate"
+ desc = "Foam Force is for boys. Laser Tag is for men. Contains three sets of red suits, blue suits, matching helmets, and matching laser tag guns."
+ cost = 3500
+ contains = list(/obj/item/gun/energy/laser/redtag,
+ /obj/item/gun/energy/laser/redtag,
+ /obj/item/gun/energy/laser/redtag,
+ /obj/item/gun/energy/laser/bluetag,
+ /obj/item/gun/energy/laser/bluetag,
+ /obj/item/gun/energy/laser/bluetag,
+ /obj/item/clothing/suit/redtag,
+ /obj/item/clothing/suit/redtag,
+ /obj/item/clothing/suit/redtag,
+ /obj/item/clothing/suit/bluetag,
+ /obj/item/clothing/suit/bluetag,
+ /obj/item/clothing/suit/bluetag,
+ /obj/item/clothing/head/helmet/redtaghelm,
+ /obj/item/clothing/head/helmet/redtaghelm,
+ /obj/item/clothing/head/helmet/redtaghelm,
+ /obj/item/clothing/head/helmet/bluetaghelm,
+ /obj/item/clothing/head/helmet/bluetaghelm,
+ /obj/item/clothing/head/helmet/bluetaghelm)
+ crate_name = "laser tag crate"
+
+/datum/supply_pack/costumes_toys/lasertag/pins
+ name = "Laser Tag Firing Pins Crate"
+ desc = "Three laser tag firing pins used in laser-tag units to ensure users are wearing their vests."
+ cost = 3000
+ contraband = TRUE
+ contains = list(/obj/item/storage/box/lasertagpins)
+ crate_name = "laser tag crate"
+
+/datum/supply_pack/costumes_toys/costume_original
+ name = "Original Costume Crate"
+ desc = "Reenact Shakespearean plays with this assortment of outfits. Contains eight different costumes!"
+ cost = 1750
+ contains = list(/obj/item/clothing/head/snowman,
+ /obj/item/clothing/suit/snowman,
+ /obj/item/clothing/head/chicken,
+ /obj/item/clothing/suit/chickensuit,
+ /obj/item/clothing/mask/gas/monkeymask,
+ /obj/item/clothing/suit/monkeysuit,
+ /obj/item/clothing/head/cardborg,
+ /obj/item/clothing/suit/cardborg,
+ /obj/item/clothing/head/xenos,
+ /obj/item/clothing/suit/xenos,
+ /obj/item/clothing/suit/hooded/ian_costume,
+ /obj/item/clothing/suit/hooded/carp_costume,
+ /obj/item/clothing/suit/hooded/bee_costume)
+ crate_name = "original costume crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/costume
+ name = "Standard Costume Crate"
+ desc = "Supply the station's entertainers with the equipment of their trade with these Nanotrasen-approved costumes! Contains a full clown and mime outfit, along with a bike horn and a bottle of nothing."
+ cost = 1300
+ access = ACCESS_THEATRE
+ contains = list(/obj/item/storage/backpack/clown,
+ /obj/item/clothing/shoes/clown_shoes,
+ /obj/item/clothing/mask/gas/clown_hat,
+ /obj/item/clothing/under/rank/clown,
+ /obj/item/bikehorn,
+ /obj/item/clothing/under/rank/mime,
+ /obj/item/clothing/shoes/sneakers/black,
+ /obj/item/clothing/gloves/color/white,
+ /obj/item/clothing/mask/gas/mime,
+ /obj/item/clothing/head/beret,
+ /obj/item/clothing/suit/suspenders,
+ /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing,
+ /obj/item/storage/backpack/mime)
+ crate_name = "standard costume crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/randomised/toys
+ name = "Toy Crate"
+ desc = "Who cares about pride and accomplishment? Skip the gaming and get straight to the sweet rewards with this product! Contains five random toys. Warranty void if used to prank research directors."
+ cost = 1500 // or play the arcade machines ya lazy bum
+ num_contained = 5
+ contains = list(/obj/item/storage/box/snappops,
+ /obj/item/toy/talking/AI,
+ /obj/item/toy/talking/codex_gigas,
+ /obj/item/clothing/under/syndicate/tacticool,
+ /obj/item/toy/sword ,
+ /obj/item/toy/gun,
+ /obj/item/gun/ballistic/shotgun/toy/crossbow,
+ /obj/item/storage/box/fakesyndiesuit,
+ /obj/item/storage/crayons,
+ /obj/item/toy/spinningtoy,
+ /obj/item/toy/prize/ripley,
+ /obj/item/toy/prize/fireripley,
+ /obj/item/toy/prize/deathripley,
+ /obj/item/toy/prize/gygax,
+ /obj/item/toy/prize/durand,
+ /obj/item/toy/prize/honk,
+ /obj/item/toy/prize/marauder,
+ /obj/item/toy/prize/seraph,
+ /obj/item/toy/prize/mauler,
+ /obj/item/toy/prize/odysseus,
+ /obj/item/toy/prize/phazon,
+ /obj/item/toy/prize/reticence,
+ /obj/item/toy/cards/deck,
+ /obj/item/toy/nuke,
+ /obj/item/toy/minimeteor,
+ /obj/item/toy/redbutton,
+ /obj/item/toy/talking/owl,
+ /obj/item/toy/talking/griffin,
+ /obj/item/coin/antagtoken,
+ /obj/item/stack/tile/fakespace/loaded,
+ /obj/item/stack/tile/fakepit/loaded,
+ /obj/item/toy/toy_xeno,
+ /obj/item/storage/box/actionfigure,
+ /obj/item/restraints/handcuffs/fake,
+ /obj/item/grenade/chem_grenade/glitter/pink,
+ /obj/item/grenade/chem_grenade/glitter/blue,
+ /obj/item/grenade/chem_grenade/glitter/white,
+ /obj/item/toy/eightball,
+ /obj/item/toy/windupToolbox,
+ /obj/item/toy/clockwork_watch,
+ /obj/item/toy/toy_dagger,
+ /obj/item/extendohand/acme,
+ /obj/item/hot_potato/harmless/toy,
+ /obj/item/card/emagfake,
+ /obj/item/clothing/shoes/wheelys,
+ /obj/item/clothing/shoes/kindleKicks,
+ /obj/item/storage/belt/military/snack,
+ /obj/item/toy/eightball,
+ /obj/item/vending_refill/donksoft)
+ crate_name = "toy crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/randomised/plush
+ name = "Plush Crate"
+ desc = "Plush tide station wide. Contains 5 random plushies for you to love. Warranty void if your love violates the terms of use."
+ cost = 1500 // or play the arcade machines ya lazy bum
+ num_contained = 5
+ contains = list(/obj/item/toy/plush/random,
+ /obj/item/toy/plush/random,
+ /obj/item/toy/plush/random,
+ /obj/item/toy/plush/random,
+ /obj/item/toy/plush/random) //I'm lazy
+ crate_name = "plushie crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/wizard
+ name = "Wizard Costume Crate"
+ desc = "Pretend to join the Wizard Federation with this full wizard outfit! Nanotrasen would like to remind its employees that actually joining the Wizard Federation is subject to termination of job and life."
+ cost = 2000
+ contains = list(/obj/item/staff,
+ /obj/item/clothing/suit/wizrobe/fake,
+ /obj/item/clothing/shoes/sandal,
+ /obj/item/clothing/head/wizard/fake)
+ crate_name = "wizard costume crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/randomised/fill(obj/structure/closet/crate/C)
+ var/list/L = contains.Copy()
+ for(var/i in 1 to num_contained)
+ var/item = pick_n_take(L)
+ new item(C)
+
+/datum/supply_pack/costumes_toys/wardrobes/autodrobe
+ name = "Autodrobe Supply Crate"
+ desc = "Autodrobe missing your favorite dress? Solve that issue today with this autodrobe refill."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/autodrobe)
+ crate_name = "autodrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/cargo
+ name = "Cargo Wardrobe Supply Crate"
+ desc = "This crate contains a refill for the CargoDrobe."
+ cost = 750
+ contains = list(/obj/item/vending_refill/wardrobe/cargo_wardrobe)
+ crate_name = "cargo department supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/engineering
+ name = "Engineering Wardrobe Supply Crate"
+ desc = "This crate contains refills for the EngiDrobe and AtmosDrobe."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/wardrobe/engi_wardrobe,
+ /obj/item/vending_refill/wardrobe/atmos_wardrobe)
+ crate_name = "engineering department wardrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/general
+ name = "General Wardrobes Supply Crate"
+ desc = "This crate contains refills for the CuraDrobe, BarDrobe, ChefDrobe, JaniDrobe, ChapDrobe."
+ cost = 3750
+ contains = list(/obj/item/vending_refill/wardrobe/curator_wardrobe,
+ /obj/item/vending_refill/wardrobe/bar_wardrobe,
+ /obj/item/vending_refill/wardrobe/chef_wardrobe,
+ /obj/item/vending_refill/wardrobe/jani_wardrobe,
+ /obj/item/vending_refill/wardrobe/chap_wardrobe)
+ crate_name = "general wardrobes vendor refills"
+
+/datum/supply_pack/costumes_toys/wardrobes/hydroponics
+ name = "Hydrobe Supply Crate"
+ desc = "This crate contains a refill for the Hydrobe."
+ cost = 750
+ contains = list(/obj/item/vending_refill/wardrobe/hydro_wardrobe)
+ crate_name = "hydrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/medical
+ name = "Medical Wardrobe Supply Crate"
+ desc = "This crate contains refills for the MediDrobe, ChemDrobe, GeneDrobe, and ViroDrobe."
+ cost = 3000
+ contains = list(/obj/item/vending_refill/wardrobe/medi_wardrobe,
+ /obj/item/vending_refill/wardrobe/chem_wardrobe,
+ /obj/item/vending_refill/wardrobe/gene_wardrobe,
+ /obj/item/vending_refill/wardrobe/viro_wardrobe)
+ crate_name = "medical department wardrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/science
+ name = "Science Wardrobe Supply Crate"
+ desc = "This crate contains refills for the SciDrobe and RoboDrobe."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/wardrobe/robo_wardrobe,
+ /obj/item/vending_refill/wardrobe/science_wardrobe)
+ crate_name = "science department wardrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/security
+ name = "Security Wardrobe Supply Crate"
+ desc = "This crate contains refills for the SecDrobe and LawDrobe."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/wardrobe/sec_wardrobe,
+ /obj/item/vending_refill/wardrobe/law_wardrobe)
+ crate_name = "security department supply crate"
+
+/datum/supply_pack/costumes_toys/kinkmate
+ name = "Kinkmate construction kit"
+ cost = 2000
+ contraband = TRUE
+ contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate)
+ crate_name = "Kinkmate construction kit"
diff --git a/code/modules/cargo/packs/emergency.dm b/code/modules/cargo/packs/emergency.dm
new file mode 100644
index 0000000000..1987369d20
--- /dev/null
+++ b/code/modules/cargo/packs/emergency.dm
@@ -0,0 +1,275 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Emergency ///////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/emergency
+ group = "Emergency"
+
+/datum/supply_pack/emergency/vehicle
+ name = "Biker Gang Kit" //TUNNEL SNAKES OWN THIS TOWN
+ desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!"
+ cost = 2500
+ contraband = TRUE
+ contains = list(/obj/vehicle/ridden/atv,
+ /obj/item/key,
+ /obj/item/clothing/suit/jacket/leather/overcoat,
+ /obj/item/clothing/gloves/color/black,
+ /obj/item/clothing/head/soft,
+ /obj/item/clothing/mask/bandana/skull)//so you can properly #cargoniabikergang
+ crate_name = "Biker Kit"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/emergency/equipment
+ name = "Emergency Bot/Internals Crate"
+ desc = "Explosions got you down? These supplies are guaranteed to patch up holes, in stations and people alike! Comes with two floorbots, two medbots, five oxygen masks and five small oxygen tanks."
+ cost = 2750
+ contains = list(/mob/living/simple_animal/bot/floorbot,
+ /mob/living/simple_animal/bot/floorbot,
+ /mob/living/simple_animal/bot/medbot,
+ /mob/living/simple_animal/bot/medbot,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas)
+ crate_name = "emergency crate"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/radiatione_emergency
+ name = "Emergenc Radiation Protection Crate"
+ desc = "Survive the Nuclear Apocalypse and Supermatter Engine alike with two sets of Radiation suits. Each set contains a helmet, suit, and Geiger counter. We'll even throw in a few pill bottles that are able to handles radiation and the affects of the poisoning."
+ cost = 2500
+ contains = list(/obj/item/clothing/head/radiation,
+ /obj/item/clothing/head/radiation,
+ /obj/item/clothing/suit/radiation,
+ /obj/item/clothing/suit/radiation,
+ /obj/item/geiger_counter,
+ /obj/item/geiger_counter,
+ /obj/item/storage/pill_bottle/mutarad,
+ /obj/item/storage/firstaid/radbgone)
+ crate_name = "radiation protection crate"
+ crate_type = /obj/structure/closet/crate/radiation
+
+/datum/supply_pack/emergency/rcds
+ name = "Emergency RCDs"
+ desc = "Bombs going off on station? SME blown and now you need to fix the hole it left behind? Well this crate has a pare of Rcds to be able to easily fix up any problem you may have!"
+ cost = 1500
+ contains = list(/obj/item/construction/rcd,
+ /obj/item/construction/rcd)
+ crate_name = "emergency rcds"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/soft_suit
+ name = "Emergency Space Suit "
+ desc = "Is there bombs going off left and right? Is there meteors shooting around the station? Well we have two fragile space suit for emergencys as well as air and masks."
+ cost = 1200
+ contains = list(/obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/suit/space/fragile,
+ /obj/item/clothing/suit/space/fragile,
+ /obj/item/clothing/head/helmet/space/fragile,
+ /obj/item/clothing/head/helmet/space/fragile)
+ crate_name = "emergency crate"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/firefighting
+ name = "Firefighting Crate"
+ desc = "Only you can prevent station fires. Partner up with two firefighter suits, gas masks, flashlights, large oxygen tanks, extinguishers, and hardhats!"
+ cost = 1200
+ contains = list(/obj/item/clothing/suit/fire/firefighter,
+ /obj/item/clothing/suit/fire/firefighter,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/flashlight,
+ /obj/item/flashlight,
+ /obj/item/tank/internals/oxygen/red,
+ /obj/item/tank/internals/oxygen/red,
+ /obj/item/extinguisher/advanced,
+ /obj/item/extinguisher/advanced,
+ /obj/item/clothing/head/hardhat/red,
+ /obj/item/clothing/head/hardhat/red)
+ crate_name = "firefighting crate"
+
+/datum/supply_pack/emergency/atmostank
+ name = "Firefighting Tank Backpack"
+ desc = "Mow down fires with this high-capacity fire fighting tank backpack. Requires Atmospherics access to open."
+ cost = 1000
+ access = ACCESS_ATMOSPHERICS
+ contains = list(/obj/item/watertank/atmos)
+ crate_name = "firefighting backpack crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/emergency/internals
+ name = "Internals Crate"
+ desc = "Master your life energy and control your breathing with three breath masks, three emergency oxygen tanks and three large air tanks."//IS THAT A
+ cost = 1000
+ contains = list(/obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/breath,
+ /obj/item/clothing/mask/breath,
+ /obj/item/clothing/mask/breath,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air)
+ crate_name = "internals crate"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/metalfoam
+ name = "Metal Foam Grenade Crate"
+ desc = "Seal up those pesky hull breaches with 14 Metal Foam Grenades."
+ cost = 1500
+ contains = list(/obj/item/storage/box/metalfoam,
+ /obj/item/storage/box/metalfoam)
+ crate_name = "metal foam grenade crate"
+
+/datum/supply_pack/emergency/syndicate
+ name = "NULL_ENTRY"
+ desc = "(#@&^$THIS PACKAGE CONTAINS 30TC WORTH OF SOME RANDOM SYNDICATE GEAR WE HAD LYING AROUND THE WAREHOUSE. GIVE EM HELL, OPERATIVE@&!*() "
+ hidden = TRUE
+ cost = 20000
+ contains = list()
+ crate_name = "emergency crate"
+ crate_type = /obj/structure/closet/crate/internals
+ dangerous = TRUE
+
+/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
+ var/crate_value = 30
+ var/list/uplink_items = get_uplink_items(SSticker.mode)
+ while(crate_value)
+ var/category = pick(uplink_items)
+ var/item = pick(uplink_items[category])
+ var/datum/uplink_item/I = uplink_items[category][item]
+ if(!I.surplus_nullcrates || prob(100 - I.surplus_nullcrates))
+ continue
+ if(crate_value < I.cost)
+ continue
+ crate_value -= I.cost
+ new I.item(C)
+
+/datum/supply_pack/emergency/plasma_spacesuit
+ name = "Plasmaman Space Envirosuits"
+ desc = "Contains two space-worthy envirosuits for Plasmamen. Order now and we'll throw in two free helmets! Requires EVA access to open."
+ cost = 4000
+ access = ACCESS_EVA
+ contains = list(/obj/item/clothing/suit/space/eva/plasmaman,
+ /obj/item/clothing/suit/space/eva/plasmaman,
+ /obj/item/clothing/head/helmet/space/plasmaman,
+ /obj/item/clothing/head/helmet/space/plasmaman)
+ crate_name = "plasmaman EVA crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/emergency/plasmaman
+ name = "Plasmaman Supply Kit"
+ desc = "Keep those Plasmamen alive with two sets of Plasmaman outfits. Each set contains a plasmaman jumpsuit, internals tank, and helmet."
+ cost = 2000
+ contains = list(/obj/item/clothing/under/plasmaman,
+ /obj/item/clothing/under/plasmaman,
+ /obj/item/tank/internals/plasmaman/belt/full,
+ /obj/item/tank/internals/plasmaman/belt/full,
+ /obj/item/clothing/head/helmet/space/plasmaman,
+ /obj/item/clothing/head/helmet/space/plasmaman)
+ crate_name = "plasmaman supply kit"
+
+/datum/supply_pack/emergency/radiation
+ name = "Radiation Protection Crate"
+ desc = "Survive the Nuclear Apocalypse and Supermatter Engine alike with two sets of Radiation suits. Each set contains a helmet, suit, and Geiger counter. We'll even throw in a bottle of vodka and some glasses too, considering the life-expectancy of people who order this."
+ cost = 1300
+ contains = list(/obj/item/clothing/head/radiation,
+ /obj/item/clothing/head/radiation,
+ /obj/item/clothing/suit/radiation,
+ /obj/item/clothing/suit/radiation,
+ /obj/item/geiger_counter,
+ /obj/item/geiger_counter,
+ /obj/item/reagent_containers/food/drinks/bottle/vodka,
+ /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
+ crate_name = "radiation protection crate"
+ crate_type = /obj/structure/closet/crate/radiation
+
+/datum/supply_pack/emergency/spacesuit
+ name = "Space Suit Crate"
+ desc = "Contains two aging suits from Space-Goodwill. Requires EVA access to open."
+ cost = 3000
+ access = ACCESS_EVA
+ contains = list(/obj/item/clothing/suit/space,
+ /obj/item/clothing/suit/space,
+ /obj/item/clothing/head/helmet/space,
+ /obj/item/clothing/head/helmet/space,
+ /obj/item/clothing/mask/breath,
+ /obj/item/clothing/mask/breath)
+ crate_name = "space suit crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/emergency/spacejets
+ name = "Spare EVA Jetpacks"
+ desc = "Contains three EVA grade jectpaks. Requires EVA access to open."
+ cost = 2000
+ access = ACCESS_EVA
+ contains = list(/obj/item/tank/jetpack/carbondioxide/eva,
+ /obj/item/tank/jetpack/carbondioxide/eva,
+ /obj/item/tank/jetpack/carbondioxide/eva)
+ crate_name = "eva jetpacks crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/emergency/specialops
+ name = "Special Ops Supplies"
+ desc = "(*!&@#TOO CHEAP FOR THAT NULL_ENTRY, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN STILL HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, AND A \"SLEEPY PEN\" FULL OF NICE TOXINS!#@*$"
+ hidden = TRUE
+ cost = 2200
+ contains = list(/obj/item/storage/box/emps,
+ /obj/item/grenade/smokebomb,
+ /obj/item/grenade/smokebomb,
+ /obj/item/grenade/smokebomb,
+ /obj/item/pen/sleepy,
+ /obj/item/grenade/chem_grenade/incendiary)
+ crate_name = "emergency crate"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/weedcontrol
+ name = "Weed Control Crate"
+ desc = "Keep those invasive species OUT. Contains a scythe, gasmask, two sprays of Plant-B-Gone, and two anti-weed chemical grenades. Warranty void if used on ambrosia. Requires Hydroponics access to open."
+ cost = 1800
+ access = ACCESS_HYDROPONICS
+ contains = list(/obj/item/scythe,
+ /obj/item/clothing/mask/gas,
+ /obj/item/grenade/chem_grenade/antiweed,
+ /obj/item/grenade/chem_grenade/antiweed,
+ /obj/item/reagent_containers/spray/plantbgone,
+ /obj/item/reagent_containers/spray/plantbgone)
+ crate_name = "weed control crate"
+ crate_type = /obj/structure/closet/crate/secure/hydroponics
+
+/datum/supply_pack/medical/anitvirus
+ name = "Virus Containment Crate"
+ desc = "Viro let out a death plague Mk II again? Someone didnt wash there hands? Old plagues born anew? Well this crate is for you! Hope you cure it before it brakes out of the station... This crate needs medical access to open and has two bio suits, a box of needles and beakers, five spaceacillin needles, and a medibot."
+ cost = 3000
+ access = ACCESS_MEDICAL
+ contains = list(/mob/living/simple_animal/bot/medbot,
+ /obj/item/clothing/head/bio_hood,
+ /obj/item/clothing/head/bio_hood,
+ /obj/item/clothing/suit/bio_suit,
+ /obj/item/clothing/suit/bio_suit,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/storage/box/syringes,
+ /obj/item/storage/box/beakers)
+ crate_name = "virus containment unit crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
diff --git a/code/modules/cargo/packs/engine.dm b/code/modules/cargo/packs/engine.dm
new file mode 100644
index 0000000000..a4438c7ef8
--- /dev/null
+++ b/code/modules/cargo/packs/engine.dm
@@ -0,0 +1,169 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////// Engine Construction /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/engine
+ group = "Engine Construction"
+ crate_type = /obj/structure/closet/crate/engineering
+
+/datum/supply_pack/engine/am_jar
+ name = "Antimatter Containment Jar Crate"
+ desc = "Two Antimatter containment jars stuffed into a single crate."
+ cost = 2300
+ contains = list(/obj/item/am_containment,
+ /obj/item/am_containment)
+ crate_name = "antimatter jar crate"
+
+/datum/supply_pack/engine/am_core
+ name = "Antimatter Control Crate"
+ desc = "The brains of the Antimatter engine, this device is sure to teach the station's powergrid the true meaning of real power."
+ cost = 5200
+ contains = list(/obj/machinery/power/am_control_unit)
+ crate_name = "antimatter control crate"
+
+/datum/supply_pack/engine/am_shielding
+ name = "Antimatter Shielding Crate"
+ desc = "Contains ten Antimatter shields, somehow crammed into a crate."
+ cost = 2500
+ contains = list(/obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container) //10 shields: 3x3 containment and a core
+ crate_name = "antimatter shielding crate"
+
+/datum/supply_pack/engine/emitter
+ name = "Emitter Crate"
+ desc = "Useful for powering forcefield generators while destroying locked crates and intruders alike. Contains two high-powered energy emitters. Requires CE access to open."
+ cost = 1750
+ access = ACCESS_CE
+ contains = list(/obj/machinery/power/emitter,
+ /obj/machinery/power/emitter)
+ crate_name = "emitter crate"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+ dangerous = TRUE
+
+/datum/supply_pack/engine/field_gen
+ name = "Field Generator Crate"
+ desc = "Typically the only thing standing between the station and a messy death. Powered by emitters. Contains two field generators."
+ cost = 1750
+ contains = list(/obj/machinery/field/generator,
+ /obj/machinery/field/generator)
+ crate_name = "field generator crate"
+
+/datum/supply_pack/engine/grounding_rods
+ name = "Grounding Rod Crate"
+ desc = "Four grounding rods guaranteed to keep any uppity tesla's lightning under control."
+ cost = 2200
+ contains = list(/obj/machinery/power/grounding_rod,
+ /obj/machinery/power/grounding_rod,
+ /obj/machinery/power/grounding_rod,
+ /obj/machinery/power/grounding_rod)
+ crate_name = "grounding rod crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engine/mason
+ name = "M.A.S.O.N RIG Crate"
+ desc = "The rare M.A.S.O.N RIG. Requires CE access to open."
+ cost = 15000
+ access = ACCESS_CE
+ contains = list(/obj/item/clothing/suit/space/hardsuit/ancient/mason)
+ crate_name = "M.A.S.O.N Rig"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+
+/datum/supply_pack/engine/PA
+ name = "Particle Accelerator Crate"
+ desc = "A supermassive black hole or hyper-powered teslaball are the perfect way to spice up any party! This \"My First Apocalypse\" kit contains everything you need to build your own Particle Accelerator! Ages 10 and up."
+ cost = 3750
+ contains = list(/obj/structure/particle_accelerator/fuel_chamber,
+ /obj/machinery/particle_accelerator/control_box,
+ /obj/structure/particle_accelerator/particle_emitter/center,
+ /obj/structure/particle_accelerator/particle_emitter/left,
+ /obj/structure/particle_accelerator/particle_emitter/right,
+ /obj/structure/particle_accelerator/power_box,
+ /obj/structure/particle_accelerator/end_cap)
+ crate_name = "particle accelerator crate"
+
+/datum/supply_pack/engine/collector
+ name = "Radiation Collector Crate"
+ desc = "Contains three radiation collectors. Useful for collecting energy off nearby Supermatter Crystals, Singularities or Teslas!"
+ cost = 2750
+ contains = list(/obj/machinery/power/rad_collector,
+ /obj/machinery/power/rad_collector,
+ /obj/machinery/power/rad_collector)
+ crate_name = "collector crate"
+
+/datum/supply_pack/engine/sing_gen
+ name = "Singularity Generator Crate"
+ desc = "The key to unlocking the power of Lord Singuloth. Particle Accelerator not included."
+ cost = 6000
+ contains = list(/obj/machinery/the_singularitygen)
+ crate_name = "singularity generator crate"
+
+/datum/supply_pack/engine/solar
+ name = "Solar Panel Crate"
+ desc = "Go green with this DIY advanced solar array. Contains twenty one solar assemblies, a solar-control circuit board, and tracker. If you have any questions, please check out the enclosed instruction book."
+ cost = 2850
+ contains = list(/obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/circuitboard/computer/solar_control,
+ /obj/item/electronics/tracker,
+ /obj/item/paper/guides/jobs/engi/solars)
+ crate_name = "solar panel crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engine/supermatter_shard
+ name = "Supermatter Shard Crate"
+ desc = "The power of the heavens condensed into a single crystal. Requires CE access to open."
+ cost = 10000
+ access = ACCESS_CE
+ contains = list(/obj/machinery/power/supermatter_crystal/shard)
+ crate_name = "supermatter shard crate"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+ dangerous = TRUE
+
+/datum/supply_pack/engine/tesla_coils
+ name = "Tesla Coil Crate"
+ desc = "Whether it's high-voltage executions, creating research points, or just plain old power generation: This pack of four Tesla coils can do it all!"
+ cost = 3500
+ contains = list(/obj/machinery/power/tesla_coil,
+ /obj/machinery/power/tesla_coil,
+ /obj/machinery/power/tesla_coil,
+ /obj/machinery/power/tesla_coil)
+ crate_name = "tesla coil crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engine/tesla_gen
+ name = "Tesla Generator Crate"
+ desc = "The key to unlocking the power of the Tesla energy ball. Particle Accelerator not included."
+ cost = 7000
+ contains = list(/obj/machinery/the_singularitygen/tesla)
+ crate_name = "tesla generator crate"
diff --git a/code/modules/cargo/packs/engineering.dm b/code/modules/cargo/packs/engineering.dm
new file mode 100644
index 0000000000..19cb53489e
--- /dev/null
+++ b/code/modules/cargo/packs/engineering.dm
@@ -0,0 +1,229 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Engineering /////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/engineering
+ group = "Engineering"
+ crate_type = /obj/structure/closet/crate/engineering
+
+/datum/supply_pack/engineering/shieldgen
+ name = "Anti-breach Shield Projector Crate"
+ desc = "Hull breaches again? Say no more with the Nanotrasen Anti-Breach Shield Projector! Uses forcefield technology to keep the air in, and the space out. Contains two shield projectors."
+ cost = 2500
+ contains = list(/obj/machinery/shieldgen,
+ /obj/machinery/shieldgen)
+ crate_name = "anti-breach shield projector crate"
+
+/datum/supply_pack/engineering/conveyor
+ name = "Conveyor Assembly Crate"
+ desc = "Keep production moving along with six conveyor belts. Conveyor switch included. If you have any questions, check out the enclosed instruction book."
+ cost = 750
+ contains = list(/obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_switch_construct,
+ /obj/item/paper/guides/conveyor)
+ crate_name = "conveyor assembly crate"
+
+/datum/supply_pack/engineering/engiequipment
+ name = "Engineering Gear Crate"
+ desc = "Gear up with three toolbelts, high-visibility vests, welding helmets, hardhats, and two pairs of meson goggles!"
+ cost = 1500
+ contains = list(/obj/item/storage/belt/utility,
+ /obj/item/storage/belt/utility,
+ /obj/item/storage/belt/utility,
+ /obj/item/clothing/suit/hazardvest,
+ /obj/item/clothing/suit/hazardvest,
+ /obj/item/clothing/suit/hazardvest,
+ /obj/item/clothing/head/welding,
+ /obj/item/clothing/head/welding,
+ /obj/item/clothing/head/welding,
+ /obj/item/clothing/head/hardhat,
+ /obj/item/clothing/head/hardhat,
+ /obj/item/clothing/head/hardhat,
+ /obj/item/clothing/glasses/meson/engine,
+ /obj/item/clothing/glasses/meson/engine)
+ crate_name = "engineering gear crate"
+
+/datum/supply_pack/engineering/engihardsuit
+ name = "Engineering Hardsuit"
+ desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!"
+ cost = 2250
+ contains = list(/obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/suit/space/hardsuit/engine)
+ crate_name = "engineering hardsuit"
+
+/datum/supply_pack/engineering/atmoshardsuit
+ name = "Atmospherics Hardsuit"
+ desc = "Too many techs and not enough hardsuits? Time to buy some more! Comes with gas mask and air tank. Ask the CE to open."
+ cost = 5000
+ access = ACCESS_CE
+ contains = list(/obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/suit/space/hardsuit/engine/atmos)
+ crate_name = "atmospherics hardsuit"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+
+/datum/supply_pack/engineering/industrialrcd
+ name = "Industrial RCD"
+ desc = "A industrial RCD in case the station has gone through more then one meteor storm and the CE needs to bring out the somthing a bit more reliable. Dose not contain spare ammo for the industrial RCD or any other RCD modles."
+ cost = 4500
+ access = ACCESS_CE
+ contains = list(/obj/item/construction/rcd/industrial)
+ crate_name = "industrial rcd"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+
+/datum/supply_pack/engineering/powergamermitts
+ name = "Insulated Gloves Crate"
+ desc = "The backbone of modern society. Barely ever ordered for actual engineering. Contains three insulated gloves."
+ cost = 2300 //Made of pure-grade bullshittinium
+ contains = list(/obj/item/clothing/gloves/color/yellow,
+ /obj/item/clothing/gloves/color/yellow,
+ /obj/item/clothing/gloves/color/yellow)
+ crate_name = "insulated gloves crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/obj/item/stock_parts/cell/inducer_supply
+ maxcharge = 5000
+ charge = 5000
+
+/datum/supply_pack/engineering/inducers
+ name = "NT-75 Electromagnetic Power Inducers Crate"
+ desc = "No rechargers? No problem, with the NT-75 EPI, you can recharge any standard cell-based equipment anytime, anywhere. Contains two Inducers."
+ cost = 2300
+ contains = list(/obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}, /obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}) //FALSE doesn't work in modified type paths apparently.
+ crate_name = "inducer crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engineering/pacman
+ name = "P.A.C.M.A.N Generator Crate"
+ desc = "Engineers can't set up the engine? Not an issue for you, once you get your hands on this P.A.C.M.A.N. Generator! Takes in plasma and spits out sweet sweet energy."
+ cost = 2250
+ contains = list(/obj/machinery/power/port_gen/pacman)
+ crate_name = "PACMAN generator crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engineering/power
+ name = "Power Cell Crate"
+ desc = "Looking for power overwhelming? Look no further. Contains three high-voltage power cells."
+ cost = 1000
+ contains = list(/obj/item/stock_parts/cell/high,
+ /obj/item/stock_parts/cell/high,
+ /obj/item/stock_parts/cell/high)
+ crate_name = "power cell crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+
+/datum/supply_pack/engineering/siezedpower
+ name = "Siezed Power Cell Crate"
+ desc = "We took the means of power! Contains three high-voltage plus power cells."
+ cost = 1300
+ contraband = TRUE
+ contains = list(/obj/item/stock_parts/cell/high/plus,
+ /obj/item/stock_parts/cell/high/plus,
+ /obj/item/stock_parts/cell/high/plus)
+ crate_name = "siezed crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engineering/shuttle_engine
+ name = "Shuttle Engine Crate"
+ desc = "Through advanced bluespace-shenanigans, our engineers have managed to fit an entire shuttle engine into one tiny little crate. Requires CE access to open."
+ cost = 5000
+ access = ACCESS_CE
+ contains = list(/obj/structure/shuttle/engine/propulsion/burst/cargo)
+ crate_name = "shuttle engine crate"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+
+/datum/supply_pack/engineering/siezedproduction
+ name = "The Means of Production"
+ desc = "We will win for we have took over the production! S five metal sheets, five wire, three matter bins, one manipulater and one sheet of glass."
+ cost = 1500
+ contraband = TRUE
+ contains = list(/obj/item/stock_parts/cell/high/plus,
+ /obj/item/circuitboard/machine/autolathe,
+ /obj/item/stack/cable_coil/random/five,
+ /obj/item/stack/sheet/metal/five,
+ /obj/item/stock_parts/matter_bin,
+ /obj/item/stock_parts/matter_bin,
+ /obj/item/stock_parts/matter_bin,
+ /obj/item/stock_parts/manipulator,
+ /obj/item/stack/sheet/glass,)
+ crate_name = "siezed crate"
+
+/datum/supply_pack/engineering/tools
+ name = "Toolbox Crate"
+ desc = "Any robust spaceman is never far from their trusty toolbox. Contains three electrical toolboxes and three mechanical toolboxes."
+ contains = list(/obj/item/storage/toolbox/electrical,
+ /obj/item/storage/toolbox/electrical,
+ /obj/item/storage/toolbox/electrical,
+ /obj/item/storage/toolbox/mechanical,
+ /obj/item/storage/toolbox/mechanical,
+ /obj/item/storage/toolbox/mechanical)
+ cost = 1200
+ crate_name = "toolbox crate"
+
+/datum/supply_pack/engineering/bsa
+ name = "Bluespace Artillery Parts"
+ desc = "The pride of Nanotrasen Naval Command. The legendary Bluespace Artillery Cannon is a devastating feat of human engineering and testament to wartime determination. Highly advanced research is required for proper construction. "
+ cost = 15000
+ special = TRUE
+ contains = list(/obj/item/circuitboard/machine/bsa/front,
+ /obj/item/circuitboard/machine/bsa/middle,
+ /obj/item/circuitboard/machine/bsa/back,
+ /obj/item/circuitboard/computer/bsa_control
+ )
+ crate_name= "bluespace artillery parts crate"
+
+/datum/supply_pack/engineering/dna_vault
+ name = "DNA Vault Parts"
+ desc = "Secure the longevity of the current state of humanity within this massive library of scientific knowledge, capable of granting superhuman powers and abilities. Highly advanced research is required for proper construction. Also contains five DNA probes."
+ cost = 12000
+ special = TRUE
+ contains = list(
+ /obj/item/circuitboard/machine/dna_vault,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe
+ )
+ crate_name= "dna vault parts crate"
+
+/datum/supply_pack/engineering/dna_probes
+ name = "DNA Vault Samplers"
+ desc = "Contains five DNA probes for use in the DNA vault."
+ cost = 3000
+ special = TRUE
+ contains = list(/obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe
+ )
+ crate_name= "dna samplers crate"
+
+/datum/supply_pack/engineering/shield_sat
+ name = "Shield Generator Satellite"
+ desc = "Protect the very existence of this station with these Anti-Meteor defenses. Contains three Shield Generator Satellites."
+ cost = 4000
+ contains = list(
+ /obj/machinery/satellite/meteor_shield,
+ /obj/machinery/satellite/meteor_shield,
+ /obj/machinery/satellite/meteor_shield
+ )
+ crate_name= "shield sat crate"
+
+/datum/supply_pack/engineering/shield_sat_control
+ name = "Shield System Control Board"
+ desc = "A control system for the Shield Generator Satellite system."
+ cost = 4000
+ contains = list(/obj/item/circuitboard/computer/sat_control)
+ crate_name= "shield control board crate"
diff --git a/code/modules/cargo/packs/livestock.dm b/code/modules/cargo/packs/livestock.dm
new file mode 100644
index 0000000000..6479869ee0
--- /dev/null
+++ b/code/modules/cargo/packs/livestock.dm
@@ -0,0 +1,154 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////// Livestock /////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/critter
+ group = "Livestock"
+ crate_type = /obj/structure/closet/crate/critter
+
+/datum/supply_pack/critter/butterfly
+ name = "Butterflies Crate"
+ desc = "Not a very dangerous insect, but they do give off a better image than, say, flies or cockroaches."//is that a motherfucking worm reference
+ contraband = TRUE
+ cost = 5000
+ contains = list(/mob/living/simple_animal/butterfly)
+ crate_name = "entomology samples crate"
+
+/datum/supply_pack/critter/butterfly/generate()
+ . = ..()
+ for(var/i in 1 to 49)
+ new /mob/living/simple_animal/butterfly(.)
+
+/datum/supply_pack/critter/cat
+ name = "Cat Crate"
+ desc = "The cat goes meow! Comes with a collar and a nice cat toy! Cheeseburger not included."//i can't believe im making this reference
+ cost = 5000 //Cats are worth as much as corgis.
+ contains = list(/mob/living/simple_animal/pet/cat,
+ /obj/item/clothing/neck/petcollar,
+ /obj/item/toy/cattoy)
+ crate_name = "cat crate"
+
+/datum/supply_pack/critter/cat/generate()
+ . = ..()
+ if(prob(50))
+ var/mob/living/simple_animal/pet/cat/C = locate() in .
+ qdel(C)
+ new /mob/living/simple_animal/pet/cat/Proc(.)
+
+/datum/supply_pack/critter/chick
+ name = "Chicken Crate"
+ desc = "The chicken goes bwaak!"
+ cost = 2000
+ contains = list( /mob/living/simple_animal/chick)
+ crate_name = "chicken crate"
+
+/datum/supply_pack/critter/crab
+ name = "Crab Rocket"
+ desc = "CRAAAAAAB ROCKET. CRAB ROCKET. CRAB ROCKET. CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB ROCKET. CRAFT. ROCKET. BUY. CRAFT ROCKET. CRAB ROOOCKET. CRAB ROOOOCKET. CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB ROOOOOOOOOOOOOOOOOOOOOOCK EEEEEEEEEEEEEEEEEEEEEEEEE EEEETTTTTTTTTTTTAAAAAAAAA AAAHHHHHHHHHHHHH. CRAB ROCKET. CRAAAB ROCKEEEEEEEEEGGGGHHHHTT CRAB CRAB CRAABROCKET CRAB ROCKEEEET."//fun fact: i actually spent like 10 minutes and transcribed the entire video.
+ cost = 5000
+ contains = list(/mob/living/simple_animal/crab)
+ crate_name = "look sir free crabs"
+ DropPodOnly = TRUE
+
+/datum/supply_pack/critter/crab/generate()
+ . = ..()
+ for(var/i in 1 to 49)
+ new /mob/living/simple_animal/crab(.)
+
+/datum/supply_pack/critter/corgi
+ name = "Corgi Crate"
+ desc = "Considered the optimal dog breed by thousands of research scientists, this Corgi is but one dog from the millions of Ian's noble bloodline. Comes with a cute collar!"
+ cost = 5000
+ contains = list(/mob/living/simple_animal/pet/dog/corgi,
+ /obj/item/clothing/neck/petcollar)
+ crate_name = "corgi crate"
+
+/datum/supply_pack/critter/corgi/generate()
+ . = ..()
+ if(prob(50))
+ var/mob/living/simple_animal/pet/dog/corgi/D = locate() in .
+ if(D.gender == FEMALE)
+ qdel(D)
+ new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
+
+/datum/supply_pack/critter/corgis/exotic
+ name = "Exotic Corgi Crate"
+ desc = "Corgis fit for a king, these corgis come in a unique color to signify their superiority. Comes with a cute collar!"
+ cost = 5500
+ contains = list(/mob/living/simple_animal/pet/dog/corgi/exoticcorgi,
+ /obj/item/clothing/neck/petcollar)
+ crate_name = "exotic corgi crate"
+
+/datum/supply_pack/critter/cow
+ name = "Cow Crate"
+ desc = "The cow goes moo!"
+ cost = 3000
+ contains = list(/mob/living/simple_animal/cow)
+ crate_name = "cow crate"
+
+/datum/supply_pack/critter/fox
+ name = "Fox Crate"
+ desc = "The fox goes...? Comes with a collar!"//what does the fox say
+ cost = 5000
+ contains = list(/mob/living/simple_animal/pet/fox,
+ /obj/item/clothing/neck/petcollar)
+ crate_name = "fox crate"
+
+/datum/supply_pack/critter/goat
+ name = "Goat Crate"
+ desc = "The goat goes baa! Warranty void if used as a replacement for Pete."
+ cost = 2500
+ contains = list(/mob/living/simple_animal/hostile/retaliate/goat)
+ crate_name = "goat crate"
+
+/datum/supply_pack/critter/goose
+ name = "Goose Crate"
+ desc = "Angry and violent birds. Evil, evil creatures."
+ cost = 2500
+ contains = list(/mob/living/simple_animal/hostile/retaliate/goose)
+ crate_name = "goose crate"
+
+/datum/supply_pack/critter/monkey
+ name = "Monkey Cube Crate"
+ desc = "Stop monkeying around! Contains seven monkey cubes. Just add water!"
+ cost = 2000
+ contains = list (/obj/item/storage/box/monkeycubes)
+ crate_name = "monkey cube crate"
+
+/datum/supply_pack/critter/pug
+ name = "Pug Crate"
+ desc = "Like a normal dog, but... squished. Comes with a nice collar!"
+ cost = 5000
+ contains = list(/mob/living/simple_animal/pet/dog/pug,
+ /obj/item/clothing/neck/petcollar)
+ crate_name = "pug crate"
+
+/datum/supply_pack/organic/critter/kiwi
+ name = "Space kiwi Crate"
+ cost = 2000
+ contains = list( /mob/living/simple_animal/kiwi)
+ crate_name = "space kiwi crate"
+
+/datum/supply_pack/critter/snake
+ name = "Snake Crate"
+ desc = "Tired of these MOTHER FUCKING snakes on this MOTHER FUCKING space station? Then this isn't the crate for you. Contains three poisonous snakes."
+ cost = 3000
+ contains = list(/mob/living/simple_animal/hostile/retaliate/poison/snake,
+ /mob/living/simple_animal/hostile/retaliate/poison/snake,
+ /mob/living/simple_animal/hostile/retaliate/poison/snake)
+ crate_name = "snake crate"
+
+/datum/supply_pack/critter/secbat
+ name = "Security Bat Crate"
+ desc = "Contains five security bats, perfect to Bat-up any security officer."
+ cost = 2500
+ contains = list(/mob/living/simple_animal/hostile/retaliate/bat/secbat,
+ /mob/living/simple_animal/hostile/retaliate/bat/secbat,
+ /mob/living/simple_animal/hostile/retaliate/bat/secbat,
+ /mob/living/simple_animal/hostile/retaliate/bat/secbat,
+ /mob/living/simple_animal/hostile/retaliate/bat/secbat)
+ crate_name = "security bat crate"
diff --git a/code/modules/cargo/packs/materials.dm b/code/modules/cargo/packs/materials.dm
new file mode 100644
index 0000000000..0f8ad2462a
--- /dev/null
+++ b/code/modules/cargo/packs/materials.dm
@@ -0,0 +1,170 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////// Canisters & Materials ////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/materials
+ group = "Canisters & Materials"
+
+/datum/supply_pack/materials/cardboard50
+ name = "50 Cardboard Sheets"
+ desc = "Create a bunch of boxes."
+ cost = 1000
+ contains = list(/obj/item/stack/sheet/cardboard/fifty)
+ crate_name = "cardboard sheets crate"
+
+/datum/supply_pack/materials/glass50
+ name = "50 Glass Sheets"
+ desc = "Let some nice light in with fifty glass sheets!"
+ cost = 850
+ contains = list(/obj/item/stack/sheet/glass/fifty)
+ crate_name = "glass sheets crate"
+
+/datum/supply_pack/materials/metal50
+ name = "50 Metal Sheets"
+ desc = "Any construction project begins with a good stack of fifty metal sheets!"
+ cost = 850
+ contains = list(/obj/item/stack/sheet/metal/fifty)
+ crate_name = "metal sheets crate"
+
+/datum/supply_pack/materials/plasteel20
+ name = "20 Plasteel Sheets"
+ desc = "Reinforce the station's integrity with twenty plasteel sheets!"
+ cost = 4700
+ contains = list(/obj/item/stack/sheet/plasteel/twenty)
+ crate_name = "plasteel sheets crate"
+
+/datum/supply_pack/materials/plasteel50
+ name = "50 Plasteel Sheets"
+ desc = "For when you REALLY have to reinforce something."
+ cost = 9050
+ contains = list(/obj/item/stack/sheet/plasteel/fifty)
+ crate_name = "plasteel sheets crate"
+
+/datum/supply_pack/materials/plastic50
+ name = "50 Plastic Sheets"
+ desc = "Build a limitless amount of toys with fifty plastic sheets!"
+ cost = 950
+ contains = list(/obj/item/stack/sheet/plastic/fifty)
+ crate_name = "plastic sheets crate"
+
+/datum/supply_pack/materials/sandstone30
+ name = "30 Sandstone Blocks"
+ desc = "Neither sandy nor stoney, these thirty blocks will still get the job done."
+ cost = 800
+ contains = list(/obj/item/stack/sheet/mineral/sandstone/thirty)
+ crate_name = "sandstone blocks crate"
+
+/datum/supply_pack/materials/wood50
+ name = "50 Wood Planks"
+ desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with fifty wooden planks!"
+ cost = 1450
+ contains = list(/obj/item/stack/sheet/mineral/wood/fifty)
+ crate_name = "wood planks crate"
+
+/datum/supply_pack/materials/rcdammo
+ name = "Spare RDC ammo"
+ desc = "This crate contains sixteen RCD ammo packs, to help with any holes or projects people mite be working on."
+ cost = 3750
+ contains = list(/obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo)
+ crate_name = "rcd ammo"
+
+/datum/supply_pack/materials/bz
+ name = "BZ Canister Crate"
+ desc = "Contains a canister of BZ. Requires Toxins access to open."
+ cost = 7500 // Costs 3 credits more than what you can get for selling it.
+ access = ACCESS_TOX_STORAGE
+ contains = list(/obj/machinery/portable_atmospherics/canister/bz)
+ crate_name = "BZ canister crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/materials/carbon_dio
+ name = "Carbon Dioxide Canister"
+ desc = "Contains a canister of Carbon Dioxide."
+ cost = 3000
+ contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide)
+ crate_name = "carbon dioxide canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/nitrogen
+ name = "Nitrogen Canister"
+ desc = "Contains a canister of Nitrogen."
+ cost = 2000
+ contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen)
+ crate_name = "nitrogen canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/nitrous_oxide_canister
+ name = "Nitrous Oxide Canister"
+ desc = "Contains a canister of Nitrous Oxide. Requires Atmospherics access to open."
+ cost = 3000
+ access = ACCESS_ATMOSPHERICS
+ contains = list(/obj/machinery/portable_atmospherics/canister/nitrous_oxide)
+ crate_name = "nitrous oxide canister crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/materials/oxygen
+ name = "Oxygen Canister"
+ desc = "Contains a canister of Oxygen. Canned in Druidia."
+ cost = 1500
+ contains = list(/obj/machinery/portable_atmospherics/canister/oxygen)
+ crate_name = "oxygen canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/water_vapor
+ name = "Water Vapor Canister"
+ desc = "Contains a canister of Water Vapor. I swear to god if you open this in the halls..."
+ cost = 2500
+ contains = list(/obj/machinery/portable_atmospherics/canister/water_vapor)
+ crate_name = "water vapor canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/fueltank
+ name = "Fuel Tank Crate"
+ desc = "Contains a welding fuel tank. Caution, highly flammable."
+ cost = 800
+ contains = list(/obj/structure/reagent_dispensers/fueltank)
+ crate_name = "fuel tank crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/watertank
+ name = "Water Tank Crate"
+ desc = "Contains a tank of dihydrogen monoxide... sounds dangerous."
+ cost = 600
+ contains = list(/obj/structure/reagent_dispensers/watertank)
+ crate_name = "water tank crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/foamtank
+ name = "Firefighting Foam Tank Crate"
+ desc = "Contains a tank of firefighting foam. Also known as \"plasmaman's bane\"."
+ cost = 1500
+ contains = list(/obj/structure/reagent_dispensers/foamtank)
+ crate_name = "foam tank crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/hightank
+ name = "Large Water Tank Crate"
+ desc = "Contains a high-capacity water tank. Useful for botany or other service jobs."
+ cost = 1200
+ contains = list(/obj/structure/reagent_dispensers/watertank/high)
+ crate_name = "high-capacity water tank crate"
+ crate_type = /obj/structure/closet/crate/large
diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm
new file mode 100644
index 0000000000..656474cc1d
--- /dev/null
+++ b/code/modules/cargo/packs/medical.dm
@@ -0,0 +1,228 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Medical /////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/medical
+ group = "Medical"
+ crate_type = /obj/structure/closet/crate/medical
+
+/datum/supply_pack/medical/firstaidbruises
+ name = "Bruise Treatment Kit Crate"
+ desc = "Contains three first aid kits focused on healing bruises and broken bones."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/brute,
+ /obj/item/storage/firstaid/brute,
+ /obj/item/storage/firstaid/brute)
+ crate_name = "brute treatment kit crate"
+
+/datum/supply_pack/medical/firstaidburns
+ name = "Burn Treatment Kit Crate"
+ desc = "Contains three first aid kits focused on healing severe burns."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/fire,
+ /obj/item/storage/firstaid/fire,
+ /obj/item/storage/firstaid/fire)
+ crate_name = "burn treatment kit crate"
+
+/datum/supply_pack/medical/bloodpacks
+ name = "Blood Pack Variety Crate"
+ desc = "Contains ten different blood packs for reintroducing blood to patients."
+ cost = 3000
+ contains = list(/obj/item/reagent_containers/blood/random,
+ /obj/item/reagent_containers/blood/random,
+ /obj/item/reagent_containers/blood/APlus,
+ /obj/item/reagent_containers/blood/AMinus,
+ /obj/item/reagent_containers/blood/BPlus,
+ /obj/item/reagent_containers/blood/BMinus,
+ /obj/item/reagent_containers/blood/OPlus,
+ /obj/item/reagent_containers/blood/OMinus,
+ /obj/item/reagent_containers/blood/lizard,
+ /obj/item/reagent_containers/blood/jellyblood,
+ /obj/item/reagent_containers/blood/insect)
+ crate_name = "blood freezer"
+ crate_type = /obj/structure/closet/crate/freezer
+
+/datum/supply_pack/medical/bloodpackssynth
+ name = "Synthetics Blood Pack Crate"
+ desc = "Contains five synthetics blood packs for reintroducing blood to patients."
+ cost = 3000
+ contains = list(/obj/item/reagent_containers/blood/synthetics,
+ /obj/item/reagent_containers/blood/synthetics,
+ /obj/item/reagent_containers/blood/synthetics,
+ /obj/item/reagent_containers/blood/synthetics,
+ /obj/item/reagent_containers/blood/synthetics)
+ crate_name = "blood freezer"
+ crate_type = /obj/structure/closet/crate/freezer
+
+/datum/supply_pack/medical/defibs
+ name = "Defibrillator Crate"
+ desc = "Contains two defibrillators for bringing the recently deceased back to life."
+ cost = 2500
+ contains = list(/obj/item/defibrillator/loaded,
+ /obj/item/defibrillator/loaded)
+ crate_name = "defibrillator crate"
+
+/datum/supply_pack/medical/firstaid
+ name = "First Aid Kit Crate"
+ desc = "Contains four first aid kits for healing most types of wounds."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/regular,
+ /obj/item/storage/firstaid/regular,
+ /obj/item/storage/firstaid/regular,
+ /obj/item/storage/firstaid/regular)
+ crate_name = "first aid kit crate"
+
+/datum/supply_pack/medical/iv_drip
+ name = "IV Drip Crate"
+ desc = "Contains a single IV drip stand for intravenous delivery."
+ cost = 800
+ contains = list(/obj/machinery/iv_drip)
+ crate_name = "iv drip crate"
+
+/datum/supply_pack/science/adv_surgery_tools
+ name = "Med-Co Advanced surgery tools"
+ desc = "A full set of Med-Co advanced surgery tools, this crate also comes with a spay of synth flesh as well as a can of . Requires Surgery access to open."
+ cost = 5500
+ access = ACCESS_SURGERY
+ contains = list(/obj/item/storage/belt/medical/surgery_belt_adv,
+ /obj/item/reagent_containers/medspray/synthflesh,
+ /obj/item/reagent_containers/medspray/sterilizine)
+ crate_name = "medco newest surgery tools"
+ crate_type = /obj/structure/closet/crate/medical
+
+/datum/supply_pack/medical/medicalhardsuit
+ name = "Medical Hardsuit"
+ desc = "Got people being spaced left and right? Hole in the same room as the dead body of Hos or cap? Fear not, now you can buy one medical hardsuit with a mask and air tank to save your fellow crewmembers."
+ cost = 2750
+ contains = list(/obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/suit/space/hardsuit/medical)
+ crate_name = "medical hardsuit"
+
+/datum/supply_pack/medical/supplies
+ name = "Medical Supplies Crate"
+ desc = "Contains seven beakers, syringes, and bodybags. Three morphine bottles, four insulin pills. Two charcoal bottles, epinephrine bottles, antitoxin bottles, and large beakers. Finally, a single roll of medical gauze, as well as a bottle of stimulant pills for long, hard work days. German doctor not included."
+ cost = 2500
+ contains = list(/obj/item/reagent_containers/glass/bottle/charcoal,
+ /obj/item/reagent_containers/glass/bottle/charcoal,
+ /obj/item/reagent_containers/glass/bottle/epinephrine,
+ /obj/item/reagent_containers/glass/bottle/epinephrine,
+ /obj/item/reagent_containers/glass/bottle/morphine,
+ /obj/item/reagent_containers/glass/bottle/morphine,
+ /obj/item/reagent_containers/glass/bottle/morphine,
+ /obj/item/reagent_containers/glass/bottle/toxin,
+ /obj/item/reagent_containers/glass/bottle/toxin,
+ /obj/item/reagent_containers/glass/beaker/large,
+ /obj/item/reagent_containers/glass/beaker/large,
+ /obj/item/reagent_containers/pill/insulin,
+ /obj/item/reagent_containers/pill/insulin,
+ /obj/item/reagent_containers/pill/insulin,
+ /obj/item/reagent_containers/pill/insulin,
+ /obj/item/stack/medical/gauze,
+ /obj/item/storage/box/beakers,
+ /obj/item/storage/box/medsprays,
+ /obj/item/storage/box/syringes,
+ /obj/item/storage/box/bodybags,
+ /obj/item/storage/pill_bottle/stimulant)
+ crate_name = "medical supplies crate"
+
+/datum/supply_pack/medical/vending
+ name = "Medical Vending Crate"
+ desc = "Contains refills for medical vending machines."
+ cost = 2000
+ contains = list(/obj/item/vending_refill/medical,
+ /obj/item/vending_refill/wallmed)
+ crate_name = "medical vending crate"
+
+/datum/supply_pack/medical/sprays
+ name = "Medical Sprays"
+ desc = "Contains two cans of Styptic Spray, Silver Sulfadiazine Spray, Synthflesh Spray and Sterilizer Compound Spray."
+ cost = 2250
+ contains = list(/obj/item/reagent_containers/medspray/styptic,
+ /obj/item/reagent_containers/medspray/styptic,
+ /obj/item/reagent_containers/medspray/silver_sulf,
+ /obj/item/reagent_containers/medspray/silver_sulf,
+ /obj/item/reagent_containers/medspray/synthflesh,
+ /obj/item/reagent_containers/medspray/synthflesh,
+ /obj/item/reagent_containers/medspray/sterilizine,
+ /obj/item/reagent_containers/medspray/sterilizine)
+ crate_name = "medical supplies crate"
+
+/datum/supply_pack/medical/firstaidmixed
+ name = "Mixed Medical Kits"
+ desc = "Contains one of each medical kits for dealing with a variety of injured crewmembers."
+ cost = 1250
+ contains = list(/obj/item/storage/firstaid/toxin,
+ /obj/item/storage/firstaid/o2,
+ /obj/item/storage/firstaid/brute,
+ /obj/item/storage/firstaid/fire,
+ /obj/item/storage/firstaid/regular)
+ crate_name = "medical supplies crate"
+
+/datum/supply_pack/medical/firstaidoxygen
+ name = "Oxygen Deprivation Kit Crate"
+ desc = "Contains three first aid kits focused on helping oxygen deprivation victims."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/o2,
+ /obj/item/storage/firstaid/o2,
+ /obj/item/storage/firstaid/o2)
+ crate_name = "oxygen deprivation kit crate"
+
+/datum/supply_pack/medical/advrad
+ name = "Radiation Treatment Crate Deluxe"
+ desc = "A crate for when radiation is out of hand... Contains two rad-b-gone kits, one bottle of anti radiation deluxe pill bottle, as well as a radiation treatment deluxe pill bottle!"
+ cost = 3500
+ contains = list(/obj/item/storage/pill_bottle/antirad_plus,
+ /obj/item/storage/pill_bottle/mutarad,
+ /obj/item/storage/firstaid/radbgone,
+ /obj/item/storage/firstaid/radbgone,
+ /obj/item/geiger_counter,
+ /obj/item/geiger_counter)
+ crate_name = "radiation protection crate"
+ crate_type = /obj/structure/closet/crate/radiation
+
+/datum/supply_pack/medical/surgery
+ name = "Surgical Supplies Crate"
+ desc = "Do you want to perform surgery, but don't have one of those fancy shmancy degrees? Just get started with this crate containing a medical duffelbag, Sterilizine spray and collapsible roller bed."
+ cost = 1300
+ contains = list(/obj/item/storage/backpack/duffelbag/med/surgery,
+ /obj/item/reagent_containers/medspray/sterilizine,
+ /obj/item/roller)
+ crate_name = "surgical supplies crate"
+
+/datum/supply_pack/medical/firstaidtoxins
+ name = "Toxin Treatment Kit Crate"
+ desc = "Contains three first aid kits focused on healing damage dealt by heavy toxins."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/toxin,
+ /obj/item/storage/firstaid/toxin,
+ /obj/item/storage/firstaid/toxin)
+ crate_name = "toxin treatment kit crate"
+
+/datum/supply_pack/medical/virus
+ name = "Virus Crate"
+ desc = "Contains twelve different bottles, containing several viral samples for virology research. Also includes seven beakers and syringes. Balled-up jeans not included. Requires CMO access to open."
+ cost = 2500
+ access = ACCESS_CMO
+ contains = list(/obj/item/reagent_containers/glass/bottle/flu_virion,
+ /obj/item/reagent_containers/glass/bottle/cold,
+ /obj/item/reagent_containers/glass/bottle/random_virus,
+ /obj/item/reagent_containers/glass/bottle/random_virus,
+ /obj/item/reagent_containers/glass/bottle/random_virus,
+ /obj/item/reagent_containers/glass/bottle/random_virus,
+ /obj/item/reagent_containers/glass/bottle/fake_gbs,
+ /obj/item/reagent_containers/glass/bottle/magnitis,
+ /obj/item/reagent_containers/glass/bottle/pierrot_throat,
+ /obj/item/reagent_containers/glass/bottle/brainrot,
+ /obj/item/reagent_containers/glass/bottle/anxiety,
+ /obj/item/reagent_containers/glass/bottle/beesease,
+ /obj/item/storage/box/syringes,
+ /obj/item/storage/box/beakers,
+ /obj/item/reagent_containers/glass/bottle/mutagen)
+ crate_name = "virus crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+ dangerous = TRUE
diff --git a/code/modules/cargo/packs/misc.dm b/code/modules/cargo/packs/misc.dm
new file mode 100644
index 0000000000..c380d5411e
--- /dev/null
+++ b/code/modules/cargo/packs/misc.dm
@@ -0,0 +1,230 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Miscellaneous ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/misc
+ group = "Miscellaneous Supplies"
+
+/datum/supply_pack/misc/artsupply
+ name = "Art Supplies"
+ desc = "Make some happy little accidents with six canvasses, two easels, two boxes of crayons, and a rainbow crayon!"
+ cost = 800
+ contains = list(/obj/structure/easel,
+ /obj/structure/easel,
+ /obj/item/canvas/nineteenXnineteen,
+ /obj/item/canvas/nineteenXnineteen,
+ /obj/item/canvas/twentythreeXnineteen,
+ /obj/item/canvas/twentythreeXnineteen,
+ /obj/item/canvas/twentythreeXtwentythree,
+ /obj/item/canvas/twentythreeXtwentythree,
+ /obj/item/storage/crayons,
+ /obj/item/storage/crayons,
+ /obj/item/toy/crayon/rainbow,
+ /obj/item/toy/crayon/white,
+ /obj/item/toy/crayon/white)
+ crate_name = "art supply crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/misc/captain_pen
+ name = "Captain Pen"
+ desc = "A spare Captain fountain pen."
+ access = ACCESS_CAPTAIN
+ cost = 10000
+ contains = list(/obj/item/pen/fountain/captain)
+ crate_name = "captain pen"
+ crate_type = /obj/structure/closet/crate/secure/weapon //It is a combat pen
+
+/datum/supply_pack/misc/bicycle
+ name = "Bicycle"
+ desc = "Nanotrasen reminds all employees to never toy with powers outside their control."
+ cost = 1000000
+ contains = list(/obj/vehicle/ridden/bicycle)
+ crate_name = "Bicycle Crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/misc/bigband
+ name = "Big Band Instrument Collection"
+ desc = "Get your sad station movin' and groovin' with this fine collection! Contains nine different instruments!"
+ cost = 5000
+ crate_name = "Big band musical instruments collection"
+ contains = list(/obj/item/instrument/violin,
+ /obj/item/instrument/guitar,
+ /obj/item/instrument/glockenspiel,
+ /obj/item/instrument/accordion,
+ /obj/item/instrument/saxophone,
+ /obj/item/instrument/trombone,
+ /obj/item/instrument/recorder,
+ /obj/item/instrument/harmonica,
+ /obj/structure/piano/unanchored)
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/misc/book_crate
+ name = "Book Crate"
+ desc = "Surplus from the Nanotrasen Archives, these five books are sure to be good reads."
+ cost = 1500
+ contains = list(/obj/item/book/codex_gigas,
+ /obj/item/book/manual/random/,
+ /obj/item/book/manual/random/,
+ /obj/item/book/manual/random/,
+ /obj/item/book/random/triple)
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/misc/paper
+ name = "Bureaucracy Crate"
+ desc = "High stacks of papers on your desk Are a big problem - make it Pea-sized with these bureaucratic supplies! Contains five pens, some camera film, hand labeler supplies, a paper bin, three folders, two clipboards and two stamps as well as a briefcase."//that was too forced
+ cost = 1500
+ contains = list(/obj/structure/filingcabinet/chestdrawer/wheeled,
+ /obj/item/camera_film,
+ /obj/item/hand_labeler,
+ /obj/item/hand_labeler_refill,
+ /obj/item/hand_labeler_refill,
+ /obj/item/paper_bin,
+ /obj/item/pen/fourcolor,
+ /obj/item/pen/fourcolor,
+ /obj/item/pen,
+ /obj/item/pen/blue,
+ /obj/item/pen/red,
+ /obj/item/folder/blue,
+ /obj/item/folder/red,
+ /obj/item/folder/yellow,
+ /obj/item/clipboard,
+ /obj/item/clipboard,
+ /obj/item/stamp,
+ /obj/item/stamp/denied,
+ /obj/item/storage/briefcase)
+ crate_name = "bureaucracy crate"
+
+/datum/supply_pack/misc/fountainpens
+ name = "Calligraphy Crate"
+ desc = "Sign death warrants in style with these seven executive fountain pens."
+ cost = 730
+ contains = list(/obj/item/storage/box/fountainpens,
+ /obj/item/paper_bin)
+ crate_type = /obj/structure/closet/crate/wooden
+ crate_name = "calligraphy crate"
+
+/datum/supply_pack/misc/wrapping_paper
+ name = "Festive Wrapping Paper Crate"
+ desc = "Want to mail your loved ones gift-wrapped chocolates, stuffed animals, the Clown's severed head? You can do all that, with this crate full of wrapping paper."
+ cost = 1000
+ contains = list(/obj/item/stack/wrapping_paper)
+ crate_type = /obj/structure/closet/crate/wooden
+ crate_name = "festive wrapping paper crate"
+
+/datum/supply_pack/misc/paper_work
+ name = "Freelance Paper work"
+ desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (20) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up.
+ cost = 700 // Net of 0 credits but makes (120 x 20 = 2400)
+ contains = list(/obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/pen/fountain
+ )
+ crate_name = "Paperwork"
+
+/datum/supply_pack/misc/funeral
+ name = "Funeral Supply crate"
+ desc = "At the end of the day, someone's gonna want someone dead. Give them a proper send-off with these funeral supplies! Contains a coffin with burial garmets and flowers."
+ cost = 800
+ contains = list(/obj/item/clothing/under/burial,
+ /obj/item/reagent_containers/food/snacks/grown/harebell,
+ /obj/item/reagent_containers/food/snacks/grown/poppy/geranium
+ )
+ crate_name = "coffin"
+ crate_type = /obj/structure/closet/crate/coffin
+
+/datum/supply_pack/misc/jukebox
+ name = "Jukebox"
+ cost = 10000
+ contains = list(/obj/machinery/jukebox)
+ crate_name = "Jukebox"
+
+/datum/supply_pack/misc/lewd
+ name = "Lewd Crate" // OwO
+ desc = "Psss want to have a good time with your sluts? Well I got what you want maid clothing, dildos, collars and more!"
+ cost = 5250
+ contraband = TRUE
+ contains = list(/obj/item/dildo/custom,
+ /obj/item/dildo/custom,
+ /obj/item/vending_refill/kink,
+ /obj/item/vending_refill/kink,
+ /obj/item/clothing/under/maid,
+ /obj/item/clothing/under/maid,
+ /obj/item/electropack/shockcollar,
+ /obj/item/electropack/shockcollar,
+ /obj/item/restraints/handcuffs/fake/kinky,
+ /obj/item/restraints/handcuffs/fake/kinky,
+ /obj/item/clothing/head/kitty/genuine, // Why its illegal
+ /obj/item/clothing/head/kitty/genuine,
+ /obj/item/storage/pill_bottle/penis_enlargement,
+ /obj/structure/reagent_dispensers/keg/aphro)
+ crate_name = "lewd kit"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/misc/lewdkeg
+ name = "Lewd Deluxe Keg"
+ desc = "That other stuff not getting you ready? Well I have a Chemslut making tons of the good stuff."
+ cost = 7500 //It can be a weapon
+ contraband = TRUE
+ contains = list(/obj/structure/reagent_dispensers/keg/aphro/strong)
+ crate_name = "deluxe keg"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/misc/religious_supplies
+ name = "Religious Supplies Crate"
+ desc = "Keep your local chaplain happy and well-supplied, lest they call down judgement upon your cargo bay. Contains two bottles of holywater, bibles, chaplain robes, and burial garmets."
+ cost = 4000 // it costs so much because the Space Church is ran by Space Jews
+ contains = list(/obj/item/reagent_containers/food/drinks/bottle/holywater,
+ /obj/item/reagent_containers/food/drinks/bottle/holywater,
+ /obj/item/storage/book/bible/booze,
+ /obj/item/storage/book/bible/booze,
+ /obj/item/clothing/suit/hooded/chaplain_hoodie,
+ /obj/item/clothing/suit/hooded/chaplain_hoodie
+ )
+ crate_name = "religious supplies crate"
+
+/datum/supply_pack/misc/randomised/promiscuous
+ name = "Promiscuous Organs"
+ desc = "Do YOU want to have more genital? Well we have just the thing for you~. This crate has two autosurgeon, that will let you have a new sex, organ to impress that hot stud and or chick."
+ cost = 4000 //Only get 2!
+ contraband = TRUE
+ var/num_contained = 2
+ contains = list(/obj/item/autosurgeon/penis,
+ /obj/item/autosurgeon/testicles,
+ /obj/item/autosurgeon/vagina,
+ /obj/item/autosurgeon/breasts,
+ /obj/item/autosurgeon/womb)
+ crate_name = "promiscuous organs"
+
+/datum/supply_pack/misc/toner
+ name = "Toner Crate"
+ desc = "Spent too much ink printing butt pictures? Fret not, with these six toner refills, you'll be printing butts 'till the cows come home!'"
+ cost = 1000
+ contains = list(/obj/item/toner,
+ /obj/item/toner,
+ /obj/item/toner,
+ /obj/item/toner,
+ /obj/item/toner,
+ /obj/item/toner)
+ crate_name = "toner crate"
diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm
new file mode 100644
index 0000000000..2b5df207c3
--- /dev/null
+++ b/code/modules/cargo/packs/organic.dm
@@ -0,0 +1,290 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Organic /////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/organic
+ group = "Food & Hydroponics"
+ crate_type = /obj/structure/closet/crate/freezer
+
+/datum/supply_pack/organic/hydroponics/beekeeping_suits
+ name = "Beekeeper Suit Crate"
+ desc = "Bee business booming? Better be benevolent and boost botany by bestowing bi-Beekeeper-suits! Contains two beekeeper suits and matching headwear."
+ cost = 1300
+ contains = list(/obj/item/clothing/head/beekeeper_head,
+ /obj/item/clothing/suit/beekeeper_suit,
+ /obj/item/clothing/head/beekeeper_head,
+ /obj/item/clothing/suit/beekeeper_suit)
+ crate_name = "beekeeper suits"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/hydroponics/beekeeping_fullkit
+ name = "Beekeeping Starter Crate"
+ desc = "BEES BEES BEES. Contains three honey frames, a beekeeper suit and helmet, flyswatter, bee house, and, of course, a pure-bred Nanotrasen-Standardized Queen Bee!"
+ cost = 1800
+ contains = list(/obj/structure/beebox/unwrenched,
+ /obj/item/honey_frame,
+ /obj/item/honey_frame,
+ /obj/item/honey_frame,
+ /obj/item/queen_bee/bought,
+ /obj/item/clothing/head/beekeeper_head,
+ /obj/item/clothing/suit/beekeeper_suit,
+ /obj/item/melee/flyswatter)
+ crate_name = "beekeeping starter crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/candy/randomised
+ name = "Candy Crate"
+ desc = "For people that have a insatiable sweet tooth! Has ten candies to be eaten up.."
+ cost = 2500
+ var/num_contained = 10 //number of items picked to be contained in a randomised crate
+ contains = list(/obj/item/reagent_containers/food/snacks/candy,
+ /obj/item/reagent_containers/food/snacks/lollipop,
+ /obj/item/reagent_containers/food/snacks/gumball,
+ /obj/item/reagent_containers/food/snacks/chocolateegg,
+ /obj/item/reagent_containers/food/snacks/donut,
+ /obj/item/reagent_containers/food/snacks/cookie,
+ /obj/item/reagent_containers/food/snacks/sugarcookie,
+ /obj/item/reagent_containers/food/snacks/chococornet,
+ /obj/item/reagent_containers/food/snacks/mint,
+ /obj/item/reagent_containers/food/snacks/spiderlollipop,
+ /obj/item/reagent_containers/food/snacks/chococoin,
+ /obj/item/reagent_containers/food/snacks/fudgedice,
+ /obj/item/reagent_containers/food/snacks/chocoorange,
+ /obj/item/reagent_containers/food/snacks/honeybar,
+ /obj/item/reagent_containers/food/snacks/tinychocolate,
+ /obj/item/reagent_containers/food/snacks/spacetwinkie,
+ /obj/item/reagent_containers/food/snacks/syndicake,
+ /obj/item/reagent_containers/food/snacks/cheesiehonkers,
+ /obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull,
+ /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin,
+ /obj/item/reagent_containers/food/snacks/candy_corn,
+ /obj/item/reagent_containers/food/snacks/candiedapple,
+ /obj/item/reagent_containers/food/snacks/chocolatebar,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/storage/fancy/heart_box,
+ /obj/item/storage/fancy/donut_box)
+ crate_name = "candy crate"
+
+/datum/supply_pack/organic/cutlery
+ name = "Kitchen Cutlery Deluxe Set"
+ desc = "Need to slice and dice away those ''Tomatos'' well we got what you need! From a nice set of knifes, forks, plates, glasses, and a whetstone for when you got some grizzle that is a bit harder to slice then normal."
+ cost = 10000
+ contraband = TRUE
+ contains = list(/obj/item/sharpener,
+ /obj/item/kitchen/fork,
+ /obj/item/kitchen/fork,
+ /obj/item/kitchen/knife,
+ /obj/item/kitchen/knife,
+ /obj/item/kitchen/knife,
+ /obj/item/kitchen/knife,
+ /obj/item/kitchen/knife/butcher,
+ /obj/item/kitchen/knife/butcher,
+ /obj/item/kitchen/rollingpin, //Deluxe for a reason
+ /obj/item/trash/plate,
+ /obj/item/trash/plate,
+ /obj/item/trash/plate,
+ /obj/item/trash/plate,
+ /obj/item/reagent_containers/food/drinks/drinkingglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
+ crate_name = "kitchen cutlery deluxe set"
+
+/datum/supply_pack/organic/food
+ name = "Food Crate"
+ desc = "Get things cooking with this crate full of useful ingredients! Contains a two dozen eggs, three bananas, and two bags of flour and rice, two cartons of milk, soymilk, as well as salt and pepper shakers, a enzyme and sugar bottle, and three slabs of monkeymeat."
+ cost = 1000
+ contains = list(/obj/item/reagent_containers/food/condiment/flour,
+ /obj/item/reagent_containers/food/condiment/flour,
+ /obj/item/reagent_containers/food/condiment/rice,
+ /obj/item/reagent_containers/food/condiment/rice,
+ /obj/item/reagent_containers/food/condiment/milk,
+ /obj/item/reagent_containers/food/condiment/milk,
+ /obj/item/reagent_containers/food/condiment/soymilk,
+ /obj/item/reagent_containers/food/condiment/saltshaker,
+ /obj/item/reagent_containers/food/condiment/peppermill,
+ /obj/item/storage/fancy/egg_box,
+ /obj/item/storage/fancy/egg_box,
+ /obj/item/reagent_containers/food/condiment/enzyme,
+ /obj/item/reagent_containers/food/condiment/sugar,
+ /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
+ /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
+ /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
+ /obj/item/reagent_containers/food/snacks/grown/banana,
+ /obj/item/reagent_containers/food/snacks/grown/banana,
+ /obj/item/reagent_containers/food/snacks/grown/banana)
+ crate_name = "food crate"
+
+/datum/supply_pack/organic/cream_piee
+ name = "High-yield Clown-grade Cream Pie Crate"
+ desc = "Designed by Aussec's Advanced Warfare Research Division, these high-yield, Clown-grade cream pies are powered by a synergy of performance and efficiency. Guaranteed to provide maximum results."
+ cost = 6000
+ contains = list(/obj/item/storage/backpack/duffelbag/clown/cream_pie)
+ crate_name = "party equipment crate"
+ contraband = TRUE
+ access = ACCESS_THEATRE
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/organic/hunting
+ name = "Huntting gear"
+ desc = "Even in space, we can fine prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a huntting shotgun. "
+ cost = 3500
+ contraband = TRUE
+ contains = list(/obj/item/clothing/head/flatcap,
+ /obj/item/clothing/suit/hooded/wintercoat/captain,
+ /obj/item/reagent_containers/food/drinks/bottle/cognac,
+ /obj/item/storage/fancy/cigarettes/cigars/havana,
+ /obj/item/clothing/gloves/color/white,
+ /obj/item/clothing/under/rank/curator,
+ /obj/item/gun/ballistic/shotgun/lethal)
+ access = ACCESS_ARMORY
+ crate_name = "sporting crate"
+ crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:(
+
+/datum/supply_pack/organic/hydroponics
+ name = "Hydroponics Crate"
+ desc = "Supplies for growing a great garden! Contains two bottles of ammonia, two Plant-B-Gone spray bottles, a hatchet, cultivator, plant analyzer, as well as a pair of leather gloves and a botanist's apron."
+ cost = 1750
+ contains = list(/obj/item/reagent_containers/spray/plantbgone,
+ /obj/item/reagent_containers/spray/plantbgone,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/hatchet,
+ /obj/item/cultivator,
+ /obj/item/plant_analyzer,
+ /obj/item/clothing/gloves/botanic_leather,
+ /obj/item/clothing/suit/apron)
+ crate_name = "hydroponics crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/hydroponics/hydrotank
+ name = "Hydroponics Backpack Crate"
+ desc = "Bring on the flood with this high-capacity backpack crate. Contains 500 units of life-giving H2O. Requires hydroponics access to open."
+ cost = 1200
+ access = ACCESS_HYDROPONICS
+ contains = list(/obj/item/watertank)
+ crate_name = "hydroponics backpack crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/organic/mre
+ name = "MRE supply kit (emergency rations)"
+ desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank."
+ cost = 2000
+ contains = list(/obj/item/storage/box/mre/menu1/safe,
+ /obj/item/storage/box/mre/menu1/safe,
+ /obj/item/storage/box/mre/menu2/safe,
+ /obj/item/storage/box/mre/menu2/safe,
+ /obj/item/storage/box/mre/menu3,
+ /obj/item/storage/box/mre/menu4/safe)
+ crate_name = "MRE crate (emergency rations)"
+
+/datum/supply_pack/organic/pizza
+ name = "Pizza Crate"
+ desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!"
+ cost = 6000 // Best prices this side of the galaxy.
+ contains = list(/obj/item/pizzabox/margherita,
+ /obj/item/pizzabox/mushroom,
+ /obj/item/pizzabox/meat,
+ /obj/item/pizzabox/vegetable,
+ /obj/item/pizzabox/pineapple)
+ crate_name = "pizza crate"
+ var/static/anomalous_box_provided = FALSE
+
+/datum/supply_pack/organic/pizza/fill(obj/structure/closet/crate/C)
+ . = ..()
+ if(!anomalous_box_provided)
+ for(var/obj/item/pizzabox/P in C)
+ if(prob(1)) //1% chance for each box, so 4% total chance per order
+ var/obj/item/pizzabox/infinite/fourfiveeight = new(C)
+ fourfiveeight.boxtag = P.boxtag
+ qdel(P)
+ anomalous_box_provided = TRUE
+ log_game("An anomalous pizza box was provided in a pizza crate at during cargo delivery")
+ if(prob(50))
+ addtimer(CALLBACK(src, .proc/anomalous_pizza_report), rand(300, 1800))
+ else
+ message_admins("An anomalous pizza box was silently created with no command report in a pizza crate delivery.")
+ break
+
+/datum/supply_pack/organic/pizza/proc/anomalous_pizza_report()
+ print_command_report("[station_name()], our anomalous materials divison has reported a missing object that is highly likely to have been sent to your station during a routine cargo \
+ delivery. Please search all crates and manifests provided with the delivery and return the object if is located. The object resembles a standard \[DATA EXPUNGED\] and is to be \
+ considered \[REDACTED\] and returned at your leisure. Note that objects the anomaly produces are specifically attuned exactly to the individual opening the anomaly; regardless \
+ of species, the individual will find the object edible and it will taste great according to their personal definitions, which vary significantly based on person and species.")
+
+/datum/supply_pack/organic/potted_plants
+ name = "Potted Plants Crate"
+ desc = "Spruce up the station with these lovely plants! Contains a random assortment of five potted plants from Nanotrasen's potted plant research division. Warranty void if thrown."
+ cost = 730
+ contains = list(/obj/item/twohanded/required/kirbyplants/random,
+ /obj/item/twohanded/required/kirbyplants/random,
+ /obj/item/twohanded/required/kirbyplants/random,
+ /obj/item/twohanded/required/kirbyplants/random,
+ /obj/item/twohanded/required/kirbyplants/random)
+ crate_name = "potted plants crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/seeds
+ name = "Seeds Crate"
+ desc = "Big things have small beginnings. Contains thirteen different seeds."
+ cost = 1250
+ contains = list(/obj/item/seeds/chili,
+ /obj/item/seeds/berry,
+ /obj/item/seeds/corn,
+ /obj/item/seeds/eggplant,
+ /obj/item/seeds/tomato,
+ /obj/item/seeds/soya,
+ /obj/item/seeds/wheat,
+ /obj/item/seeds/wheat/rice,
+ /obj/item/seeds/carrot,
+ /obj/item/seeds/sunflower,
+ /obj/item/seeds/chanter,
+ /obj/item/seeds/potato,
+ /obj/item/seeds/sugarcane)
+ crate_name = "seeds crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/vday
+ name = "Surplus Valentine Crate"
+ desc = "Turns out we got warehouses of this love-y dove-y crap. Were sending out small barged buddle of Valentine gear. This crate has two boxes of chocolate, three poppy flowers, five candy hearts, and three cards."
+ cost = 3000
+ contraband = TRUE
+ contains = list(/obj/item/storage/fancy/heart_box,
+ /obj/item/storage/fancy/heart_box,
+ /obj/item/reagent_containers/food/snacks/grown/poppy,
+ /obj/item/reagent_containers/food/snacks/grown/poppy,
+ /obj/item/reagent_containers/food/snacks/grown/poppy,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/valentine,
+ /obj/item/valentine,
+ /obj/item/valentine)
+ crate_name = "valentine crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/organic/exoticseeds
+ name = "Exotic Seeds Crate"
+ desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!"
+ cost = 1500
+ contains = list(/obj/item/seeds/nettle,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/plump,
+ /obj/item/seeds/liberty,
+ /obj/item/seeds/amanita,
+ /obj/item/seeds/reishi,
+ /obj/item/seeds/banana,
+ /obj/item/seeds/eggplant/eggy,
+ /obj/item/seeds/random,
+ /obj/item/seeds/random)
+ crate_name = "exotic seeds crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
diff --git a/code/modules/cargo/packs/science.dm b/code/modules/cargo/packs/science.dm
new file mode 100644
index 0000000000..c4fbc0bfe5
--- /dev/null
+++ b/code/modules/cargo/packs/science.dm
@@ -0,0 +1,119 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Science /////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/science
+ group = "Science"
+ crate_type = /obj/structure/closet/crate/science
+
+/datum/supply_pack/science/robotics/mecha_odysseus
+ name = "Circuit Crate (Odysseus)"
+ desc = "Ever wanted to build your own giant medical robot? Well, now you can! Contains the Odysseus main control board and Odysseus peripherals board. Requires Robotics access to open."
+ cost = 2500
+ access = ACCESS_ROBOTICS
+ contains = list(/obj/item/circuitboard/mecha/odysseus/peripherals,
+ /obj/item/circuitboard/mecha/odysseus/main)
+ crate_name = "\improper Odysseus circuit crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/science/robotics/mecha_ripley
+ name = "Circuit Crate (Ripley APLU)"
+ desc = "Rip apart rocks and xenomorphs alike with the Ripley APLU. Contains the Main Ripley control board, as well as the Ripley Peripherals board. Requires Robotics access to open."
+ cost = 3000
+ access = ACCESS_ROBOTICS
+ contains = list(/obj/item/book/manual/ripley_build_and_repair,
+ /obj/item/circuitboard/mecha/ripley/main,
+ /obj/item/circuitboard/mecha/ripley/peripherals)
+ crate_name = "\improper APLU Ripley circuit crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/science/circuitry
+ name = "Circuitry Starter Pack Crate"
+ desc = "Journey into the mysterious world of Circuitry with this starter pack. Contains a circuit printer, analyzer, debugger and wirer. Power cells not included."
+ cost = 1000
+ contains = list(/obj/item/integrated_electronics/analyzer,
+ /obj/item/integrated_circuit_printer,
+ /obj/item/integrated_electronics/debugger,
+ /obj/item/integrated_electronics/wirer)
+ crate_name = "circuitry starter pack crate"
+
+/datum/supply_pack/science/plasma
+ name = "Plasma Assembly Crate"
+ desc = "Everything you need to burn something to the ground, this contains three plasma assembly sets. Each set contains a plasma tank, igniter, proximity sensor, and timer! Warranty void if exposed to high temperatures. Requires Toxins access to open."
+ cost = 1800
+ access = ACCESS_TOX_STORAGE
+ contains = list(/obj/item/tank/internals/plasma,
+ /obj/item/tank/internals/plasma,
+ /obj/item/tank/internals/plasma,
+ /obj/item/assembly/igniter,
+ /obj/item/assembly/igniter,
+ /obj/item/assembly/igniter,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/assembly/timer,
+ /obj/item/assembly/timer,
+ /obj/item/assembly/timer)
+ crate_name = "plasma assembly crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+
+/datum/supply_pack/science/robotics
+ name = "Robotics Assembly Crate"
+ desc = "The tools you need to replace those finicky humans with a loyal robot army! Contains three proximity sensors, two high-powered cells, six flashes, and an electrical toolbox. Requires Robotics access to open."
+ cost = 1500
+ access = ACCESS_ROBOTICS
+ contains = list(/obj/item/assembly/prox_sensor,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/storage/toolbox/electrical,
+ /obj/item/storage/box/flashes,
+ /obj/item/stock_parts/cell/high,
+ /obj/item/stock_parts/cell/high)
+ crate_name = "robotics assembly crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/science/shieldwalls
+ name = "Shield Generator Crate"
+ desc = "These high powered Shield Wall Generators are guaranteed to keep any unwanted lifeforms on the outside, where they belong! Contains four shield wall generators. Requires Teleporter access to open."
+ cost = 2000
+ access = ACCESS_TELEPORTER
+ contains = list(/obj/machinery/shieldwallgen,
+ /obj/machinery/shieldwallgen,
+ /obj/machinery/shieldwallgen,
+ /obj/machinery/shieldwallgen)
+ crate_name = "shield generators crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/science/tablets
+ name = "Tablet Crate"
+ desc = "What's a computer? Contains five cargo tablets."
+ cost = 5000
+ contains = list(/obj/item/modular_computer/tablet/preset/cargo,
+ /obj/item/modular_computer/tablet/preset/cargo,
+ /obj/item/modular_computer/tablet/preset/cargo,
+ /obj/item/modular_computer/tablet/preset/cargo,
+ /obj/item/modular_computer/tablet/preset/cargo)
+ crate_name = "tablet crate"
+
+/datum/supply_pack/science/transfer_valves
+ name = "Tank Transfer Valves Crate"
+ desc = "The key ingredient for making a lot of people very angry very fast. Contains two tank transfer valves. Requires RD access to open."
+ cost = 6000
+ access = ACCESS_RD
+ contains = list(/obj/item/transfer_valve,
+ /obj/item/transfer_valve)
+ crate_name = "tank transfer valves crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+ dangerous = TRUE
+
+/datum/supply_pack/science/tech_slugs
+ name = "Tech Slug Ammo Shells"
+ desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all."
+ cost = 1700
+ contains = list(/obj/item/storage/box/techsslug,
+ /obj/item/storage/box/techsslug)
+ crate_name = "tech slug crate"
diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm
new file mode 100644
index 0000000000..3c68fe7f6d
--- /dev/null
+++ b/code/modules/cargo/packs/security.dm
@@ -0,0 +1,192 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Security ////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/security
+ group = "Security"
+ access = ACCESS_SECURITY
+ crate_type = /obj/structure/closet/crate/secure/gear
+
+/datum/supply_pack/security/armor
+ name = "Armor Crate"
+ desc = "Three vests of well-rounded, decently-protective armor. Requires Security access to open."
+ cost = 1200
+ contains = list(/obj/item/clothing/suit/armor/vest,
+ /obj/item/clothing/suit/armor/vest,
+ /obj/item/clothing/suit/armor/vest)
+ crate_name = "armor crate"
+
+/datum/supply_pack/security/disabler
+ name = "Disabler Crate"
+ desc = "Three stamina-draining disabler weapons. Requires Security access to open."
+ cost = 1300
+ contains = list(/obj/item/gun/energy/disabler,
+ /obj/item/gun/energy/disabler,
+ /obj/item/gun/energy/disabler)
+ crate_name = "disabler crate"
+
+/datum/supply_pack/security/forensics
+ name = "Forensics Crate"
+ desc = "Stay hot on the criminal's heels with Nanotrasen's Detective Essentials(tm). Contains a forensics scanner, six evidence bags, camera, tape recorder, white crayon, and of course, a fedora. Requires Security access to open."
+ cost = 1800
+ contains = list(/obj/item/detective_scanner,
+ /obj/item/storage/box/evidence,
+ /obj/item/camera,
+ /obj/item/taperecorder,
+ /obj/item/toy/crayon/white,
+ /obj/item/clothing/head/fedora/det_hat)
+ crate_name = "forensics crate"
+
+/datum/supply_pack/security/helmets
+ name = "Helmets Crate"
+ desc = "Contains three standard-issue brain buckets. Requires Security access to open."
+ cost = 1200
+ contains = list(/obj/item/clothing/head/helmet/sec,
+ /obj/item/clothing/head/helmet/sec,
+ /obj/item/clothing/head/helmet/sec)
+ crate_name = "helmet crate"
+
+/datum/supply_pack/security/laser
+ name = "Lasers Crate"
+ desc = "Contains three lethal, high-energy laser guns. Requires Security access to open."
+ cost = 1750
+ contains = list(/obj/item/gun/energy/laser,
+ /obj/item/gun/energy/laser,
+ /obj/item/gun/energy/laser)
+ crate_name = "laser crate"
+
+/datum/supply_pack/security/russianclothing
+ name = "Russian Surplus Clothing"
+ desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!"
+ contraband = TRUE
+ cost = 5750 // Its basicly sec suits, good boots/gloves
+ contains = list(/obj/item/clothing/suit/security/officer/russian,
+ /obj/item/clothing/suit/security/officer/russian,
+ /obj/item/clothing/shoes/combat,
+ /obj/item/clothing/shoes/combat,
+ /obj/item/clothing/head/ushanka,
+ /obj/item/clothing/head/ushanka,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/gloves/combat,
+ /obj/item/clothing/gloves/combat,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas)
+ crate_name = "surplus russian clothing"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/security/russianmosin
+ name = "Russian Minutemen Gear"
+ desc = "An old russian Minutemen crate, comes with a full russian outfit, a mosin and a stripper clip."
+ contraband = TRUE
+ access = FALSE
+ cost = 5500 //
+ contains = list(/obj/item/clothing/suit/security/officer/russian,
+ /obj/item/clothing/shoes/combat,
+ /obj/item/clothing/head/ushanka,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/gloves/combat,
+ /obj/item/clothing/mask/gas,
+ /obj/item/gun/ballistic/shotgun/boltaction,
+ /obj/item/ammo_box/a762)
+ crate_name = "surplus russian gear"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/security/sechardsuit
+ name = "Sec Hardsuit"
+ desc = "One Sec Hardsuit with a small air tank and mask."
+ cost = 3000 // half of SWAT gear for have the armor and half the gear
+ contains = list(/obj/item/clothing/suit/space/hardsuit/security,
+ /obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas)
+ crate_name = "sec hardsuit crate"
+
+/datum/supply_pack/security/securitybarriers
+ name = "Security Barrier Grenades"
+ desc = "Stem the tide with four Security Barrier grenades. Requires Security access to open."
+ contains = list(/obj/item/grenade/barrier,
+ /obj/item/grenade/barrier,
+ /obj/item/grenade/barrier,
+ /obj/item/grenade/barrier)
+ cost = 2000
+ crate_name = "security barriers crate"
+
+/datum/supply_pack/security/securityclothes
+ name = "Security Clothing Crate"
+ desc = "Contains appropriate outfits for the station's private security force. Contains outfits for the Warden, Head of Security, and two Security Officers. Each outfit comes with a rank-appropriate jumpsuit, suit, and beret. Requires Security access to open."
+ cost = 3250
+ contains = list(/obj/item/clothing/under/rank/security/navyblue,
+ /obj/item/clothing/under/rank/security/navyblue,
+ /obj/item/clothing/suit/security/officer,
+ /obj/item/clothing/suit/security/officer,
+ /obj/item/clothing/head/beret/sec/navyofficer,
+ /obj/item/clothing/head/beret/sec/navyofficer,
+ /obj/item/clothing/under/rank/warden/navyblue,
+ /obj/item/clothing/suit/security/warden,
+ /obj/item/clothing/head/beret/sec/navywarden,
+ /obj/item/clothing/under/rank/head_of_security/navyblue,
+ /obj/item/clothing/suit/security/hos,
+ /obj/item/clothing/head/beret/sec/navyhos)
+ crate_name = "security clothing crate"
+
+/datum/supply_pack/security/supplies
+ name = "Security Supplies Crate"
+ desc = "Contains seven flashbangs, seven teargas grenades, six flashes, and seven handcuffs. Requires Security access to open."
+ cost = 1200
+ contains = list(/obj/item/storage/box/flashbangs,
+ /obj/item/storage/box/teargas,
+ /obj/item/storage/box/flashes,
+ /obj/item/storage/box/handcuffs)
+ crate_name = "security supply crate"
+
+/datum/supply_pack/security/firingpins
+ name = "Standard Firing Pins Crate"
+ desc = "Upgrade your arsenal with 10 standard firing pins. Requires Security access to open."
+ cost = 2000
+ contains = list(/obj/item/storage/box/firingpins,
+ /obj/item/storage/box/firingpins)
+ crate_name = "firing pins crate"
+
+/datum/supply_pack/security/justiceinbound
+ name = "Standard Justice Enforcer Crate"
+ desc = "This is it. The Bee's Knees. The Creme of the Crop. The Pick of the Litter. The best of the best of the best. The Crown Jewel of Nanotrasen. The Alpha and the Omega of security headwear. Guaranteed to strike fear into the hearts of each and every criminal aboard the station. Also comes with a security gasmask. Requires Security access to open."
+ cost = 6000 //justice comes at a price. An expensive, noisy price.
+ contraband = TRUE
+ contains = list(/obj/item/clothing/head/helmet/justice,
+ /obj/item/clothing/mask/gas/sechailer)
+ crate_name = "security clothing crate"
+
+/datum/supply_pack/security/baton
+ name = "Stun Batons Crate"
+ desc = "Arm the Civil Protection Forces with three stun batons. Batteries included. Requires Security access to open."
+ cost = 1200
+ contains = list(/obj/item/melee/baton/loaded,
+ /obj/item/melee/baton/loaded,
+ /obj/item/melee/baton/loaded)
+ crate_name = "stun baton crate"
+
+/datum/supply_pack/security/taser
+ name = "Taser Crate"
+ desc = "From the depths of stunbased combat, this order rises above, supreme. Contains three hybrid tasers, capable of firing both electrodes and disabling shots. Requires Security access to open."
+ cost = 3500
+ contains = list(/obj/item/gun/energy/e_gun/advtaser,
+ /obj/item/gun/energy/e_gun/advtaser,
+ /obj/item/gun/energy/e_gun/advtaser)
+ crate_name = "taser crate"
+
+/datum/supply_pack/security/wall_flash
+ name = "Wall-Mounted Flash Crate"
+ desc = "Contains four wall-mounted flashes. Requires Security access to open."
+ cost = 1000
+ contains = list(/obj/item/storage/box/wall_flash,
+ /obj/item/storage/box/wall_flash,
+ /obj/item/storage/box/wall_flash,
+ /obj/item/storage/box/wall_flash)
+ crate_name = "wall-mounted flash crate"
diff --git a/code/modules/cargo/packs/service.dm b/code/modules/cargo/packs/service.dm
new file mode 100644
index 0000000000..14bde519e1
--- /dev/null
+++ b/code/modules/cargo/packs/service.dm
@@ -0,0 +1,266 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// Service //////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/service
+ group = "Service"
+
+/datum/supply_pack/service/advlighting
+ name = "Advanced Lighting crate"
+ desc = "Thanks to advanced lighting tech we here at the Lamp Factory have be able to produce more lamps and lamp items! This crate has three lamps, a box of lights and a state of the art rapid-light-device!"
+ cost = 2750
+ contains = list(/obj/item/construction/rld,
+ /obj/item/flashlight/lamp,
+ /obj/item/flashlight/lamp,
+ /obj/item/flashlight/lamp/green,
+ /obj/item/storage/box/lights/mixed)
+ crate_name = "advanced lighting crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/service/cargo_supples
+ name = "Cargo Supplies Crate"
+ desc = "Sold everything that wasn't bolted down? You can get right back to work with this crate containing stamps, an export scanner, destination tagger, hand labeler and some package wrapping."
+ cost = 1000
+ contains = list(/obj/item/stamp,
+ /obj/item/stamp/denied,
+ /obj/item/export_scanner,
+ /obj/item/destTagger,
+ /obj/item/hand_labeler,
+ /obj/item/stack/packageWrap)
+ crate_name = "cargo supplies crate"
+
+/datum/supply_pack/service/carpet_exotic
+ name = "Exotic Carpet Crate"
+ desc = "Exotic carpets straight from Space Russia, for all your decorating needs. Contains 100 tiles each of 10 different flooring patterns."
+ cost = 7000
+ contains = list(/obj/item/stack/tile/carpet/blue/fifty,
+ /obj/item/stack/tile/carpet/blue/fifty,
+ /obj/item/stack/tile/carpet/cyan/fifty,
+ /obj/item/stack/tile/carpet/cyan/fifty,
+ /obj/item/stack/tile/carpet/green/fifty,
+ /obj/item/stack/tile/carpet/green/fifty,
+ /obj/item/stack/tile/carpet/orange/fifty,
+ /obj/item/stack/tile/carpet/orange/fifty,
+ /obj/item/stack/tile/carpet/purple/fifty,
+ /obj/item/stack/tile/carpet/purple/fifty,
+ /obj/item/stack/tile/carpet/red/fifty,
+ /obj/item/stack/tile/carpet/red/fifty,
+ /obj/item/stack/tile/carpet/royalblue/fifty,
+ /obj/item/stack/tile/carpet/royalblue/fifty,
+ /obj/item/stack/tile/carpet/royalblack/fifty,
+ /obj/item/stack/tile/carpet/royalblack/fifty,
+ /obj/item/stack/tile/carpet/blackred/fifty,
+ /obj/item/stack/tile/carpet/blackred/fifty,
+ /obj/item/stack/tile/carpet/monochrome/fifty,
+ /obj/item/stack/tile/carpet/monochrome/fifty)
+ crate_name = "exotic carpet crate"
+
+/datum/supply_pack/service/food_cart
+ name = "Food Cart Crate"
+ desc = "Want to sell food on the go? Cook lost their cart? Well we just so happen to have a few carts to spare!"
+ cost = 1000
+ contains = list(/obj/machinery/food_cart)
+ crate_name = "food cart crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/service/noslipfloor
+ name = "High-traction Floor Tiles"
+ desc = "Make slipping a thing of the past with sixty industrial-grade anti-slip floortiles!"
+ cost = 2000
+ contains = list(/obj/item/stack/tile/noslip/thirty,
+ /obj/item/stack/tile/noslip/thirty)
+ crate_name = "high-traction floor tiles crate"
+
+/datum/supply_pack/service/icecream_cart
+ name = "Ice Cream Cart Crate"
+ desc = "Plasma fire a to hot for you, want a nice treat after a hard days work? Well now we have the cart for you! This Ice Cream Vat has everthing you need to make you and your friends so ice cream treats! This cart comes stocked with some ingredients for each type of scoopable icecream."
+ cost = 2750 //Comes prestocked with basic ingredients
+ contains = list(/obj/machinery/icecream_vat)
+ crate_name = "ice cream vat crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/service/janitor
+ name = "Janitorial Supplies Crate"
+ desc = "Fight back against dirt and grime with Nanotrasen's Janitorial Essentials(tm)! Contains three buckets, caution signs, and cleaner grenades. Also has a single mop, spray cleaner, rag, NT soap and a trash bag."
+ cost = 1300
+ contains = list(/obj/item/reagent_containers/glass/bucket,
+ /obj/item/reagent_containers/glass/bucket,
+ /obj/item/reagent_containers/glass/bucket,
+ /obj/item/mop,
+ /obj/item/caution,
+ /obj/item/caution,
+ /obj/item/caution,
+ /obj/item/storage/bag/trash,
+ /obj/item/reagent_containers/spray/cleaner,
+ /obj/item/reagent_containers/rag,
+ /obj/item/grenade/chem_grenade/cleaner,
+ /obj/item/grenade/chem_grenade/cleaner,
+ /obj/item/grenade/chem_grenade/cleaner,
+ /obj/item/soap/nanotrasen)
+ crate_name = "janitorial supplies crate"
+
+/datum/supply_pack/service/janitor/janicart
+ name = "Janitorial Cart and Galoshes Crate"
+ desc = "The keystone to any successful janitor. As long as you have feet, this pair of galoshes will keep them firmly planted on the ground. Also contains a janitorial cart."
+ cost = 2000
+ contains = list(/obj/structure/janitorialcart,
+ /obj/item/clothing/shoes/galoshes)
+ crate_name = "janitorial cart crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/service/janitor/janitank
+ name = "Janitor Backpack Crate"
+ desc = "Call forth divine judgement upon dirt and grime with this high capacity janitor backpack. Contains 500 units of station-cleansing cleaner. Requires janitor access to open."
+ cost = 1000
+ access = ACCESS_JANITOR
+ contains = list(/obj/item/watertank/janitor)
+ crate_name = "janitor backpack crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/service/janitor/janpremium
+ name = "Janitor Premium Supplies"
+ desc = "Do to the union for better supplies, we have desided to make a deal for you, In this crate you can get a brand new chem, Drying Angent this stuff is the work of slimes or magic! This crate also contains a rag to test out the Drying Angent magic, three wet floor signs, and some spare bottles of ammonia."
+ cost = 1750
+ access = ACCESS_JANITOR
+ contains = list(/obj/item/caution,
+ /obj/item/caution,
+ /obj/item/caution,
+ /obj/item/reagent_containers/rag,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/reagent_containers/spray/drying_agent)
+ crate_name = "janitor backpack crate"
+
+/datum/supply_pack/service/janitor/janpimp
+ name = "Custodial Cruiser"
+ desc = "Clown steal your ride? Assistant lock it in the dorms? Order a new one and get back to cleaning in style!"
+ cost = 3000
+ access = ACCESS_JANITOR
+ contains = list(/obj/vehicle/ridden/janicart,
+ /obj/item/key/janitor)
+ crate_name = "janitor ride crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/service/mule
+ name = "MULEbot Crate"
+ desc = "Pink-haired Quartermaster not doing her job? Replace her with this tireless worker, today!"
+ cost = 2000
+ contains = list(/mob/living/simple_animal/bot/mulebot)
+ crate_name = "\improper MULEbot Crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/service/party
+ name = "Party Equipment"
+ desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, and a bottle of patron, goldschlager, and shaker!"
+ cost = 2000
+ contains = list(/obj/item/storage/box/drinkingglasses,
+ /obj/item/reagent_containers/food/drinks/shaker,
+ /obj/item/reagent_containers/food/drinks/bottle/patron,
+ /obj/item/reagent_containers/food/drinks/bottle/goldschlager,
+ /obj/item/reagent_containers/food/drinks/ale,
+ /obj/item/reagent_containers/food/drinks/ale,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/flashlight/glowstick,
+ /obj/item/flashlight/glowstick/red,
+ /obj/item/flashlight/glowstick/blue,
+ /obj/item/flashlight/glowstick/cyan,
+ /obj/item/flashlight/glowstick/orange,
+ /obj/item/flashlight/glowstick/yellow,
+ /obj/item/flashlight/glowstick/pink)
+ crate_name = "party equipment crate"
+
+/datum/supply_pack/service/carpet
+ name = "Premium Carpet Crate"
+ desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains the classics."
+ cost = 1000
+ contains = list(/obj/item/stack/tile/carpet/fifty,
+ /obj/item/stack/tile/carpet/fifty,
+ /obj/item/stack/tile/carpet/black/fifty,
+ /obj/item/stack/tile/carpet/black/fifty)
+ crate_name = "premium carpet crate"
+
+/datum/supply_pack/service/carpet2
+ name = "Premium Carpet Crate #2"
+ desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains red, and monochrome"
+ cost = 1000
+ contains = list(/obj/item/stack/tile/carpet/blackred/fifty,
+ /obj/item/stack/tile/carpet/blackred/fifty,
+ /obj/item/stack/tile/carpet/monochrome/fifty,
+ /obj/item/stack/tile/carpet/monochrome/fifty)
+ crate_name = "premium carpet crate #2"
+
+/datum/supply_pack/service/lightbulbs
+ name = "Replacement Lights"
+ desc = "May the light of Aether shine upon this station! Or at least, the light of forty two light tubes and twenty one light bulbs as well as a light replacer."
+ cost = 1200
+ contains = list(/obj/item/storage/box/lights/mixed,
+ /obj/item/storage/box/lights/mixed,
+ /obj/item/storage/box/lights/mixed,
+ /obj/item/lightreplacer)
+ crate_name = "replacement lights"
+
+/datum/supply_pack/service/minerkit
+ name = "Shaft Miner Starter Kit"
+ desc = "All the miners died too fast? Assistant wants to get a taste of life off-station? Either way, this kit is the best way to turn a regular crewman into an ore-producing, monster-slaying machine. Contains meson goggles, a pickaxe, advanced mining scanner, cargo headset, ore bag, gasmask, and explorer suit. Requires QM access to open."
+ cost = 2500
+ access = ACCESS_QM
+ contains = list(/obj/item/pickaxe/mini,
+ /obj/item/clothing/glasses/meson,
+ /obj/item/t_scanner/adv_mining_scanner/lesser,
+ /obj/item/radio/headset/headset_cargo/mining,
+ /obj/item/storage/bag/ore,
+ /obj/item/clothing/suit/hooded/explorer/standard,
+ /obj/item/clothing/mask/gas/explorer)
+ crate_name = "shaft miner starter kit"
+ crate_type = /obj/structure/closet/crate/secure
+
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////// Vending Restocks /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/service/vending/bartending
+ name = "Bartending Supply Crate"
+ desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!"
+ cost = 2000
+ contains = list(/obj/item/vending_refill/boozeomat,
+ /obj/item/vending_refill/coffee,
+ /obj/item/book/granter/action/drink_fling)
+ crate_name = "bartending supply crate"
+
+/datum/supply_pack/service/vending/cigarette
+ name = "Cigarette Supply Crate"
+ desc = "Don't believe the reports - smoke today! Contains a cigarette vending machine refill."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/cigarette)
+ crate_name = "cigarette supply crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/service/vending/games
+ name = "Games Supply Crate"
+ desc = "Get your game on with this game vending machine refill."
+ cost = 1000
+ contains = list(/obj/item/vending_refill/games)
+ crate_name = "games supply crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/service/vending/snack
+ name = "Snack Supply Crate"
+ desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!"
+ cost = 1500
+ contains = list(/obj/item/vending_refill/snack)
+ crate_name = "snacks supply crate"
+
+/datum/supply_pack/service/vending/cola
+ name = "Softdrinks Supply Crate"
+ desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with this soda machine refill, today!"
+ cost = 1500
+ contains = list(/obj/item/vending_refill/cola)
+ crate_name = "soft drinks supply crate"
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index c6166ca970..47c3293c35 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -86,6 +86,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/skin_tone = "caucasian1" //Skin color
var/eye_color = "000" //Eye color
var/horn_color = "85615a" //Horn color
+ var/wing_color = "fff" //Wing color
var/datum/species/pref_species = new /datum/species/human() //Mutant race
var/list/features = list("mcolor" = "FFF",
"tail_lizard" = "Smooth",
@@ -591,6 +592,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "
Decorative wings
"
dat += "[features["deco_wings"]]"
+ dat += "Change "
+
if("insect_wings" in pref_species.default_features)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -598,6 +601,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "
"
@@ -70,8 +72,8 @@
if(check_rights_for(target.client, R_FUN)) //Allows admins to view faxes
return TRUE
if(isAI(target))
- var/mob/living/silicon/ai/ai = target
- return get_dist(src, ai.current) < 2
+ force_stars = TRUE
+ return TRUE
if(iscyborg(target))
return get_dist(src, target) < 2
return ..()
@@ -133,18 +135,8 @@
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
addtimer(CALLBACK(src, .proc/reset_spamflag), 20)
-
/obj/item/paper/attack_ai(mob/living/silicon/ai/user)
- var/dist
- if(istype(user) && user.current) //is AI
- dist = get_dist(src, user.current)
- else //cyborg or AI not seeing through a camera
- dist = get_dist(src, user)
- if(dist < 2)
- show_content(user)
- else
- to_chat(user, "You can't quite see it.")
-
+ show_content(user)
/obj/item/paper/proc/addtofield(id, text, links = 0)
var/locid = 0
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index 5bcb7a60df..fece60f268 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -158,6 +158,7 @@
if(..())
if(reagents.total_volume)
if(M.reagents)
+ reagents.reaction(M, INJECT)
reagents.trans_to(M, reagents.total_volume)
@@ -200,7 +201,7 @@
throwforce = 35
playsound(user, 'sound/weapons/saberon.ogg', 5, 1)
to_chat(user, "[src] is now active.")
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = on
update_icon()
diff --git a/code/modules/photography/photos/album.dm b/code/modules/photography/photos/album.dm
index bd77d468d7..3400ed6de0 100644
--- a/code/modules/photography/photos/album.dm
+++ b/code/modules/photography/photos/album.dm
@@ -13,7 +13,7 @@
/obj/item/storage/photo_album/Initialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.can_hold = typecacheof(list(/obj/item/photo))
STR.max_combined_w_class = 42
STR.max_items = 21
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 1759f31344..0762ad46b0 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -20,6 +20,7 @@
var/self_recharge = 0 //does it self recharge, over time, or not?
var/ratingdesc = TRUE
var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it.
+ rad_flags = RAD_NO_CONTAMINATE // Prevent the same cheese as with the stock parts
/obj/item/stock_parts/cell/get_cell()
return src
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 120976b61f..e6fa1e0ee4 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -29,7 +29,7 @@
#define MOLE_HEAT_PENALTY 350 //Heat damage scales around this. Too hot setups with this amount of moles do regular damage, anything above and below is scaled
#define POWER_PENALTY_THRESHOLD 5000 //Higher == Engine can generate more power before triggering the high power penalties.
#define SEVERE_POWER_PENALTY_THRESHOLD 7000 //Same as above, but causes more dangerous effects
-#define CRITICAL_POWER_PENALTY_THRESHOLD 9000 //Even more dangerous effects, threshold for tesla delamination
+#define CRITICAL_POWER_PENALTY_THRESHOLD 12000 //Even more dangerous effects, threshold for tesla delamination
#define HEAT_PENALTY_THRESHOLD 40 //Higher == Crystal safe operational temperature is higher.
#define DAMAGE_HARDCAP 0.002
#define DAMAGE_INCREASE_MULTIPLIER 0.25
@@ -421,7 +421,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(prob(50))
radiation_pulse(src, power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumbonus) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER))))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%)
if(bzcomp >= 0.4 && prob(30 * bzcomp))
- src.fire_nuclear_particles() // Start to emit radballs at a maximum of 30% chance per tick
+ fire_nuclear_particle() // Start to emit radballs at a maximum of 30% chance per tick
var/device_energy = power * REACTION_POWER_MODIFIER
diff --git a/code/modules/projectiles/ammunition/energy/laser.dm b/code/modules/projectiles/ammunition/energy/laser.dm
index 638711e8d4..0940144721 100644
--- a/code/modules/projectiles/ammunition/energy/laser.dm
+++ b/code/modules/projectiles/ammunition/energy/laser.dm
@@ -71,9 +71,3 @@
projectile_type = /obj/item/projectile/beam/mindflayer
select_name = "MINDFUCK"
fire_sound = 'sound/weapons/laser.ogg'
-
-/obj/item/ammo_casing/energy/laser/weak
- projectile_type = /obj/item/projectile/beam/weak/minigun
- e_cost = 10
- fire_sound = 'sound/weapons/gatling.ogg'
- click_cooldown_override = 1
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index fb3ed19f82..13fd834657 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -62,16 +62,16 @@
var/zoomed = FALSE //Zoom toggle
var/zoom_amt = 3 //Distance in TURFs to move the user's screen forward (the "zoom" effect)
var/zoom_out_amt = 0
- var/datum/action/toggle_scope_zoom/azoom
+ var/datum/action/item_action/toggle_scope_zoom/azoom
/obj/item/gun/Initialize()
. = ..()
if(pin)
pin = new pin(src)
if(gun_light)
- alight = new /datum/action/item_action/toggle_gunlight(src)
- build_zooming()
-
+ alight = new (src)
+ if(zoomable)
+ azoom = new (src)
/obj/item/gun/CheckParts(list/parts_list)
..()
@@ -372,6 +372,12 @@
else
return ..()
+/obj/item/gun/ui_action_click(mob/user, action)
+ if(istype(action, /datum/action/item_action/toggle_scope_zoom))
+ zoom(user)
+ else if(istype(action, alight))
+ toggle_gunlight()
+
/obj/item/gun/proc/toggle_gunlight()
if(!gun_light)
return
@@ -407,21 +413,10 @@
var/datum/action/A = X
A.UpdateButtonIcon()
-/obj/item/gun/pickup(mob/user)
- ..()
- if(azoom)
- azoom.Grant(user)
- if(alight)
- alight.Grant(user)
-
-/obj/item/gun/dropped(mob/user)
- ..()
- if(zoomed)
- zoom(user,FALSE)
- if(azoom)
- azoom.Remove(user)
- if(alight)
- alight.Remove(user)
+/obj/item/gun/item_action_slot_check(slot, mob/user, datum/action/A)
+ if(istype(A, /datum/action/item_action/toggle_scope_zoom) && slot != SLOT_HANDS)
+ return FALSE
+ return ..()
/obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer)
if(!ishuman(user) || !ishuman(target))
@@ -468,41 +463,32 @@
// ZOOMING //
/////////////
-/datum/action/toggle_scope_zoom
+/datum/action/item_action/toggle_scope_zoom
name = "Toggle Scope"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "sniper_zoom"
- var/obj/item/gun/gun = null
-/datum/action/toggle_scope_zoom/Trigger()
- gun.zoom(owner)
-
-/datum/action/toggle_scope_zoom/IsAvailable()
+/datum/action/item_action/toggle_scope_zoom/IsAvailable()
. = ..()
- if(!gun)
- return FALSE
if(!.)
- gun.zoom(owner, FALSE)
- if(!owner.get_held_index_of_item(gun))
- return FALSE
-
-/datum/action/toggle_scope_zoom/Remove(mob/living/L)
- gun.zoom(L, FALSE)
- ..()
+ var/obj/item/gun/G = target
+ G.zoom(owner, FALSE)
+/datum/action/item_action/toggle_scope_zoom/Remove(mob/living/L)
+ var/obj/item/gun/G = target
+ G.zoom(L, FALSE)
+ return ..()
/obj/item/gun/proc/zoom(mob/living/user, forced_zoom)
- if(!user || !user.client)
+ if(!(user?.client))
return
- switch(forced_zoom)
- if(FALSE)
- zoomed = FALSE
- if(TRUE)
- zoomed = TRUE
- else
- zoomed = !zoomed
+ if(!isnull(forced_zoom))
+ if(zoomed == forced_zoom)
+ return
+ zoomed = forced_zoom
+ else
+ zoomed = !zoomed
if(zoomed)
var/_x = 0
@@ -524,16 +510,6 @@
user.client.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
user.client.pixel_y = 0
- return zoomed
-
-//Proc, so that gun accessories/scopes/etc. can easily add zooming.
-/obj/item/gun/proc/build_zooming()
- if(azoom)
- return
-
- if(zoomable)
- azoom = new()
- azoom.gun = src
/obj/item/gun/handle_atom_del(atom/A)
if(A == chambered)
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 1117bc1000..06ce7b91e4 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -170,7 +170,7 @@
if(iscarbon(user))
var/mob/living/carbon/C = user
user_dna = C.dna
- B.add_blood_DNA(user_dna)
+ B.add_blood_DNA(user_dna, C.diseases)
var/datum/callback/gibspawner = CALLBACK(GLOBAL_PROC, /proc/spawn_atom_to_turf, /obj/effect/gibspawner/generic, B, 1, FALSE, list(user_dna))
B.throw_at(target, BRAINS_BLOWN_THROW_RANGE, BRAINS_BLOWN_THROW_SPEED, callback=gibspawner)
return(BRUTELOSS)
diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm
index 4bd65a7b20..cd86b0b06c 100644
--- a/code/modules/projectiles/guns/ballistic/automatic.dm
+++ b/code/modules/projectiles/guns/ballistic/automatic.dm
@@ -51,8 +51,11 @@
else
to_chat(user, "You cannot seem to get \the [src] out of your hands!")
-/obj/item/gun/ballistic/automatic/ui_action_click()
- burst_select()
+/obj/item/gun/ballistic/automatic/ui_action_click(mob/user, action)
+ if(istype(action, /datum/action/item_action/toggle_firemode))
+ burst_select()
+ else
+ return ..()
/obj/item/gun/ballistic/automatic/proc/burst_select()
var/mob/living/carbon/human/user = usr
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 6060ceba99..2cccc57d9e 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -174,9 +174,6 @@
itemState += "[ratio]"
item_state = itemState
-/obj/item/gun/energy/ui_action_click()
- toggle_gunlight()
-
/obj/item/gun/energy/suicide_act(mob/living/user)
if (istype(user) && can_shoot() && can_trigger_gun(user) && user.get_bodypart(BODY_ZONE_HEAD))
user.visible_message("[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!")
diff --git a/code/modules/projectiles/guns/energy/minigun.dm b/code/modules/projectiles/guns/energy/minigun.dm
deleted file mode 100644
index d903cda47c..0000000000
--- a/code/modules/projectiles/guns/energy/minigun.dm
+++ /dev/null
@@ -1,149 +0,0 @@
-//The ammo/gun is stored in a back slot item
-/obj/item/minigunpack2
- name = " Laser Gatling Pack"
- desc = "A massive battery pack with an attached laser gatling gun!"
- icon = 'icons/obj/guns/minigun.dmi'
- icon_state = "holstered"
- item_state = "backpack"
- lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
- slot_flags = ITEM_SLOT_BACK
- w_class = WEIGHT_CLASS_HUGE
- var/obj/item/gun/energy/minigun/gun
- var/armed = 0 //whether the gun is attached, 0 is attached, 1 is the gun is wielded.
- var/overheat = 0
- var/overheat_max = 60
- var/heat_diffusion = 5
-
-/obj/item/minigunpack2/Initialize()
- . = ..()
- gun = new(src)
- START_PROCESSING(SSobj, src)
-
-/obj/item/minigunpack2/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
-
-/obj/item/minigunpack2/process()
- overheat = max(0, overheat - heat_diffusion)
-
-//ATTACK HAND IGNORING PARENT RETURN VALUE
-/obj/item/minigunpack2/attack_hand(var/mob/living/carbon/user)
- if(src.loc == user)
- if(!armed)
- if(user.get_item_by_slot(SLOT_BACK) == src)
- armed = 1
- if(!user.put_in_hands(gun))
- armed = 0
- to_chat(user, "You need a free hand to hold the gun!")
- return
- update_icon()
- user.update_inv_back()
- else
- to_chat(user, "You are already holding the gun!")
- else
- ..()
-
-/obj/item/minigunpack2/attackby(obj/item/W, mob/user, params)
- if(W == gun) //Don't need armed check, because if you have the gun assume its armed.
- user.dropItemToGround(gun, TRUE)
- else
- ..()
-
-/obj/item/minigunpack2/dropped(mob/user)
- if(armed)
- user.dropItemToGround(gun, TRUE)
-
-/obj/item/minigunpack2/MouseDrop(atom/over_object)
- . = ..()
- if(armed)
- return
- if(iscarbon(usr))
- var/mob/M = usr
-
- if(!over_object)
- return
-
- if(!M.incapacitated())
-
- if(istype(over_object, /obj/screen/inventory/hand))
- var/obj/screen/inventory/hand/H = over_object
- M.putItemFromInventoryInHandIfPossible(src, H.held_index)
-
-
-/obj/item/minigunpack2/update_icon()
- if(armed)
- icon_state = "notholstered"
- else
- icon_state = "holstered"
-
-/obj/item/minigunpack2/proc/attach_gun(var/mob/user)
- if(!gun)
- gun = new(src)
- gun.forceMove(src)
- armed = 0
- if(user)
- to_chat(user, "You attach the [gun.name] to the [name].")
- else
- src.visible_message("The [gun.name] snaps back onto the [name]!")
- update_icon()
- user.update_inv_back()
-
-
-/obj/item/gun/energy/minigun
- name = "laser gatling gun"
- desc = "An advanced laser cannon with an incredible rate of fire. Requires a bulky backpack power source to use."
- icon = 'icons/obj/guns/minigun.dmi'
- icon_state = "minigun_spin"
- item_state = "minigun"
- flags_1 = CONDUCT_1
- force = 15
- recoil = 2
- slowdown = 1
- slot_flags = null
- w_class = WEIGHT_CLASS_HUGE
- materials = list()
- ammo_type = list(/obj/item/ammo_casing/energy/laser/weak)
- burst_size = 2
- automatic = 1
- can_charge = 0
- selfcharge = EGUN_SELFCHARGE
- charge_tick = 2
- charge_delay = 5
- weapon_weight = WEAPON_HEAVY
- item_flags = NEEDS_PERMIT | SLOWS_WHILE_IN_HAND
- var/obj/item/minigunpack2/ammo_pack
-
-/obj/item/gun/energy/minigun/Initialize()
- if(istype(loc, /obj/item/minigunpack2)) //We should spawn inside an ammo pack so let's use that one.
- ammo_pack = loc
- else
- return INITIALIZE_HINT_QDEL //No pack, no gun
-
- return ..()
-
-/obj/item/gun/energy/minigun/attack_self(mob/living/user)
- return
-
-/obj/item/gun/energy/minigun/dropped(mob/user)
- if(ammo_pack)
- ammo_pack.attach_gun(user)
- else
- qdel(src)
-
-/obj/item/gun/energy/minigun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
- if(ammo_pack)
- if(ammo_pack.overheat < ammo_pack.overheat_max)
- ammo_pack.overheat += burst_size
- ..()
- else
- to_chat(user, "The gun's heat sensor locked the trigger to prevent lens damage.")
-
-/obj/item/gun/energy/minigun/afterattack(atom/target, mob/living/user, flag, params)
- if(!ammo_pack || ammo_pack.loc != user)
- to_chat(user, "You need the backpack power source to fire the gun!")
- . = ..()
-
-/obj/item/gun/energy/minigun/dropped(mob/living/user)
- ammo_pack.attach_gun(user)
-
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 44c7894467..c5d4c36813 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -20,7 +20,7 @@
name = "hybrid taser"
desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams."
icon_state = "advtaser"
- ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler)
+ ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode)
ammo_x_offset = 2
/obj/item/gun/energy/e_gun/advtaser/cyborg
diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm
index e4d13ad315..92fe91c222 100644
--- a/code/modules/projectiles/guns/misc/beam_rifle.dm
+++ b/code/modules/projectiles/guns/misc/beam_rifle.dm
@@ -45,7 +45,7 @@
var/aiming_lastangle = 0
var/mob/current_user = null
var/list/obj/effect/projectile/tracer/current_tracers
-
+
var/structure_piercing = 1
var/structure_bleed_coeff = 0.7
var/wall_pierce_amount = 0
@@ -76,7 +76,7 @@
var/static/image/drained_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_empty")
var/datum/action/item_action/zoom_lock_action/zoom_lock_action
- var/datum/component/mobhook
+ var/mob/listeningTo
/obj/item/gun/energy/beam_rifle/debug
delay = 0
@@ -111,7 +111,9 @@
to_chat(owner, "You switch [src]'s zooming processor to center mode.")
if(ZOOM_LOCK_OFF)
to_chat(owner, "You disable [src]'s zooming system.")
- reset_zooming()
+ reset_zooming()
+ else
+ return ..()
/obj/item/gun/energy/beam_rifle/proc/set_autozoom_pixel_offsets_immediate(current_angle)
if(zoom_lock == ZOOM_LOCK_CENTER_VIEW || zoom_lock == ZOOM_LOCK_OFF)
@@ -172,7 +174,7 @@
STOP_PROCESSING(SSfastprocess, src)
set_user(null)
QDEL_LIST(current_tracers)
- QDEL_NULL(mobhook)
+ listeningTo = null
return ..()
/obj/item/gun/energy/beam_rifle/emp_act(severity)
@@ -259,14 +261,17 @@
if(user == current_user)
return
stop_aiming(current_user)
- QDEL_NULL(mobhook)
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
if(istype(current_user))
LAZYREMOVE(current_user.mousemove_intercept_objects, src)
current_user = null
if(istype(user))
current_user = user
LAZYOR(current_user.mousemove_intercept_objects, src)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_mob_move)))
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move)
+ listeningTo = user
/obj/item/gun/energy/beam_rifle/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
if(aiming)
diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm
index 26e66b1987..342ceecbc2 100644
--- a/code/modules/projectiles/guns/misc/syringe_gun.dm
+++ b/code/modules/projectiles/guns/misc/syringe_gun.dm
@@ -122,3 +122,32 @@
else
to_chat(user, "You can't put the [A] into \the [src]!")
return FALSE
+
+/obj/item/gun/syringe/dart/rapiddart
+ name = "Repeating dart gun"
+ icon_state = "rapiddartgun"
+ item_state = "rapiddartgun"
+
+/obj/item/gun/syringe/dart/rapiddart/CheckParts(list/parts_list)
+ var/obj/item/reagent_containers/glass/beaker/B = locate(/obj/item/reagent_containers/glass/beaker) in parts_list
+
+ if(istype(B, /obj/item/reagent_containers/glass/beaker/large))
+ desc = "[initial(desc)] A modification of the dart gun's pressure chamber has been perfomed using a [B], extending it's holding size to [max_syringes]."
+ max_syringes = 2
+ return
+ else if(istype(B, /obj/item/reagent_containers/glass/beaker/plastic))
+ desc = "[initial(desc)] A modification of the dart gun's pressure chamber has been perfomed using a [B], extending it's holding size to [max_syringes]."
+ max_syringes = 3
+ return
+ else if(istype(B, /obj/item/reagent_containers/glass/beaker/meta))
+ desc = "[initial(desc)] A modification of the dart gun's pressure chamber has been perfomed using a [B], extending it's holding size to [max_syringes]."
+ max_syringes = 4
+ return
+ else if(istype(B, /obj/item/reagent_containers/glass/beaker/bluespace))
+ desc = "[initial(desc)] A modification of the dart gun's pressure chamber has been perfomed using a [B], extending it's holding size to [max_syringes]."
+ max_syringes = 6
+ return
+ else
+ max_syringes = 1
+ desc = "[initial(desc)] It has a [B] strapped to it, but it doesn't seem to be doing anything."
+ ..()
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index efae090707..8b881b57ed 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -88,6 +88,8 @@
//Effects
var/stun = 0
var/knockdown = 0
+ var/knockdown_stamoverride
+ var/knockdown_stam_max
var/unconscious = 0
var/irradiate = 0
var/stutter = 0
@@ -161,15 +163,26 @@
var/splatter_dir = dir
if(starting)
splatter_dir = get_dir(starting, target_loca)
- if(isalien(L))
+ var/obj/item/bodypart/B = L.get_bodypart(def_zone)
+ if(B.status == BODYPART_ROBOTIC) // So if you hit a robotic, it sparks instead of bloodspatters
+ do_sparks(2, FALSE, target.loc)
+ if(prob(25))
+ new /obj/effect/decal/cleanable/oil(target_loca)
+ else if(isalien(L))
new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir)
else
- new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, bloodtype_to_color(H.dna.blood_type))
+ else
+ new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, bloodtype_to_color())
+
if(iscarbon(L))
var/mob/living/carbon/C = L
C.bleed(damage)
else
L.add_splatter_floor(target_loca)
+
else if(impact_effect_type && !hitscan)
new impact_effect_type(target_loca, hitx, hity)
@@ -202,7 +215,7 @@
else
L.log_message("has been shot by [firer] with [src]", LOG_ATTACK, color="orange")
- return L.apply_effects(stun, knockdown, unconscious, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
+ return L.apply_effects(stun, knockdown, unconscious, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter, knockdown_stamoverride, knockdown_stam_max)
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index d8154b367d..e43eb5a3bc 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -39,14 +39,6 @@
/obj/item/projectile/beam/weak
damage = 15
-/obj/item/projectile/beam/weak/minigun
- damage = 12.5
- armour_penetration = 40
-
-/obj/item/projectile/beam/weak/minigun/Initialize()
- .=..()
- speed = pick(0.7,0.75,0.8,0.85,0.9,0.95,1,1.05,1.1,1.15)
-
/obj/item/projectile/beam/weak/penetrator
armour_penetration = 50
diff --git a/code/modules/projectiles/projectile/bullets/smg.dm b/code/modules/projectiles/projectile/bullets/smg.dm
index dfc6df537d..42aef1ec9d 100644
--- a/code/modules/projectiles/projectile/bullets/smg.dm
+++ b/code/modules/projectiles/projectile/bullets/smg.dm
@@ -17,31 +17,40 @@
/obj/item/projectile/bullet/c45_cleaning/on_hit(atom/target, blocked = FALSE)
. = ..()
var/turf/T = get_turf(target)
-
- //section shamelessly copypasta'd from the clean component
- SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/A in T)
if(is_cleanable(A))
qdel(A)
- else if(istype(A, /obj/item))
- var/obj/item/I = A
- SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(ismob(I.loc))
- var/mob/M = I.loc
+ else if(isitem(A))
+ var/obj/item/cleaned_item = A
+ SEND_SIGNAL(cleaned_item, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_item.clean_blood()
+ if(ismob(cleaned_item.loc))
+ var/mob/M = cleaned_item.loc
M.regenerate_icons()
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
- if(cleaned_human.head)
- SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(cleaned_human.wear_suit)
- SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- else if(cleaned_human.w_uniform)
- SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(cleaned_human.shoes)
- SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- cleaned_human.wash_cream()
- cleaned_human.regenerate_icons()
+ if(cleaned_human.lying)
+ if(cleaned_human.head)
+ SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.head.clean_blood()
+ cleaned_human.update_inv_head()
+ if(cleaned_human.wear_suit)
+ SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.wear_suit.clean_blood()
+ cleaned_human.update_inv_wear_suit()
+ else if(cleaned_human.w_uniform)
+ SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.w_uniform.clean_blood()
+ cleaned_human.update_inv_w_uniform()
+ if(cleaned_human.shoes)
+ SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.shoes.clean_blood()
+ cleaned_human.update_inv_shoes()
+ SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.clean_blood()
+ cleaned_human.wash_cream()
+ cleaned_human.regenerate_icons()
// 4.6x30mm (Autorifles)
@@ -57,4 +66,4 @@
/obj/item/projectile/bullet/incendiary/c46x30mm
name = "4.6x30mm incendiary bullet"
damage = 10
- fire_stacks = 1
+ fire_stacks = 1
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/energy/nuclear_particle.dm b/code/modules/projectiles/projectile/energy/nuclear_particle.dm
index 1753587ad3..e08f806fe5 100644
--- a/code/modules/projectiles/projectile/energy/nuclear_particle.dm
+++ b/code/modules/projectiles/projectile/energy/nuclear_particle.dm
@@ -3,10 +3,9 @@
name = "nuclear particle"
icon_state = "nuclear_particle"
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
- damage = 20
- damage_type = TOX
- irradiate = 2500 //enough to knockdown and induce vomiting
- speed = 0.4
+ flag = "rad"
+ irradiate = 5000
+ speed = 0.4
hitsound = 'sound/weapons/emitter2.ogg'
impact_type = /obj/effect/projectile/impact/xray
var/static/list/particle_colors = list(
@@ -25,22 +24,6 @@
add_atom_colour(particle_colors[our_color], FIXED_COLOUR_PRIORITY)
set_light(4, 3, particle_colors[our_color]) //Range of 4, brightness of 3 - Same range as a flashlight
-/atom/proc/fire_nuclear_particles(power_ratio) //used by fusion to fire random # of nuclear particles - power ratio determines about how many are fired
- var/random_particles = rand(3,6)
- var/particles_to_fire
- var/particles_fired
- switch(power_ratio) //multiply random_particles * factor for whatever tier
- if(0 to FUSION_MID_TIER_THRESHOLD)
- particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_LOW
- if(FUSION_MID_TIER_THRESHOLD to FUSION_HIGH_TIER_THRESHOLD)
- particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_MID
- if(FUSION_HIGH_TIER_THRESHOLD to FUSION_SUPER_TIER_THRESHOLD)
- particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_HIGH
- if(FUSION_SUPER_TIER_THRESHOLD to INFINITY)
- particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_SUPER
- while(particles_to_fire)
- particles_fired++
- var/angle = rand(0,360)
- var/obj/item/projectile/energy/nuclear_particle/P = new /obj/item/projectile/energy/nuclear_particle(src)
- addtimer(CALLBACK(P, /obj/item/projectile.proc/fire, angle), particles_fired) //multiply particles fired * delay so the particles end up stagnated (once every decisecond)
- particles_to_fire--
\ No newline at end of file
+/atom/proc/fire_nuclear_particle(angle = rand(0,360)) //used by fusion to fire random nuclear particles. Fires one particle in a random direction.
+ var/obj/item/projectile/energy/nuclear_particle/P = new /obj/item/projectile/energy/nuclear_particle(src)
+ P.fire(angle)
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index 895a165f49..d7c8b8b082 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -3,7 +3,9 @@
icon_state = "spark"
color = "#FFFF00"
nodamage = 1
- knockdown = 100
+ knockdown = 60
+ knockdown_stamoverride = 36
+ knockdown_stam_max = 50
stutter = 5
jitter = 20
hitsound = 'sound/weapons/taserhit.ogg'
@@ -11,6 +13,7 @@
tracer_type = /obj/effect/projectile/tracer/stun
muzzle_type = /obj/effect/projectile/muzzle/stun
impact_type = /obj/effect/projectile/impact/stun
+ var/tase_duration = 50
/obj/item/projectile/energy/electrode/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -23,6 +26,7 @@
if(C.dna && C.dna.check_mutation(HULK))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
+ C.apply_status_effect(STATUS_EFFECT_TASED, tase_duration)
addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5)
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
diff --git a/code/modules/projectiles/projectile/special/neurotoxin.dm b/code/modules/projectiles/projectile/special/neurotoxin.dm
index baf1495abb..1d359585c0 100644
--- a/code/modules/projectiles/projectile/special/neurotoxin.dm
+++ b/code/modules/projectiles/projectile/special/neurotoxin.dm
@@ -8,7 +8,7 @@
if(isalien(target))
knockdown = 0
nodamage = TRUE
- else if(isliving(target))
+ else if(iscarbon(target))
var/mob/living/L = target
L.Knockdown(100, TRUE, FALSE, 30, 25)
return ..()
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 96aa0901e0..f540ae850d 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -175,7 +175,7 @@
data["chosenPillStyle"] = chosenPillStyle
data["isPillBottleLoaded"] = bottle ? 1 : 0
if(bottle)
- GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
+ var/datum/component/storage/STRB = bottle.GetComponent(/datum/component/storage)
data["pillBotContent"] = bottle.contents.len
data["pillBotMaxContent"] = STRB.max_items
@@ -263,7 +263,7 @@
var/target_loc = bottle ? bottle : drop_location()
var/drop_threshold = INFINITY
if(bottle)
- GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
+ var/datum/component/storage/STRB = bottle.GetComponent(/datum/component/storage)
if(STRB)
drop_threshold = STRB.max_items - bottle.contents.len
@@ -384,6 +384,38 @@
adjust_item_drop_location(P)
reagents.trans_to(P, vol_part)
. = TRUE
+
+ if("createDart")
+ for(var/datum/reagent/R in reagents.reagent_list)
+ if(!(istype(R, /datum/reagent/medicine)))
+ visible_message("The [src] beeps, \"SmartDarts are insoluble with non-medicinal compounds.\"")
+ return
+
+ var/many = params["many"]
+ if(reagents.total_volume == 0)
+ return
+ var/amount = 1
+ var/vol_each = min(reagents.total_volume, 20)
+ if(text2num(many))
+ amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many darts?", amount) as num|null), 0, 10)
+ if(!amount)
+ return
+ vol_each = min(reagents.total_volume / amount, 20)
+
+ var/name = stripped_input(usr,"Name:","Name your SmartDart!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
+ if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
+ return
+
+ var/obj/item/reagent_containers/syringe/dart/D
+ for(var/i = 0; i < amount; i++)
+ D = new /obj/item/reagent_containers/syringe/dart(drop_location())
+ D.name = trim("[name] SmartDart")
+ adjust_item_drop_location(D)
+ reagents.trans_to(D, vol_each)
+ D.mode=!mode
+ D.update_icon()
+ . = TRUE
+
//END CITADEL ADDITIONS
if("analyzeBeak")
var/datum/reagent/R = GLOB.chemical_reagents_list[params["id"]]
diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm
index 6efa4276b6..05fa4d382a 100644
--- a/code/modules/reagents/chemistry/machinery/pandemic.dm
+++ b/code/modules/reagents/chemistry/machinery/pandemic.dm
@@ -188,7 +188,7 @@
to_chat(usr, "ERROR: Cannot replicate virus strain.")
return
A = A.Copy()
- var/list/data = list("viruses" = list(A))
+ var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY", "viruses" = list(A))
var/obj/item/reagent_containers/glass/bottle/B = new(drop_location())
B.name = "[A.name] culture bottle"
B.desc = "A small bottle. Contains [A.agent] culture in synthblood medium."
diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
index f3df72cd4d..1475f94f53 100644
--- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
@@ -423,7 +423,7 @@
. = 1
/datum/reagent/drug/happiness/addiction_act_stage1(mob/living/M)// all work and no play makes jack a dull boy
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(min(mood.sanity, SANITY_DISTURBED))
M.Jitter(5)
if(prob(20))
@@ -431,7 +431,7 @@
..()
/datum/reagent/drug/happiness/addiction_act_stage2(mob/living/M)
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(min(mood.sanity, SANITY_UNSTABLE))
M.Jitter(10)
if(prob(30))
@@ -439,7 +439,7 @@
..()
/datum/reagent/drug/happiness/addiction_act_stage3(mob/living/M)
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(min(mood.sanity, SANITY_CRAZY))
M.Jitter(15)
if(prob(40))
@@ -447,7 +447,7 @@
..()
/datum/reagent/drug/happiness/addiction_act_stage4(mob/living/carbon/human/M)
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(SANITY_INSANE)
M.Jitter(20)
if(prob(50))
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 951a77b0e8..3db5c4c4dc 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -236,10 +236,12 @@
/datum/reagent/medicine/silver_sulfadiazine
name = "Silver Sulfadiazine"
id = "silver_sulfadiazine"
- description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. If ingested through other means, deals minor toxin damage."
+ description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. It is mildly poisonous taken orally or by injection. If overdosed, deals brute and minor liver damage."
reagent_state = LIQUID
pH = 7.2
color = "#ffeac9"
+ metabolization_rate = 5 * REAGENTS_METABOLISM
+ overdose_threshold = 50
/datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M) && M.stat != DEAD)
@@ -260,6 +262,15 @@
..()
. = 1
+/datum/reagent/medicine/silver_sulfadiazine/overdose_start(mob/living/M)
+ metabolization_rate = 15 * REAGENTS_METABOLISM
+ M.adjustBruteLoss(2*REM, 0)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.applyLiverDamage(1)
+ ..()
+ . = 1
+
/datum/reagent/medicine/oxandrolone
name = "Oxandrolone"
id = "oxandrolone"
@@ -271,7 +282,7 @@
pH = 10.7
/datum/reagent/medicine/oxandrolone/on_mob_life(mob/living/carbon/M)
- if(M.getFireLoss() > 50)
+ if(M.getFireLoss() > 25)
M.adjustFireLoss(-4*REM, 0) //Twice as effective as silver sulfadiazine for severe burns
else
M.adjustFireLoss(-0.5*REM, 0) //But only a quarter as effective for more minor ones
@@ -287,10 +298,12 @@
/datum/reagent/medicine/styptic_powder
name = "Styptic Powder"
id = "styptic_powder"
- description = "If used in touch-based applications, immediately restores bruising as well as restoring more over time. If ingested through other means, deals minor toxin damage."
+ description = "If used in touch-based applications, immediately restores bruising as well as restoring more over time. It is poisonous if taken orally or by injection. If overdosed, deals brute and minor liver damage."
reagent_state = LIQUID
color = "#FF9696"
pH = 6.7
+ metabolization_rate = 5 * REAGENTS_METABOLISM
+ overdose_threshold = 50
/datum/reagent/medicine/styptic_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M) && M.stat != DEAD)
@@ -312,6 +325,15 @@
..()
. = 1
+datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
+ metabolization_rate = 15 * REAGENTS_METABOLISM
+ M.adjustBruteLoss(2*REM, 0)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.applyLiverDamage(1)
+ ..()
+ . = 1
+
/datum/reagent/medicine/salglu_solution
name = "Saline-Glucose Solution"
id = "salglu_solution"
@@ -398,23 +420,35 @@
/datum/reagent/medicine/synthflesh
name = "Synthflesh"
id = "synthflesh"
- description = "Has a 100% chance of instantly healing brute and burn damage. One unit of the chemical will heal one point of damage. Touch application only."
+ description = "Has a 100% chance of healing large amounts of brute and burn damage very quickly. One unit of the chemical will heal one point of damage. Touch application only."
reagent_state = LIQUID
color = "#FFEBEB"
pH = 11.5
+ metabolization_rate = 5 * REAGENTS_METABOLISM
+ overdose_threshold = 40
/datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1)
if(iscarbon(M))
if (M.stat == DEAD)
show_message = 0
- if(method in list(PATCH, TOUCH))
- M.adjustBruteLoss(-1.25 * reac_volume)
- M.adjustFireLoss(-1.25 * reac_volume)
+ if(method in list(INGEST, VAPOR))
+ var/mob/living/carbon/C = M
+ C.losebreath++
+ C.emote("cough")
+ to_chat(M, "You feel your throat closing up!")
+ else if(method == INJECT)
+ return
+ else if(method in list(PATCH, TOUCH))
+ M.adjustBruteLoss(-1 * reac_volume)
+ M.adjustFireLoss(-1 * reac_volume)
if(show_message)
to_chat(M, "You feel your burns and bruises healing! It stings like hell!")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
..()
+/datum/reagent/medicine/synthflesh/overdose_start(mob/living/M)
+ metabolization_rate = 15 * REAGENTS_METABOLISM
+
/datum/reagent/medicine/charcoal
name = "Charcoal"
id = "charcoal"
@@ -545,7 +579,7 @@
/datum/reagent/medicine/sal_acid/on_mob_life(mob/living/carbon/M)
- if(M.getBruteLoss() > 50)
+ if(M.getBruteLoss() > 25)
M.adjustBruteLoss(-4*REM, 0) //Twice as effective as styptic powder for severe bruising
else
M.adjustBruteLoss(-0.5*REM, 0) //But only a quarter as effective for more minor ones
@@ -1297,10 +1331,12 @@
/datum/reagent/medicine/corazone/on_mob_metabolize(mob/living/M)
..()
- ADD_TRAIT(M, TRAIT_STABLEHEART, id)
+ ADD_TRAIT(M, TRAIT_STABLEHEART, type)
+ ADD_TRAIT(M, TRAIT_STABLELIVER, type)
/datum/reagent/medicine/corazone/on_mob_end_metabolize(mob/living/M)
- REMOVE_TRAIT(M, TRAIT_STABLEHEART, id)
+ REMOVE_TRAIT(M, TRAIT_STABLEHEART, type)
+ REMOVE_TRAIT(M, TRAIT_STABLELIVER, type)
..()
/datum/reagent/medicine/muscle_stimulant
@@ -1407,7 +1443,7 @@
M.dizziness = max(0, M.dizziness-6)
M.confused = max(0, M.confused-6)
M.disgust = max(0, M.disgust-6)
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if(mood.sanity <= SANITY_NEUTRAL) // only take effect if in negative sanity and then...
mood.setSanity(min(mood.sanity+5, SANITY_NEUTRAL)) // set minimum to prevent unwanted spiking over neutral
..()
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 95b4a33c0d..8f8902503c 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -1,9 +1,9 @@
/datum/reagent/blood
- data = list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Blood"
id = "blood"
- color = "#C80000" // rgb: 200, 0, 0
- description = "Blood from a human, or otherwise."
+ color = BLOOD_COLOR_HUMAN // rgb: 200, 0, 0
+ description = "Blood from some creature."
metabolization_rate = 5 //fast rate so it disappears fast.
taste_description = "iron"
taste_mult = 1.3
@@ -28,27 +28,75 @@
if(iscarbon(L))
var/mob/living/carbon/C = L
- if(C.get_blood_id() == "blood" && (method == INJECT || (method == INGEST && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
- if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type)))
- C.reagents.add_reagent("toxin", reac_volume * 0.5)
- else
- C.blood_volume = min(C.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM)
+ var/blood_id = C.get_blood_id()
+ if((blood_id == "blood" || blood_id == "jellyblood") && (method == INJECT || (method == INGEST && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
+ C.blood_volume = min(C.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM * C.blood_ratio)
+ // we don't care about bloodtype here, we're just refilling the mob
- if(reac_volume >= 10 && istype(L))
+ if(reac_volume >= 10 && istype(L) && method != INJECT)
L.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
+/datum/reagent/blood/on_mob_life(mob/living/carbon/C) //Because lethals are preferred over stamina. damnifino.
+ var/blood_id = C.get_blood_id()
+ if((blood_id == "blood" || blood_id == "jellyblood"))
+ if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type))) //we only care about bloodtype here because this is where the poisoning should be
+ C.adjustToxLoss(rand(2,8)*REM, TRUE, TRUE) //forced to ensure people don't use it to gain beneficial toxin as slime person
+ ..()
+
/datum/reagent/blood/reaction_obj(obj/O, volume)
if(volume >= 3 && istype(O))
- O.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
+ O.add_blood_DNA(data)
+
+/datum/reagent/blood/reaction_turf(turf/T, reac_volume)//splash the blood all over the place
+ if(!istype(T))
+ return
+ if(reac_volume < 3)
+ return
+
+ var/obj/effect/decal/cleanable/blood/B = locate() in T //find some blood here
+ if(!B)
+ B = new(T)
+ if(data["blood_DNA"])
+ B.blood_DNA[data["blood_DNA"]] = data["blood_type"]
+ if(!B.reagents)
+ B.reagents.add_reagent(id, reac_volume)
+ B.update_icon()
/datum/reagent/blood/on_new(list/data)
if(istype(data))
SetViruses(src, data)
+ color = bloodtype_to_color(data["blood_type"])
+ if(data["blood_type"] == "SY")
+ name = "Synthetic Blood"
+ taste_description = "oily"
+
+ if(data["blood_type"] == "X*")
+ name = "Xenomorph Blood"
+ taste_description = "acidic heresy"
+ shot_glass_icon_state = "shotglassgreen"
+ pH = 2.5
+
+ if(data["blood_type"] == "HF")
+ name = "Hydraulic Blood"
+ taste_description = "burnt oil"
+ pH = 9.75
+
+ if(data["blood_type"] == "BUG")
+ name = "Insect Blood"
+ taste_description = "greasy"
+ pH = 7.25
+
+ if(data["blood_type"] == "L")
+ name = "Lizard Blood"
+ taste_description = "spicy"
+ pH = 6.85
+
+
/datum/reagent/blood/on_merge(list/mix_data)
if(data && mix_data)
if(data["blood_DNA"] != mix_data["blood_DNA"])
- data["cloneable"] = 0 //On mix, consider the genetic sampling unviable for pod cloning if the DNA sample doesn't match.
+ data["cloneable"] = FALSE //On mix, consider the genetic sampling unviable for pod cloning if the DNA sample doesn't match.
if(data["viruses"] || mix_data["viruses"])
var/list/mix1 = data["viruses"]
@@ -78,27 +126,111 @@
var/datum/disease/D = thing
. += D
-/datum/reagent/blood/reaction_turf(turf/T, reac_volume)//splash the blood all over the place
- if(!istype(T))
- return
- if(reac_volume < 3)
- return
+/datum/reagent/blood/synthetics
+ data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Synthetic Blood"
+ id = "syntheticblood"
+ taste_description = "oily"
+ color = BLOOD_COLOR_SYNTHETIC // rgb: 11, 7, 48
- var/obj/effect/decal/cleanable/blood/B = locate() in T //find some blood here
- if(!B)
- B = new(T)
- if(data["blood_DNA"])
- B.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
+/datum/reagent/blood/lizard
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_LIZARD, "blood_type"="L","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Lizard Blood"
+ id = "lizardblood"
+ taste_description = "spicy"
+ color = BLOOD_COLOR_LIZARD // rgb: 11, 7, 48
+ pH = 6.85
+
+/datum/reagent/blood/jellyblood
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Slime Jelly Blood"
+ id = "jellyblood"
+ description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL."
+ color = BLOOD_COLOR_SLIME
+ taste_description = "slime"
+ taste_mult = 1.3
+ pH = 4
+
+/datum/reagent/blood/xenomorph
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Xenomorph Blood"
+ id = "xenoblood"
+ taste_description = "acidic heresy"
+ color = BLOOD_COLOR_XENO // greenish yellow ooze
+ shot_glass_icon_state = "shotglassgreen"
+ pH = 2.5
+
+/datum/reagent/blood/oil
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Hydraulic Blood"
+ id = "oilblood"
+ taste_description = "burnt oil"
+ color = BLOOD_COLOR_OIL // dark, y'know, expected batman colors.
+ pH = 9.75
+
+/datum/reagent/blood/insect
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_BUG, "blood_type"="BUG","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Insectoid Blood"
+ id = "bugblood"
+ taste_description = "waxy"
+ color = BLOOD_COLOR_BUG // Bug colored, I guess.
+ pH = 7.25
+
+
+/datum/reagent/blood/jellyblood/on_mob_life(mob/living/carbon/M)
+ if(prob(10))
+ if(M.dna?.species?.exotic_bloodtype != "GEL")
+ to_chat(M, "Your insides are burning!")
+ M.adjustToxLoss(rand(20,60)*REM, 0)
+ . = 1
+ else if(prob(40) && isjellyperson(M))
+ M.heal_bodypart_damage(2*REM)
+ . = 1
+ ..()
/datum/reagent/liquidgibs
name = "Liquid gibs"
id = "liquidgibs"
- color = "#FF9966"
+ color = BLOOD_COLOR_HUMAN
description = "You don't even want to think about what's in here."
taste_description = "gross iron"
shot_glass_icon_state = "shotglassred"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 7.45
+/datum/reagent/liquidgibs/xeno
+ name = "Liquid xeno gibs"
+ id = "liquidxenogibs"
+ color = BLOOD_COLOR_XENO
+ taste_description = "blended heresy"
+ shot_glass_icon_state = "shotglassgreen"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ pH = 2.5
+
+/datum/reagent/liquidgibs/slime
+ name = "Slime sludge"
+ id = "liquidslimegibs"
+ color = BLOOD_COLOR_SLIME
+ taste_description = "slime"
+ shot_glass_icon_state = "shotglassgreen"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ pH = 4
+
+/datum/reagent/liquidgibs/synth
+ name = "Synthetic sludge"
+ id = "liquidsyntheticgibs"
+ color = BLOOD_COLOR_SYNTHETIC
+ taste_description = "jellied plastic"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+
+/datum/reagent/liquidgibs/oil
+ name = "Hydraulic sludge"
+ id = "liquidoilgibs"
+ color = BLOOD_COLOR_OIL
+ taste_description = "chunky burnt oil"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ pH = 9.75
+
/datum/reagent/vaccine
//data must contain virus type
name = "Vaccine"
@@ -585,6 +717,30 @@
race = /datum/species/android
mutationtext = "The pain subsides. You feel... artificial."
+//Citadel Races
+/datum/reagent/mutationtoxin/mammal
+ name = "Mammal Mutation Toxin"
+ id = "mammalmutationtoxin"
+ description = "A glowing toxin."
+ color = "#5EFF3B" //RGB: 94, 255, 59
+ race = /datum/species/mammal
+ mutationtext = "The pain subsides. You feel... fluffier."
+
+/datum/reagent/mutationtoxin/insect
+ name = "Insect Mutation Toxin"
+ id = "insectmutationtoxin"
+ description = "A glowing toxin."
+ color = "#5EFF3B" //RGB: 94, 255, 59
+ race = /datum/species/insect
+ mutationtext = "The pain subsides. You feel... attracted to dark, moist areas."
+
+/datum/reagent/mutationtoxin/xenoperson
+ name = "Xeno-Hybrid Mutation Toxin"
+ id = "xenopersonmutationtoxin"
+ description = "A glowing toxin."
+ color = "#5EFF3B" //RGB: 94, 255, 59
+ race = /datum/species/xeno
+ mutationtext = "The pain subsides. You feel... oddly longing for the Queen." //sadly, not the British one.
//BLACKLISTED RACES
/datum/reagent/mutationtoxin/skeleton
@@ -947,12 +1103,12 @@
reagent_state = SOLID
taste_description = "iron"
pH = 6
-
+ overdose_threshold = 30
color = "#c2391d"
/datum/reagent/iron/on_mob_life(mob/living/carbon/C)
if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio))
- C.blood_volume += 0.5
+ C.blood_volume += 0.01 //we'll have synthetics from medbay.
..()
/datum/reagent/iron/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
@@ -961,6 +1117,17 @@
M.reagents.add_reagent("toxin", reac_volume)
..()
+/datum/reagent/iron/overdose_start(mob/living/M)
+ to_chat(M, "You start feeling your guts twisting painfully!")
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[id]_overdose", /datum/mood_event/overdose, name)
+
+/datum/reagent/iron/overdose_process(mob/living/carbon/C)
+ if(prob(20))
+ var/obj/item/organ/liver/L = C.getorganslot(ORGAN_SLOT_LIVER)
+ if (istype(L))
+ C.applyLiverDamage(2) //mild until the fabled med rework comes out. the organ damage galore
+ ..()
+
/datum/reagent/gold
name = "Gold"
id = "gold"
@@ -1077,17 +1244,19 @@
pH = 5.5
/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
- if(istype(O, /obj/effect/decal/cleanable))
+ if(istype(O, /obj/effect/decal/cleanable) || istype(O, /obj/item/projectile/bullet/reusable/foam_dart) || istype(O, /obj/item/ammo_casing/caseless/foam_dart))
qdel(O)
else
if(O)
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ O.clean_blood()
/datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume)
if(reac_volume >= 1)
T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ T.clean_blood()
for(var/obj/effect/decal/cleanable/C in T)
qdel(C)
@@ -1105,26 +1274,33 @@
H.lip_style = null
H.update_body()
for(var/obj/item/I in C.held_items)
- SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ I.clean_blood()
if(C.wear_mask)
- if(SEND_SIGNAL(C.wear_mask, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(C.wear_mask, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(C.wear_mask.clean_blood())
C.update_inv_wear_mask()
if(ishuman(M))
var/mob/living/carbon/human/H = C
if(H.head)
- if(SEND_SIGNAL(H.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(H.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(H.head.clean_blood())
H.update_inv_head()
if(H.wear_suit)
- if(SEND_SIGNAL(H.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(H.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(H.wear_suit.clean_blood())
H.update_inv_wear_suit()
else if(H.w_uniform)
- if(SEND_SIGNAL(H.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(H.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(H.w_uniform.clean_blood())
H.update_inv_w_uniform()
if(H.shoes)
- if(SEND_SIGNAL(H.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(H.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(H.shoes.clean_blood())
H.update_inv_shoes()
H.wash_cream()
- SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ M.clean_blood()
/datum/reagent/space_cleaner/ez_clean
name = "EZ Clean"
@@ -2119,26 +2295,22 @@
chemical_flags = REAGENT_INVISIBLE
/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C)
- if(C && C.dna && data["desired_dna"])
+ if(ishuman(C) && C.dna && data["desired_dna"])
original_dna = new C.dna.type
C.dna.copy_dna(original_dna)
var/datum/dna/new_dna = data["desired_dna"]
- new_dna.copy_dna(C.dna)
+ new_dna.transfer_identity(C, TRUE)
C.real_name = new_dna.real_name
- C.updateappearance(mutcolor_update=1)
- C.update_body()
+ C.updateappearance(mutcolor_update = TRUE)
C.domutcheck()
- C.regenerate_icons()
..()
/datum/reagent/changeling_string/on_mob_end_metabolize(mob/living/carbon/C)
if(original_dna)
- original_dna.copy_dna(C.dna)
+ original_dna.transfer_identity(C, TRUE)
C.real_name = original_dna.real_name
- C.updateappearance(mutcolor_update=1)
- C.update_body()
+ C.updateappearance(mutcolor_update = TRUE)
C.domutcheck()
- C.regenerate_icons()
..()
/datum/reagent/changeling_string/Destroy()
diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm
index 2ed9a31107..374f7715bb 100644
--- a/code/modules/reagents/chemistry/recipes/medicine.dm
+++ b/code/modules/reagents/chemistry/recipes/medicine.dm
@@ -283,6 +283,12 @@
results = list("regen_jelly" = 2)
required_reagents = list("tricordrazine" = 1, "slimejelly" = 1)
+/datum/chemical_reaction/jelly_convert
+ name = "Blood Jelly Conversion"
+ id = "blood_jelly"
+ results = list("slimejelly" = 1)
+ required_reagents = list("toxin" = 1, "jellyblood" = 1)
+
/datum/chemical_reaction/corazone
name = "Corazone"
id = "corazone"
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index b3f9591f64..d475b118b2 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -26,7 +26,7 @@
create_reagents(volume, reagent_flags)
if(spawned_disease)
var/datum/disease/F = new spawned_disease()
- var/list/data = list("viruses"= list(F))
+ var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY","viruses"= list(F))
reagents.add_reagent("blood", disease_amount, data)
add_initial_reagents()
diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm
index 3e555f385f..fe35981bfe 100644
--- a/code/modules/reagents/reagent_containers/blood_pack.dm
+++ b/code/modules/reagents/reagent_containers/blood_pack.dm
@@ -4,13 +4,16 @@
icon = 'icons/obj/bloodpack.dmi'
icon_state = "bloodpack"
volume = 200
+ reagent_flags = DRAINABLE
var/blood_type = null
var/labelled = 0
+ var/color_to_apply = "#FFFFFF"
+ var/mutable_appearance/fill_overlay
/obj/item/reagent_containers/blood/Initialize()
. = ..()
if(blood_type != null)
- reagents.add_reagent("blood", 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
+ reagents.add_reagent("blood", 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_colour"=color, "blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
update_icon()
/obj/item/reagent_containers/blood/on_reagent_change(changetype)
@@ -18,6 +21,7 @@
var/datum/reagent/blood/B = reagents.has_reagent("blood")
if(B && B.data && B.data["blood_type"])
blood_type = B.data["blood_type"]
+ color_to_apply = bloodtype_to_color(blood_type)
else
blood_type = null
update_pack_name()
@@ -45,7 +49,7 @@
/obj/item/reagent_containers/blood/random/Initialize()
icon_state = "bloodpack"
- blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L")
+ blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L", "SY", "HF", "GEL", "BUG")
return ..()
/obj/item/reagent_containers/blood/APlus
@@ -72,6 +76,18 @@
/obj/item/reagent_containers/blood/universal
blood_type = "U"
+/obj/item/reagent_containers/blood/synthetics
+ blood_type = "SY"
+
+/obj/item/reagent_containers/blood/oilblood
+ blood_type = "HF"
+
+/obj/item/reagent_containers/blood/jellyblood
+ blood_type = "GEL"
+
+/obj/item/reagent_containers/blood/insect
+ blood_type = "BUG"
+
/obj/item/reagent_containers/blood/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/pen) || istype(I, /obj/item/toy/crayon))
if(!user.is_literate())
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index cc83eb28f6..6bdae6225a 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -104,7 +104,7 @@
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) // transfer from, transfer to - who cares?
to_chat(user, "You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.")
- if (reagents.total_volume >= reagents.maximum_volume)
+ if (round(reagents.total_volume, 0.1) >= reagents.maximum_volume)
mode=!mode
update_icon()
@@ -307,7 +307,7 @@
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "You soak the [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.")
- if (reagents.total_volume >= reagents.maximum_volume)
+ if (round(reagents.total_volume,1) >= reagents.maximum_volume)
mode=!mode
update_icon()
@@ -323,8 +323,9 @@
rounded_vol = "empty"
if(reagents && reagents.total_volume)
- if(volume/reagents.total_volume == 1)
+ if(volume/round(reagents.total_volume, 1) == 1)
rounded_vol="full"
+ mode = SYRINGE_INJECT
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index a4a6a7d473..5edddd64c2 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -283,7 +283,7 @@
/obj/machinery/disposal/bin/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/storage/bag/trash)) //Not doing component overrides because this is a specific type.
var/obj/item/storage/bag/trash/T = I
- GET_COMPONENT_FROM(STR, /datum/component/storage, T)
+ var/datum/component/storage/STR = T.GetComponent(/datum/component/storage)
to_chat(user, "You empty the bag.")
for(var/obj/item/O in T.contents)
STR.remove_from_storage(O,src)
diff --git a/code/modules/recycling/disposal/construction.dm b/code/modules/recycling/disposal/construction.dm
index 624d5e0e05..348e687e03 100644
--- a/code/modules/recycling/disposal/construction.dm
+++ b/code/modules/recycling/disposal/construction.dm
@@ -29,7 +29,7 @@
pipename = initial(pipe_type.name)
if(flip)
- GET_COMPONENT(rotcomp,/datum/component/simple_rotation)
+ var/datum/component/simple_rotation/rotcomp = GetComponent(/datum/component/simple_rotation)
rotcomp.BaseRot(null,ROTATION_FLIP)
update_icon()
diff --git a/code/modules/research/designs/electronics_designs.dm b/code/modules/research/designs/electronics_designs.dm
index 552976824d..818e80beea 100644
--- a/code/modules/research/designs/electronics_designs.dm
+++ b/code/modules/research/designs/electronics_designs.dm
@@ -131,3 +131,30 @@
category = list("Misc")
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
+/datum/design/xenobio_upgrade
+ name = "owo"
+ desc = "someone's bussin"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ category = list("Electronics")
+ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/xenobio_upgrade/xenobiomonkeys
+ name = "Xenobiology console monkey upgrade disk"
+ desc = "This disk will add the ability to remotely recycle monkeys via the Xenobiology console."
+ id = "xenobio_monkeys"
+ build_path = /obj/item/disk/xenobio_console_upgrade/monkey
+
+/datum/design/xenobio_upgrade/xenobioslimebasic
+ name = "Xenobiology console basic slime upgrade disk"
+ desc = "This disk will add the ability to remotely manipulate slimes via the Xenobiology console."
+ id = "xenobio_slimebasic"
+ build_path = /obj/item/disk/xenobio_console_upgrade/slimebasic
+
+/datum/design/xenobio_upgrade/xenobioslimeadv
+ name = "Xenobiology console advanced slime upgrade disk"
+ desc = "This disk will add the ability to remotely feed slimes potions via the Xenobiology console, and lift the restrictions on the number of slimes that can be stored inside the Xenobiology console. This includes the contents of the basic slime upgrade disk."
+ id = "xenobio_slimeadv"
+ build_path = /obj/item/disk/xenobio_console_upgrade/slimeadv
+
+
diff --git a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm
index 31723cde07..b4d67315ba 100644
--- a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm
+++ b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm
@@ -98,3 +98,11 @@
build_path = /obj/item/circuitboard/machine/vr_sleeper
departmental_flags = DEPARTMENTAL_FLAG_ALL
category = list ("Medical Machinery")
+
+/datum/design/board/autoylathe
+ name = "Machine Design (Autoylathe)"
+ desc = "The circuit board for an autoylathe."
+ id = "autoylathe"
+ build_path = /obj/item/circuitboard/machine/autoylathe
+ departmental_flags = DEPARTMENTAL_FLAG_ALL
+ category = list("Misc. Machinery")
diff --git a/code/modules/research/designs/machine_desings/machine_designs_medical.dm b/code/modules/research/designs/machine_desings/machine_designs_medical.dm
index 65b3d74f71..2f95954e01 100644
--- a/code/modules/research/designs/machine_desings/machine_designs_medical.dm
+++ b/code/modules/research/designs/machine_desings/machine_designs_medical.dm
@@ -89,3 +89,11 @@
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING
build_path = /obj/item/circuitboard/machine/clonescanner
category = list("Medical Machinery")
+
+/datum/design/board/bloodbankgen
+ name = "Machine Design (Blood Bank Generator Board)"
+ desc = "The circuit board for a blood bank generator."
+ id = "bloodbankgen"
+ build_path = /obj/item/circuitboard/machine/bloodbankgen
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+ category = list ("Medical Machinery")
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index ae01b75dd9..e70362553c 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -729,12 +729,22 @@
var/surgery
/datum/design/surgery/experimental_dissection
- name = "Experimental Dissection"
- desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database."
- id = "surgery_exp_dissection"
- surgery = /datum/surgery/advanced/bioware/experimental_dissection
+ name = "Advanced Dissection"
+ desc = "A surgical procedure which analyzes the biology of a corpse, and automatically adds new findings to the research database."
+ id = "surgery_adv_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection/adv
research_icon_state = "surgery_chest"
+/datum/design/surgery/experimental_dissection/exp
+ name = "Experimental Dissection"
+ id = "surgery_exp_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection/exp
+
+/datum/design/surgery/experimental_dissection/ext
+ name = "Extraterrestrial Dissection"
+ id = "surgery_ext_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection/alien
+
/datum/design/surgery/lobotomy
name = "Lobotomy"
desc = "An invasive surgical procedure which guarantees removal of almost all brain traumas, but might cause another permanent trauma in return."
@@ -756,13 +766,49 @@
surgery = /datum/surgery/advanced/viral_bonding
research_icon_state = "surgery_chest"
-/datum/design/surgery/reconstruction
- name = "Reconstruction"
- desc = "A surgical procedure that gradually repairs damage done to a body without the assistance of chemicals. Unlike classic medicine, it is effective on corpses."
- id = "surgery_reconstruction"
- surgery = /datum/surgery/advanced/reconstruction
+/datum/design/surgery/healing
+ name = "Tend Wounds"
+ desc = "An upgraded version of the original surgery."
+ id = "surgery_healing_base" //holder because travis cries otherwise. Not used in techweb unlocks.
research_icon_state = "surgery_chest"
+/datum/design/surgery/healing/brute_upgrade
+ name = "Tend Wounds (Brute) Upgrade"
+ surgery = /datum/surgery/healing/brute/upgraded
+ id = "surgery_heal_brute_upgrade"
+
+/datum/design/surgery/healing/brute_upgrade_2
+ name = "Tend Wounds (Brute) Upgrade"
+ surgery = /datum/surgery/healing/brute/upgraded/femto
+ id = "surgery_heal_brute_upgrade_femto"
+
+/datum/design/surgery/healing/burn_upgrade
+ name = "Tend Wounds (Burn) Upgrade"
+ surgery = /datum/surgery/healing/burn/upgraded
+ id = "surgery_heal_burn_upgrade"
+
+/datum/design/surgery/healing/burn_upgrade_2
+ name = "Tend Wounds (Burn) Upgrade"
+ surgery = /datum/surgery/healing/brute/upgraded/femto
+ id = "surgery_heal_burn_upgrade_femto"
+
+/datum/design/surgery/healing/combo
+ name = "Tend Wounds (Mixture)"
+ desc = "A surgical procedure that repairs both bruises and burns. Repair efficiency is not as high as the individual surgeries but it is faster."
+ surgery = /datum/surgery/healing/combo
+ id = "surgery_heal_combo"
+
+/datum/design/surgery/healing/combo_upgrade
+ name = "Tend Wounds (Mixture) Upgrade"
+ surgery = /datum/surgery/healing/combo/upgraded
+ id = "surgery_heal_combo_upgrade"
+
+/datum/design/surgery/healing/combo_upgrade_2
+ name = "Tend Wounds (Mixture) Upgrade"
+ desc = "A surgical procedure that repairs both bruises and burns faster than their individual counterparts. It is more effective than both the individual surgeries."
+ surgery = /datum/surgery/healing/combo/upgraded/femto
+ id = "surgery_heal_combo_upgrade_femto"
+
/datum/design/surgery/surgery_toxinhealing
name = "Body Rejuvenation"
desc = "A surgical procedure that helps deal with oxygen deprecation, and treat toxic damaged. Works on corpses and alive alike without chemicals."
@@ -805,6 +851,13 @@
surgery = /datum/surgery/advanced/bioware/vein_threading
research_icon_state = "surgery_chest"
+/datum/design/surgery/muscled_veins
+ name = "Vein Muscle Membrane"
+ desc = "A surgical procedure which adds a muscled membrane to blood vessels, allowing them to pump blood without a heart."
+ id = "surgery_muscled_veins"
+ surgery = /datum/surgery/advanced/bioware/muscled_veins
+ research_icon_state = "surgery_chest"
+
/datum/design/surgery/ligament_hook
name = "Ligament Hook"
desc = "A surgical procedure which reshapes the connections between torso and limbs, making it so limbs can be attached manually if severed. \
diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm
index 11bc31bedc..5176c4fd71 100644
--- a/code/modules/research/designs/weapon_designs.dm
+++ b/code/modules/research/designs/weapon_designs.dm
@@ -105,7 +105,7 @@
materials = list(MAT_METAL = 200)
build_path = /obj/item/ammo_casing/shotgun/stunslug
category = list("Ammo")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/techshell
name = "Unloaded Technological Shotshell"
@@ -139,7 +139,7 @@
materials = list(MAT_METAL = 500, MAT_GLASS = 300)
build_path = /obj/item/firing_pin/test_range
category = list("Firing Pins")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/pin_mindshield
name = "Mindshield Firing Pin"
@@ -235,7 +235,7 @@
reagents_list = list("radium" = 20)
build_path = /obj/item/gun/energy/floragun
category = list("Weapons")
- departmental_flags = DEPARTMENTAL_FLAG_SERVICE
+ departmental_flags = DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/xray
name = "X-ray Laser Gun"
@@ -309,7 +309,7 @@
materials = list(MAT_METAL = 2000, MAT_PLASMA = 500)
build_path = /obj/item/grenade/chem_grenade/pyro
category = list("Weapons")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/cryo_grenade
name = "Cryo Grenade"
@@ -319,7 +319,7 @@
materials = list(MAT_METAL = 2000, MAT_SILVER = 500)
build_path = /obj/item/grenade/chem_grenade/cryo
category = list("Weapons")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/adv_grenade
name = "Advanced Release Grenade"
@@ -329,7 +329,7 @@
materials = list(MAT_METAL = 3000, MAT_GLASS = 500)
build_path = /obj/item/grenade/chem_grenade/adv_release
category = list("Weapons")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
//////////
//MISC////
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index e56350a280..0bcd0c5984 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -422,7 +422,7 @@
if(exp == SCANTYPE_OBLITERATE)
visible_message("[exp_on] activates the crushing mechanism, [exp_on] is destroyed!")
if(linked_console.linked_lathe)
- GET_COMPONENT_FROM(linked_materials, /datum/component/material_container, linked_console.linked_lathe)
+ var/datum/component/material_container/linked_materials = linked_console.linked_lathe.GetComponent(/datum/component/material_container)
for(var/material in exp_on.materials)
linked_materials.insert_amount( min((linked_materials.max_amount - linked_materials.total_amount), (exp_on.materials[material])), material)
if(prob(EFFECT_PROB_LOW) && criticalReaction)
diff --git a/code/modules/research/research_disk.dm b/code/modules/research/research_disk.dm
index 2ec2398d88..02865dc5bb 100644
--- a/code/modules/research/research_disk.dm
+++ b/code/modules/research/research_disk.dm
@@ -29,3 +29,12 @@
/obj/item/disk/tech_disk/illegal/Initialize()
. = ..()
stored_research = new /datum/techweb/syndicate
+
+/obj/item/disk/tech_disk/abductor
+ name = "Gray technology disk"
+ desc = "You feel like it's not Gray because of its color."
+ materials = list()
+
+/obj/item/disk/tech_disk/abductor/Initialize()
+ . = ..()
+ stored_research = new /datum/techweb/abductor
diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm
index cd5a190fd6..1e554f112f 100644
--- a/code/modules/research/techweb/_techweb.dm
+++ b/code/modules/research/techweb/_techweb.dm
@@ -49,6 +49,14 @@
var/datum/techweb_node/syndicate_basic/Node = new()
research_node(Node, TRUE)
+/datum/techweb/abductor
+ id = "ABDUCTOR"
+ organization = "Aliens"
+
+/datum/techweb/abductor/New()
+ var/datum/techweb_node/alientech/Node = new()
+ research_node(Node, TRUE)
+
/datum/techweb/science //Global science techweb for RND consoles.
id = "SCIENCE"
organization = "Nanotrasen"
@@ -364,3 +372,7 @@
/datum/techweb/specialized/autounlocking/exofab
allowed_buildtypes = MECHFAB
+
+/datum/techweb/specialized/autounlocking/autoylathe
+ design_autounlock_buildtypes = AUTOYLATHE
+ allowed_buildtypes = AUTOYLATHE
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 477bfbe1a1..aea4192517 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -60,7 +60,7 @@
display_name = "Biological Technology"
description = "What makes us tick." //the MC, silly!
prereq_ids = list("base")
- design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag")
+ design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -110,12 +110,21 @@
export_price = 5000
/////////////////////////Advanced Surgery/////////////////////////
+/datum/techweb_node/imp_wt_surgery
+ id = "imp_wt_surgery"
+ display_name = "Improved Wound-Tending Surgery"
+ description = "Who would have known being more gentle with a hemostat decreases patient pain?"
+ prereq_ids = list("biotech")
+ design_ids = list("surgery_heal_brute_upgrade","surgery_heal_burn_upgrade")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000)
+ export_price = 1000
+
/datum/techweb_node/adv_surgery
id = "adv_surgery"
display_name = "Advanced Surgery"
description = "When simple medicine doesn't cut it."
- prereq_ids = list("adv_biotech")
- design_ids = list("surgery_lobotomy", "surgery_reconstruction", "surgery_toxinhealing", "organbox", "surgery_exp_dissection")
+ prereq_ids = list("imp_wt_surgery")
+ design_ids = list("surgery_revival", "surgery_lobotomy", "surgery_heal_brute_upgrade_femto","surgery_heal_burn_upgrade_femto", "surgery_heal_combo", "surgery_toxinhealing", "organbox", "surgery_adv_dissection")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -124,7 +133,7 @@
display_name = "Experimental Surgery"
description = "When evolution isn't fast enough."
prereq_ids = list("adv_surgery")
- design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_nerve_splice","surgery_nerve_ground","surgery_ligament_hook","surgery_ligament_reinforcement","surgery_viral_bond")
+ design_ids = list("surgery_pacify","surgery_vein_thread","surgery_muscled_veins","surgery_nerve_splice","surgery_nerve_ground","surgery_ligament_hook","surgery_ligament_reinforcement","surgery_viral_bond", "surgery_exp_dissection", "surgery_heal_combo_upgrade")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 5000
@@ -133,7 +142,7 @@
display_name = "Alien Surgery"
description = "Abductors did nothing wrong."
prereq_ids = list("exp_surgery", "alientech")
- design_ids = list("surgery_brainwashing","surgery_zombie")
+ design_ids = list("surgery_brainwashing","surgery_zombie", "surgery_ext_dissection", "surgery_heal_combo_upgrade_femto")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
export_price = 5000
@@ -1018,26 +1027,19 @@
id = "alien_bio"
display_name = "Alien Biological Tools"
description = "Advanced biological tools."
- prereq_ids = list("alientech", "adv_biotech")
+ prereq_ids = list("alientech", "advance_surgerytools")
design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery")
- boost_item_paths = list(/obj/item/gun/energy/alien, /obj/item/scalpel/alien, /obj/item/hemostat/alien, /obj/item/retractor/alien, /obj/item/circular_saw/alien,
- /obj/item/cautery/alien, /obj/item/surgicaldrill/alien, /obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, /obj/item/stock_parts/cell/infinite/abductor,
- /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor)
- research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
- export_price = 20000
- hidden = TRUE
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
+ export_price = 10000
/datum/techweb_node/alien_engi
id = "alien_engi"
display_name = "Alien Engineering"
description = "Alien engineering tools"
- prereq_ids = list("alientech", "adv_engi")
+ prereq_ids = list("alientech", "exp_tools")
design_ids = list("alien_wrench", "alien_wirecutters", "alien_screwdriver", "alien_crowbar", "alien_welder", "alien_multitool")
- boost_item_paths = list(/obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, /obj/item/stock_parts/cell/infinite/abductor,
- /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor)
- research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
- export_price = 20000
- hidden = TRUE
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
+ export_price = 10000
/datum/techweb_node/syndicate_basic
id = "syndicate_basic"
@@ -1097,4 +1099,4 @@
for(var/i in processing)
var/datum/techweb_node/TN = i
TW.add_point_list(TN.research_costs)
- return TW.printout_points()
\ No newline at end of file
+ return TW.printout_points()
diff --git a/code/modules/research/xenobiology/crossbreeding/_misc.dm b/code/modules/research/xenobiology/crossbreeding/_misc.dm
index b28f1676a1..0099fe143d 100644
--- a/code/modules/research/xenobiology/crossbreeding/_misc.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_misc.dm
@@ -58,9 +58,7 @@
var/mob/living/carbon/human/H = M
if(H.mind && !HAS_TRAIT(H, TRAIT_AGEUSIA))
to_chat(H,"That didn't taste very good...") //No disgust, though. It's just not good tasting.
- GET_COMPONENT_FROM(mood, /datum/component/mood, H)
- if(mood)
- mood.add_event(null,"gross_food", /datum/mood_event/gross_food)
+ SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "gross_food", /datum/mood_event/gross_food)
last_check_time = world.time
return
..()
diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
index b9e7122d07..6ad4ec34f8 100644
--- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
@@ -64,10 +64,9 @@
var/interrupted = FALSE
var/mob/target
var/icon/bluespace
- var/datum/weakref/redirect_component
/datum/status_effect/slimerecall/on_apply()
- redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/resistField))))
+ RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/resistField)
to_chat(owner, "You feel a sudden tug from an unknown force, and feel a pull to bluespace!")
to_chat(owner, "Resist if you wish avoid the force!")
bluespace = icon('icons/effects/effects.dmi',"chronofield")
@@ -77,9 +76,9 @@
/datum/status_effect/slimerecall/proc/resistField()
interrupted = TRUE
owner.remove_status_effect(src)
+
/datum/status_effect/slimerecall/on_remove()
- qdel(redirect_component.resolve())
- redirect_component = null
+ UnregisterSignal(owner, COMSIG_LIVING_RESIST)
owner.cut_overlay(bluespace)
if(interrupted || !ismob(target))
to_chat(owner, "The bluespace tug fades away, and you feel that the force has passed you by.")
@@ -98,10 +97,9 @@
duration = -1 //Will remove self when block breaks.
alert_type = /obj/screen/alert/status_effect/freon/stasis
var/obj/structure/ice_stasis/cube
- var/datum/weakref/redirect_component
/datum/status_effect/frozenstasis/on_apply()
- redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/breakCube))))
+ RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/breakCube)
cube = new /obj/structure/ice_stasis(get_turf(owner))
owner.forceMove(cube)
owner.status_flags |= GODMODE
@@ -118,8 +116,7 @@
if(cube)
qdel(cube)
owner.status_flags &= ~GODMODE
- qdel(redirect_component.resolve())
- redirect_component = null
+ UnregisterSignal(owner, COMSIG_LIVING_RESIST)
/datum/status_effect/slime_clone
id = "slime_cloned"
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index 5aebd1bafa..641b7e7dcb 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -29,12 +29,11 @@
var/datum/action/innate/slime_scan/scan_action
var/datum/action/innate/feed_potion/potion_action
- var/datum/component/redirect/listener
-
var/list/stored_slimes
var/obj/item/slimepotion/slime/current_potion
- var/max_slimes = 5
+ var/max_slimes = 1
var/monkeys = 0
+ var/upgradetier = 0
icon_screen = "slime_comp"
icon_keyboard = "rd_key"
@@ -50,7 +49,7 @@
scan_action = new
potion_action = new
stored_slimes = list()
- listener = AddComponent(/datum/component/redirect, list(COMSIG_ATOM_CONTENTS_DEL = CALLBACK(src, .proc/on_contents_del)))
+ RegisterSignal(src, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del)
/obj/machinery/computer/camera_advanced/xenobio/Destroy()
stored_slimes = null
@@ -108,6 +107,22 @@
stored_slimes -= deleted
/obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params)
+ if(istype(O, /obj/item/disk/xenobio_console_upgrade))
+ var/obj/item/disk/xenobio_console_upgrade/diskthing = O
+ var/successfulupgrade = FALSE
+ for(var/I in diskthing.upgradetypes)
+ if(upgradetier & I)
+ continue
+ else
+ upgradetier |= I
+ successfulupgrade = TRUE
+ if(I == XENOBIO_UPGRADE_SLIMEADV)
+ max_slimes = 10
+ if(successfulupgrade)
+ to_chat(user, "You have successfully upgraded [src] with [O].")
+ else
+ to_chat(user, "[src] already has the contents of [O] installed!")
+ return
if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
monkeys++
to_chat(user, "You feed [O] to [src]. It now has [monkeys] monkey cubes stored.")
@@ -266,3 +281,29 @@
break
else
to_chat(owner, "Target is not near a camera. Cannot proceed.")
+
+/obj/item/disk/xenobio_console_upgrade
+ name = "Xenobiology console upgrade disk"
+ desc = "Allan please add detail."
+ icon_state = "datadisk5"
+ var/list/upgradetypes = list()
+
+/obj/item/disk/xenobio_console_upgrade/admin
+ name = "Xenobio all access thing"
+ desc = "'the consoles are literally useless!!!!!!!!!!!!!!!'"
+ upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC, XENOBIO_UPGRADE_SLIMEADV, XENOBIO_UPGRADE_MONKEYS)
+
+/obj/item/disk/xenobio_console_upgrade/monkey
+ name = "Xenobiology console monkey upgrade disk"
+ desc = "This disk will add the ability to remotely recycle monkeys via the Xenobiology console."
+ upgradetypes = list(XENOBIO_UPGRADE_MONKEYS)
+
+/obj/item/disk/xenobio_console_upgrade/slimebasic
+ name = "Xenobiology console basic slime upgrade disk"
+ desc = "This disk will add the ability to remotely manipulate slimes via the Xenobiology console."
+ upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC)
+
+/obj/item/disk/xenobio_console_upgrade/slimeadv
+ name = "Xenobiology console advanced slime upgrade disk"
+ desc = "This disk will add the ability to remotely feed slimes potions via the Xenobiology console, and lift the restrictions on the number of slimes that can be stored inside the Xenobiology console. This includes the contents of the basic slime upgrade disk."
+ upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC, XENOBIO_UPGRADE_SLIMEADV)
diff --git a/code/modules/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/ruins/spaceruin_code/hilbertshotel.dm
new file mode 100644
index 0000000000..0d4d2b6ad6
--- /dev/null
+++ b/code/modules/ruins/spaceruin_code/hilbertshotel.dm
@@ -0,0 +1,529 @@
+GLOBAL_VAR_INIT(hhStorageTurf, null)
+GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
+
+/obj/item/hilbertshotel
+ name = "Hilbert's Hotel"
+ desc = "A sphere of what appears to be an intricate network of bluespace. Observing it in detail seems to give you a headache as you try to comprehend the infinite amount of infinitesimally distinct points on its surface."
+ icon_state = "hilbertshotel"
+ w_class = WEIGHT_CLASS_SMALL
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ var/datum/map_template/hilbertshotel/hotelRoomTemp
+ var/datum/map_template/hilbertshotel/empty/hotelRoomTempEmpty
+ var/datum/map_template/hilbertshotel/lore/hotelRoomTempLore
+ var/list/activeRooms = list()
+ var/list/storedRooms = list()
+ var/storageTurf
+ //Lore Stuff
+ var/ruinSpawned = FALSE
+ var/mysteryRoom
+
+/obj/item/hilbertshotel/Initialize()
+ . = ..()
+ //Load templates
+ hotelRoomTemp = new()
+ hotelRoomTempEmpty = new()
+ hotelRoomTempLore = new()
+ var/area/currentArea = get_area(src)
+ if(currentArea.type == /area/ruin/space/has_grav/hilbertresearchfacility)
+ ruinSpawned = TRUE
+
+/obj/item/hilbertshotel/Destroy()
+ ejectRooms()
+ return ..()
+
+/obj/item/hilbertshotel/attack(mob/living/M, mob/living/user)
+ if(M.mind)
+ to_chat(user, "You invite [M] to the hotel.")
+ promptAndCheckIn(M)
+ else
+ to_chat(user, "[M] is not intelligent enough to understand how to use this device!")
+
+/obj/item/hilbertshotel/attack_self(mob/user)
+ . = ..()
+ promptAndCheckIn(user)
+
+/obj/item/hilbertshotel/proc/promptAndCheckIn(mob/user)
+ var/chosenRoomNumber = input(user, "What number room will you be checking into?", "Room Number") as null|num
+ if(!chosenRoomNumber)
+ return
+ if(chosenRoomNumber > SHORT_REAL_LIMIT)
+ to_chat(user, "You have to check out the first [SHORT_REAL_LIMIT] rooms before you can go to a higher numbered one!")
+ return
+ if((chosenRoomNumber < 1) || (chosenRoomNumber != round(chosenRoomNumber)))
+ to_chat(user, "That is not a valid room number!")
+ return
+ if(ismob(loc))
+ if(user == loc) //Not always the same as user
+ forceMove(get_turf(user))
+ if(!storageTurf) //Blame subsystems for not allowing this to be in Initialize
+ if(!GLOB.hhStorageTurf)
+ var/datum/map_template/hilbertshotelstorage/storageTemp = new()
+ var/datum/turf_reservation/storageReservation = SSmapping.RequestBlockReservation(3, 3)
+ storageTemp.load(locate(storageReservation.bottom_left_coords[1], storageReservation.bottom_left_coords[2], storageReservation.bottom_left_coords[3]))
+ GLOB.hhStorageTurf = locate(storageReservation.bottom_left_coords[1]+1, storageReservation.bottom_left_coords[2]+1, storageReservation.bottom_left_coords[3])
+ else
+ storageTurf = GLOB.hhStorageTurf
+ if(tryActiveRoom(chosenRoomNumber, user))
+ return
+ if(tryStoredRoom(chosenRoomNumber, user))
+ return
+ sendToNewRoom(chosenRoomNumber, user)
+
+
+/obj/item/hilbertshotel/proc/tryActiveRoom(var/roomNumber, var/mob/user)
+ if(activeRooms["[roomNumber]"])
+ var/datum/turf_reservation/roomReservation = activeRooms["[roomNumber]"]
+ do_sparks(3, FALSE, get_turf(user))
+ user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
+ return TRUE
+ else
+ return FALSE
+
+/obj/item/hilbertshotel/proc/tryStoredRoom(var/roomNumber, var/mob/user)
+ if(storedRooms["[roomNumber]"])
+ var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height)
+ hotelRoomTempEmpty.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
+ var/turfNumber = 1
+ for(var/i=0, iAs the sphere breaks apart, you're suddenly ejected into the depths of space!")
+ var/max = world.maxx-TRANSITIONEDGE
+ var/min = 1+TRANSITIONEDGE
+ var/list/possible_transtitons = list()
+ for(var/AZ in SSmapping.z_list)
+ var/datum/space_level/D = AZ
+ if (D.linkage == CROSSLINKED)
+ possible_transtitons += D.z_value
+ var/_z = pick(possible_transtitons)
+ var/_x = rand(min,max)
+ var/_y = rand(min,max)
+ var/turf/T = locate(_x, _y, _z)
+ A.forceMove(T)
+ qdel(room)
+
+ if(storedRooms.len)
+ for(var/x in storedRooms)
+ var/list/atomList = storedRooms[x]
+ for(var/atom/movable/A in atomList)
+ var/max = world.maxx-TRANSITIONEDGE
+ var/min = 1+TRANSITIONEDGE
+ var/list/possible_transtitons = list()
+ for(var/AZ in SSmapping.z_list)
+ var/datum/space_level/D = AZ
+ if (D.linkage == CROSSLINKED)
+ possible_transtitons += D.z_value
+ var/_z = pick(possible_transtitons)
+ var/_x = rand(min,max)
+ var/_y = rand(min,max)
+ var/turf/T = locate(_x, _y, _z)
+ A.forceMove(T)
+
+//Template Stuff
+/datum/map_template/hilbertshotel
+ name = "Hilbert's Hotel Room"
+ mappath = '_maps/templates/hilbertshotel.dmm'
+ var/landingZoneRelativeX = 2
+ var/landingZoneRelativeY = 8
+
+/datum/map_template/hilbertshotel/empty
+ name = "Empty Hilbert's Hotel Room"
+ mappath = '_maps/templates/hilbertshotelempty.dmm'
+
+/datum/map_template/hilbertshotel/lore
+ name = "Doctor Hilbert's Deathbed"
+ mappath = '_maps/templates/hilbertshotellore.dmm'
+
+/datum/map_template/hilbertshotelstorage
+ name = "Hilbert's Hotel Storage"
+ mappath = '_maps/templates/hilbertshotelstorage.dmm'
+
+
+//Turfs and Areas
+/turf/closed/indestructible/hotelwall
+ name = "hotel wall"
+ desc = "A wall designed to protect the security of the hotel's guests."
+ icon_state = "hotelwall"
+ canSmoothWith = list(/turf/closed/indestructible/hotelwall)
+ explosion_block = INFINITY
+
+/turf/open/indestructible/hotelwood
+ desc = "Stylish dark wood with extra reinforcement. Secured firmly to the floor to prevent tampering."
+ icon_state = "wood"
+ footstep = FOOTSTEP_WOOD
+ tiled_dirt = FALSE
+
+/turf/open/indestructible/hoteltile
+ desc = "Smooth tile with extra reinforcement. Secured firmly to the floor to prevent tampering."
+ icon_state = "showroomfloor"
+ footstep = FOOTSTEP_FLOOR
+ tiled_dirt = FALSE
+
+/turf/open/space/bluespace
+ name = "\proper bluespace hyperzone"
+ icon_state = "bluespace"
+ baseturfs = /turf/open/space/bluespace
+ flags_1 = NOJAUNT_1
+ explosion_block = INFINITY
+ var/obj/item/hilbertshotel/parentSphere
+
+/turf/open/space/bluespace/Entered(atom/movable/A)
+ . = ..()
+ A.forceMove(get_turf(parentSphere))
+
+/turf/closed/indestructible/hoteldoor
+ name = "Hotel Door"
+ icon_state = "hoteldoor"
+ explosion_block = INFINITY
+ var/obj/item/hilbertshotel/parentSphere
+
+/turf/closed/indestructible/hoteldoor/proc/promptExit(mob/living/user)
+ if(!isliving(user))
+ return
+ if(!user.mind)
+ return
+ if(!parentSphere)
+ to_chat(user, "The door seems to be malfunctioning and refuses to operate!")
+ return
+ if(alert(user, "Hilbert's Hotel would like to remind you that while we will do everything we can to protect the belongings you leave behind, we make no guarantees of their safety while you're gone, especially that of the health of any living creatures. With that in mind, are you ready to leave?", "Exit", "Leave", "Stay") == "Leave")
+ if(!user.canmove || (get_dist(get_turf(src), get_turf(user)) > 1)) //no teleporting around if they're dead or moved away during the prompt.
+ return
+ user.forceMove(get_turf(parentSphere))
+ do_sparks(3, FALSE, get_turf(user))
+
+/turf/closed/indestructible/hoteldoor/attack_ghost(mob/dead/observer/user)
+ if(!isobserver(user) || !parentSphere)
+ return ..()
+ user.forceMove(get_turf(parentSphere))
+
+//If only this could be simplified...
+/turf/closed/indestructible/hoteldoor/attack_tk(mob/user)
+ return //need to be close.
+
+/turf/closed/indestructible/hoteldoor/attack_hand(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_animal(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_paw(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_hulk(mob/living/carbon/human/user, does_attack_animation)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_larva(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_slime(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_robot(mob/user)
+ if(get_dist(get_turf(src), get_turf(user)) <= 1)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/AltClick(mob/user)
+ . = ..()
+ if(get_dist(get_turf(src), get_turf(user)) <= 1)
+ to_chat(user, "You peak through the door's bluespace peephole...")
+ user.reset_perspective(parentSphere)
+ user.set_machine(src)
+ var/datum/action/peepholeCancel/PHC = new
+ user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
+ PHC.Grant(user)
+
+/turf/closed/indestructible/hoteldoor/check_eye(mob/user)
+ if(get_dist(get_turf(src), get_turf(user)) >= 2)
+ user.unset_machine()
+ for(var/datum/action/peepholeCancel/PHC in user.actions)
+ PHC.Trigger()
+
+/datum/action/peepholeCancel
+ name = "Cancel View"
+ desc = "Stop looking through the bluespace peephole."
+ button_icon_state = "cancel_peephole"
+
+/datum/action/peepholeCancel/Trigger()
+ . = ..()
+ to_chat(owner, "You move away from the peephole.")
+ owner.reset_perspective()
+ owner.clear_fullscreen("remote_view", 0)
+ qdel(src)
+
+/area/hilbertshotel
+ name = "Hilbert's Hotel Room"
+ icon_state = "hilbertshotel"
+ requires_power = FALSE
+ has_gravity = TRUE
+ noteleport = TRUE
+ hidden = TRUE
+ unique = FALSE
+ dynamic_lighting = DYNAMIC_LIGHTING_FORCED
+ ambientsounds = list('sound/ambience/servicebell.ogg')
+ var/roomnumber = 0
+ var/obj/item/hilbertshotel/parentSphere
+ var/datum/turf_reservation/reservation
+ var/turf/storageTurf
+
+/area/hilbertshotel/Entered(atom/movable/AM)
+ . = ..()
+ if(istype(AM, /obj/item/hilbertshotel))
+ relocate(AM)
+ var/list/obj/item/hilbertshotel/hotels = AM.GetAllContents(/obj/item/hilbertshotel)
+ for(var/obj/item/hilbertshotel/H in hotels)
+ if(parentSphere == H)
+ relocate(H)
+
+/area/hilbertshotel/proc/relocate(obj/item/hilbertshotel/H)
+ if(prob(0.135685)) //Because screw you
+ qdel(H)
+ return
+ var/turf/targetturf = find_safe_turf()
+ if(!targetturf)
+ if(GLOB.blobstart.len > 0)
+ targetturf = get_turf(pick(GLOB.blobstart))
+ else
+ CRASH("Unable to find a blobstart landmark")
+ var/turf/T = get_turf(H)
+ var/area/A = T.loc
+ log_game("[H] entered itself. Moving it to [loc_name(targetturf)].")
+ message_admins("[H] entered itself. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
+ for(var/mob/M in A)
+ to_chat(M, "[H] almost implodes in upon itself, but quickly rebounds, shooting off into a random point in space!")
+ H.forceMove(targetturf)
+
+/area/hilbertshotel/Exited(atom/movable/AM)
+ . = ..()
+ if(ismob(AM))
+ var/mob/M = AM
+ if(M.mind)
+ var/stillPopulated = FALSE
+ var/list/currentLivingMobs = GetAllContents(/mob/living) //Got to catch anyone hiding in anything
+ for(var/mob/living/L in currentLivingMobs) //Check to see if theres any sentient mobs left.
+ if(L.mind)
+ stillPopulated = TRUE
+ break
+ if(!stillPopulated)
+ storeRoom()
+
+/area/hilbertshotel/proc/storeRoom()
+ var/roomSize = (reservation.top_right_coords[1]-reservation.bottom_left_coords[1]+1)*(reservation.top_right_coords[2]-reservation.bottom_left_coords[2]+1)
+ var/storage[roomSize]
+ var/turfNumber = 1
+ var/obj/item/abstracthotelstorage/storageObj = new(storageTurf)
+ storageObj.roomNumber = roomnumber
+ storageObj.parentSphere = parentSphere
+ storageObj.name = "Room [roomnumber] Storage"
+ for(var/i=0, iIt's to far away to scan!")
+ return
+ var/obj/item/hilbertshotel/sphere = target
+ if(sphere.activeRooms.len)
+ to_chat(user, "Currently Occupied Rooms:")
+ for(var/roomnumber in sphere.activeRooms)
+ to_chat(user, roomnumber)
+ else
+ to_chat(user, "No currenty occupied rooms.")
+ if(sphere.storedRooms.len)
+ to_chat(user, "Vacated Rooms:")
+ for(var/roomnumber in sphere.storedRooms)
+ to_chat(user, roomnumber)
+ else
+ to_chat(user, "No vacated rooms.")
+
+/obj/effect/mob_spawn/human/doctorhilbert
+ name = "Doctor Hilbert"
+ mob_name = "Doctor Hilbert"
+ mob_gender = "male"
+ assignedrole = null
+ ghost_usable = FALSE
+ oxy_damage = 500
+ mob_species = /datum/species/skeleton
+ id_job = "Head Researcher"
+ id_access = ACCESS_RESEARCH
+ id_access_list = list(ACCESS_AWAY_GENERIC3, ACCESS_RESEARCH)
+ instant = TRUE
+ id = /obj/item/card/id/silver
+ uniform = /obj/item/clothing/under/rank/research_director
+ shoes = /obj/item/clothing/shoes/sneakers/brown
+ back = /obj/item/storage/backpack/satchel/leather
+ suit = /obj/item/clothing/suit/toggle/labcoat
+
+/obj/item/paper/crumpled/docslogs
+ name = "Research Logs"
+
+/obj/item/paper/crumpled/docslogs/Initialize()
+ . = ..()
+ GLOB.hhmysteryRoomNumber = rand(1, SHORT_REAL_LIMIT)
+ info = {"
Research Logs
+ I might just be onto something here!
+ The strange space-warping properties of bluespace have been known about for awhile now, but I might be on the verge of discovering a new way of harnessing it.
+ It's too soon to say for sure, but this might be the start of something quite important!
+ I'll be sure to log any major future breakthroughs. This might be a lot more than I can manage on my own, perhaps I should hire that secretary after all...
+
Breakthrough!
+ I can't believe it, but I did it! Just when I was certain it couldn't be done, I made the final necessary breakthrough.
+ Exploiting the effects of space dilation caused by specific bluespace structures combined with a precise use of geometric calculus, I've discovered a way to correlate an infinite amount of space within a finite area!
+ While the potential applications are endless, I utilized it in quite a nifty way so far by designing a system that recursively constructs subspace rooms and spatially links them to any of the infinite infinitesimally distinct points on the spheres surface.
+ I call it: Hilbert's Hotel!
+
Goodbye
+ I can't take this anymore. I know what happens next, and the fear of what is coming leaves me unable to continue working.
+ Any fool in my field has heard the stories. It's not that I didn't believe them, it's just... I guess I underestimated the importance of my own research...
+ Robert has reported a further increase in frequency of the strange, prying visitors who ask questions they have no business asking. I've requested him to keep everything on strict lockdown and have permanently dismissed all other assistants.
+ I've also instructed him to use the encryption method we discussed for any important quantitative data. The poor lad... I don't think he truly understands what he's gotten himself into...
+ It's clear what happens now. One day they'll show up uninvited, and claim my research as their own, leaving me as nothing more than a bullet ridden corpse floating in space.
+ I can't stick around to the let that happen.
+ I'm escaping into the very thing that brought all this trouble to my doorstep in the first place - my hotel.
+ I'll be in [uppertext(num2hex(GLOB.hhmysteryRoomNumber, 0))] (That will make sense to anyone who should know)
+ I'm sorry that I must go like this. Maybe one day things will be different and it will be safe to return... maybe...
+ Goodbye
+
+ Doctor Hilbert"}
+
+/obj/item/paper/crumpled/robertsworkjournal
+ name = "Work Journal"
+ info = {"
First Week!
+ First week on the new job. It's a secretarial position, but hey, whatever pays the bills. Plus it seems like some interesting stuff goes on here.
+ Doc says its best that I don't openly talk about his research with others, I guess he doesn't want it getting out or something. I've caught myself slipping a few times when talking to others, it's hard not to brag about something this cool!
+ I'm not really sure why I'm choosing to journal this. Doc seems to log everything. He says it's incase he discovers anything important.
+ I guess that's why I'm doing it too, I've always wanted to be a part of something important.
+ Here's to a new job and to becoming a part of something important!
+
Weird times...
+ Things are starting to get a little strange around here. Just weeks after Doc's amazing breakthrough, weird visitors have began showing up unannounced, asking strange things about Doc's work.
+ I knew Doc wasn't a big fan of company, but even he seemed strangely unnerved when I told him about the visitors.
+ He said it's important that from here on out we keep tight security on everything, even other staff members.
+ He also said something about securing data, something about hexes. What's that mean? Some sort of curse? Doc never struck me as the magic type...
+ He often uses a lot of big sciencey words that I don't really understand, but I kinda dig it, it makes me feel like I'm witnessing something big.
+ I hope things go back to normal soon, but I guess that's the price you pay for being a part of something important.
+