diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 53348b3467..a09c96ad30 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -30,7 +30,7 @@ #define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params) #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called #define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human) -#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob) +#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob, list/examine_list) #define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides) //Positions for overrides list #define EXAMINE_POSITION_ARTICLE 1 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 3fb149d071..9febca663d 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -523,3 +523,10 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S #define NIGHTSHIFT_AREA_NONE 4 //default/highest. #define UNTIL(X) while(!(X)) stoplag() + + +//Scavenging element defines for special loot "events". +#define SCAVENGING_FOUND_NOTHING "found_nothing" +#define SCAVENGING_SPAWN_MOUSE "spawn_mouse" +#define SCAVENGING_SPAWN_MICE "spawn_mice" +#define SCAVENGING_SPAWN_TOM "spawn_tom_the_mouse" diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index a34b3ce67c..754b56a202 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -234,38 +234,20 @@ //2. Gets a number between 1 and that total //3. For each element in the list, subtracts its weighting from that number //4. If that makes the number 0 or less, return that element. -/proc/pickweight(list/L) +/proc/pickweight(list/L, base_weight = 1) var/total = 0 var/item for (item in L) if (!L[item]) - L[item] = 1 + L[item] = base_weight total += L[item] - total = rand(1, total) + total = rand() * total for (item in L) - total -=L [item] + total -= L[item] if (total <= 0) return item - return null - -/proc/pickweightAllowZero(list/L) //The original pickweight proc will sometimes pick entries with zero weight. I'm not sure if changing the original will break anything, so I left it be. - var/total = 0 - var/item - for (item in L) - if (!L[item]) - L[item] = 0 - total += L[item] - - total = rand(0, total) - for (item in L) - total -=L [item] - if (total <= 0 && L[item]) - return item - - return null - //Pick a random element from the list and remove it from the list. /proc/pick_n_take(list/L) RETURN_TYPE(L[_].type) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 2827e40120..d3ad4dcaec 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -311,7 +311,7 @@ GLOBAL_LIST_EMPTY(species_list) else return "unknown" -/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null, ignorehelditem = 0) +/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null, ignorehelditem = FALSE, resume_time = 0 SECONDS) if(!user || !target) return 0 var/user_loc = user.loc @@ -330,10 +330,10 @@ GLOBAL_LIST_EMPTY(species_list) var/endtime = world.time+time var/starttime = world.time . = 1 - while (world.time < endtime) + while (world.time + resume_time < endtime) stoplag(1) if (progress) - progbar.update(world.time - starttime) + progbar.update(world.time - starttime + resume_time) if(QDELETED(user) || QDELETED(target)) . = 0 break @@ -365,7 +365,7 @@ GLOBAL_LIST_EMPTY(species_list) checked_health["health"] = health return ..() -/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null, required_mobility_flags = (MOBILITY_USE|MOBILITY_MOVE)) +/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null, required_mobility_flags = (MOBILITY_USE|MOBILITY_MOVE), resume_time = 0 SECONDS) if(!user) return 0 var/atom/Tloc = null @@ -394,10 +394,10 @@ GLOBAL_LIST_EMPTY(species_list) var/starttime = world.time . = 1 var/mob/living/L = isliving(user) && user //evals to last thing eval'd - while (world.time < endtime) + while (world.time + resume_time < endtime) stoplag(1) if (progress) - progbar.update(world.time - starttime) + progbar.update(world.time - starttime + resume_time) if(drifting && !user.inertia_dir) drifting = 0 diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index a202afd905..df3f24f0dc 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -361,7 +361,7 @@ SUBSYSTEM_DEF(vote) picked = S runnable_storytellers[S] *= round(stored_gamemode_votes[initial(S.name)]*100000,1) if(!picked) - picked = pickweightAllowZero(runnable_storytellers) + picked = pickweight(runnable_storytellers, 0) GLOB.dynamic_storyteller_type = picked if("map") var/datum/map_config/VM = config.maplist[.] diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index ebddc187ae..9c6bb2ebfd 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -253,7 +253,7 @@ var/datum/ai_laws/lawtype var/list/law_weights = CONFIG_GET(keyed_list/law_weight) while(!lawtype && law_weights.len) - var/possible_id = pickweightAllowZero(law_weights) + var/possible_id = pickweight(law_weights, 0) lawtype = lawid_to_type(possible_id) if(!lawtype) law_weights -= possible_id diff --git a/code/datums/components/archaeology.dm b/code/datums/components/archaeology.dm deleted file mode 100644 index b5740650e9..0000000000 --- a/code/datums/components/archaeology.dm +++ /dev/null @@ -1,95 +0,0 @@ -/datum/component/archaeology - dupe_mode = COMPONENT_DUPE_UNIQUE - var/list/archdrops = list(/obj/item/bikehorn = list(ARCH_PROB = 100, ARCH_MAXDROP = 1)) // honk~ - var/prob2drop - var/dug - var/datum/callback/callback - -/datum/component/archaeology/Initialize(list/_archdrops = list(), datum/callback/_callback) - archdrops = _archdrops - for(var/i in archdrops) - if(isnull(archdrops[i][ARCH_MAXDROP])) - archdrops[i][ARCH_MAXDROP] = 1 - stack_trace("ARCHAEOLOGY WARNING: [parent] contained a null max_drop value in [i].") - if(isnull(archdrops[i][ARCH_PROB])) - archdrops[i][ARCH_PROB] = 100 - stack_trace("ARCHAEOLOGY WARNING: [parent] contained a null probability value in [i].") - callback = _callback - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY,.proc/Dig) - RegisterSignal(parent, COMSIG_ATOM_EX_ACT, .proc/BombDig) - RegisterSignal(parent, COMSIG_ATOM_SING_PULL, .proc/SingDig) - -/datum/component/archaeology/InheritComponent(datum/component/archaeology/A, i_am_original) - var/list/other_archdrops = A.archdrops - var/list/_archdrops = archdrops - for(var/I in other_archdrops) - _archdrops[I] += other_archdrops[I] - -/datum/component/archaeology/proc/Dig(datum/source, obj/item/I, mob/living/user) - if(dug) - to_chat(user, "Looks like someone has dug here already.") - return - - if(!isturf(user.loc)) - return - - if(I.tool_behaviour == TOOL_SHOVEL || I.tool_behaviour == TOOL_MINING) - to_chat(user, "You start digging...") - - if(I.use_tool(parent, user, 40, volume=50)) - to_chat(user, "You dig a hole.") - gets_dug() - dug = TRUE - SSblackbox.record_feedback("tally", "pick_used_mining", 1, I.type) - return COMPONENT_NO_AFTERATTACK - -/datum/component/archaeology/proc/gets_dug() - if(dug) - return - else - var/turf/open/OT = get_turf(parent) - for(var/thing in archdrops) - var/maxtodrop = archdrops[thing][ARCH_MAXDROP] - for(var/i in 1 to maxtodrop) - if(prob(archdrops[thing][ARCH_PROB])) // can't win them all! - new thing(OT) - - if(isopenturf(OT)) - if(OT.postdig_icon_change) - if(istype(OT, /turf/open/floor/plating/asteroid/) && !OT.postdig_icon) - var/turf/open/floor/plating/asteroid/AOT = parent - AOT.icon_plating = "[AOT.environment_type]_dug" - AOT.icon_state = "[AOT.environment_type]_dug" - else - if(isplatingturf(OT)) - var/turf/open/floor/plating/POT = parent - POT.icon_plating = "[POT.postdig_icon]" - POT.icon_state = "[OT.postdig_icon]" - - if(OT.slowdown) //Things like snow slow you down until you dig them. - OT.slowdown = 0 - dug = TRUE - if(callback) - callback.Invoke() - -/datum/component/archaeology/proc/SingDig(datum/source, S, current_size) - switch(current_size) - if(STAGE_THREE) - if(prob(30)) - gets_dug() - if(STAGE_FOUR) - if(prob(50)) - gets_dug() - else - if(current_size >= STAGE_FIVE && prob(70)) - gets_dug() - -/datum/component/archaeology/proc/BombDig(datum/source, severity, target) - switch(severity) - if(3) - return - if(2) - if(prob(20)) - gets_dug() - if(1) - gets_dug() diff --git a/code/datums/elements/scavenging.dm b/code/datums/elements/scavenging.dm new file mode 100644 index 0000000000..b2ca7adcc3 --- /dev/null +++ b/code/datums/elements/scavenging.dm @@ -0,0 +1,164 @@ + /* + * Scavenging element. Its scope shouldn't elude your imagination. + * Basically loot piles that can be searched through for some items. + * In my opinion, these are more engaging than normal maintenance loot spawners. + * The loot doesn't have to be strictly made of items and objects, you could also use it to invoke some "events" + * such as mice, rats, an halloween spook, persistent relics, traps, etcetera, go wild. + */ +/datum/element/scavenging + element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH + id_arg_index = 3 + + var/list/loot_left_per_atom = list() //loot left per attached atom. + var/list/loot_table //pickweight list of available loot. + var/list/unique_loot //limited loot, once the associated value reaches zero, its key is removed from loot_table + var/scavenge_time = 12 SECONDS //how much time it takes + var/can_use_hands = TRUE //bare handed scavenge time multiplier. If set to zero, only tools are usable. + var/list/tool_types //which tool types the player can use instead of scavenging by hand, associated value is their speed. + var/del_atom_on_depletion = FALSE //Will the atom be deleted when there is no loot left? + var/list/search_texts = list("searches through ", "search through ", "You hear rummaging...") + + var/mean_loot_weight = 0 + var/list/progress_per_atom = list() //seconds of ditched progress per atom, used to resume the work instead of starting over. + var/static/list/players_busy_scavenging = list() //players already busy scavenging. + +/datum/element/scavenging/Attach(atom/target, amount = 5, list/loot, list/unique, time = 10 SECONDS, hands = TRUE, list/tools, list/texts, del_deplete = FALSE) + . = ..() + if(. == ELEMENT_INCOMPATIBLE || !length(loot) || !amount || !istype(target) || isarea(target)) + return ELEMENT_INCOMPATIBLE + loot_left_per_atom[target] = amount + if(!loot_table) + loot_table = loot + for(var/A in loot_table) //tally the list weights + mean_loot_weight += loot_table[A] + mean_loot_weight /= length(loot_table) + if(!unique_loot) + unique_loot = unique || list() + scavenge_time = time + can_use_hands = hands + tool_types = tools + if(texts) + search_texts = texts + del_atom_on_depletion = del_deplete + if(can_use_hands) + RegisterSignal(target, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW), .proc/scavenge_barehanded) + if(tool_types) + RegisterSignal(target, COMSIG_PARENT_ATTACKBY, .proc/scavenge_tool) + RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine) + +/datum/element/scavenging/Detach(atom/target) + . = ..() + loot_left_per_atom -= target + progress_per_atom -= target + UnregisterSignal(target, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_PARENT_ATTACKBY, COMSIG_PARENT_EXAMINE)) + +/datum/element/scavenging/proc/on_examine(atom/source, mob/user, list/examine_list) + var/text + var/methods = tool_types + if(can_use_hands) + if(!length(methods)) + methods = list("bare handed") + else + methods += "simply bare handed" + text = english_list(methods, "", " or ") + . += "Looks like [source.p_they()] can be scavenged[length(tool_types) ? " with either a" : ""] [text]" + +/datum/element/scavenging/proc/scavenge_barehanded(atom/source, mob/user) + scavenge(source, user, 1) + return COMPONENT_NO_ATTACK_HAND + +/datum/element/scavenging/proc/scavenge_tool(atom/source, obj/item/I, mob/living/user, params) + if(mob.a_intent == INTENT_HARM) //Robust trash disposal techniques! + return + var/speed_multi = tool_types[I.tool_behaviour] + if(!speed_multi) + return + scavenge(source, user, speed_multi) + return COMPONENT_NO_AFTERATTACK + +/datum/element/scavenging/proc/scavenge(atom/source, mob/user, speed_multi = 1) + if(players_busy_scavenging[user]) + return + players_busy_scavenging[user] = TRUE + var/progress_done = progress_per_atom[source] + var/len_messages = length(search_texts) + var/msg_first_person + if(len_messages >= 2) + msg_first_person = "You [progress_done ? "resume a ditched task and " : ""][search_texts[2]] [src]." + var/msg_blind + if(len_messages >= 3) + msg_blind = "[search_texts[3]]" + user.visible_message("[user] [search_texts[1]] [src].", msg_first_person, msg_blind) + if(do_after(user, scavenge_time, TRUE, source, TRUE, CALLBACK(src, .proc/set_progress, source, world.time), resume_time = progress_done)) + spawn_loot(source, user) + players_busy_scavenging -= user + progress_per_atom -= source + +/datum/element/scavenging/proc/set_progress(atom/source, start_time) + progress_per_atom[source] = world.time - start_time + +/datum/element/scavenging/proc/spawn_loot(atom/source, mob/user) + var/loot = pickweight(loot_table) + var/special = TRUE + var/free = FALSE + if(!loot_left_per_atom[source]) + to_chat(user, "Looks likes there is nothing worth of interest left in [src] anymore, further attempts would be futile.") + return + switch(loot) // TODO: datumize these out. + if(SCAVENGING_FOUND_NOTHING) + to_chat(user, "You found nothing, better luck next time.") + free = TRUE //doesn't consume the loot pile. + if(SCAVENGING_SPAWN_MOUSE) + var/nasty_rodent = pick("mouse", "rodent", "squeaky critter", "stupid pest", "annoying cable chewer", "nasty, ugly, evil, disease-ridden rodent") + to_chat(user, "You found something in [src]... no wait, that's just another [nasty_rodent].") + new /mob/living/simple_animal/mouse(source.loc) + if(SCAVENGING_SPAWN_MICE) + user.visible_message("A small gang of mice emerges from [source].", \ + "You found something in [src]... no wait, that's just another- no wait, that's a lot of damn mice.") + for(var/i in 1 to rand(4, 6)) + new /mob/living/simple_animal/mouse(source.loc) + if(SCAVENGING_SPAWN_TOM) + if(GLOB.tom_existed) //There can only be one. + to_chat(user, "You found nothing, better luck next time.") + free = TRUE + else + to_chat(user, "You found something in [src]... no wait, that's Tom, the mouse! What is he doing here?") + new /mob/living/simple_animal/mouse/brown/Tom(source.loc) + else + special = FALSE + + if(!special) //generic loot. Nothing too strange like more loot spawners anyway. + var/atom/A = new loot(source.loc) + if(isitem(A) && !user.get_active_held_item()) + user.put_in_hands(A) + var/rarity_append = "." + switch(loot_table[loot]/mean_loot_weight*100) + if(0 to 1) + rarity_append = "! AMAZING!" + if(1 to 2) + rarity_append = "! Woah!" + if(2 to 5) + rarity_append = ". Rare!" + if(5 to 10) + rarity_append = ". Great." + if(10 to 25) + rarity_append = ". Nice." + if(20 to 50) + rarity_append = ". Not bad." + to_chat(user, "You found something in [src]... it's \a [A][rarity_append]") + + if(unique_loot[loot]) + var/loot_left = --unique_loot[loot] + if(!loot_left) + loot_table -= loot + unique_loot -= loot + mean_loot_weight = 0 + for(var/A in loot_table) //re-tally the list weights + mean_loot_weight += loot_table[A] + mean_loot_weight /= length(loot_table) + + if(!free) + --loot_left_per_atom[source] + if(del_atom_on_depletion && !loot_left_per_atom[source]) + source.visible_message("[src] has been looted clean.") + qdel(source) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 5affeba6d6..57919863f2 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -272,7 +272,7 @@ reports += config.mode_reports[config_tag] Count++ for(var/i in Count to rand(3,5)) //Between three and five wrong entries on the list. - var/false_report_type = pickweightAllowZero(report_weights) + var/false_report_type = pickweight(report_weights, 0) report_weights[false_report_type] = 0 //Make it so the same false report won't be selected twice reports += config.mode_reports[false_report_type] diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 04f14692e3..851a041aab 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -483,7 +483,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) if(!SSmapping.station_room_templates[t]) log_world("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list") templates -= t - template_name = pickweightAllowZero(templates) + template_name = pickweight(templates, 0) if(!template_name) GLOB.stationroom_landmarks -= src qdel(src) diff --git a/code/game/objects/structures/loot_pile.dm b/code/game/objects/structures/loot_pile.dm new file mode 100644 index 0000000000..0886c1c8b7 --- /dev/null +++ b/code/game/objects/structures/loot_pile.dm @@ -0,0 +1,66 @@ + /* + * Loot piles structures, somewhat inspired from Polaris 13 ones but without the one search per pile ckey/mind restriction + * because the actual code is located its own element and has enough variables already. the piles themselves merely cosmetical. + */ +/obj/structure/loot_pile + name = "pile of junk" + desc = "Lots of junk lying around. They say one man's trash is another man's treasure." + icon = 'icons/obj/loot_piles.dmi' + density = FALSE + anchored = TRUE + var/loot_amount = 5 + var/delete_on_depletion = FALSE + var/can_use_hands = TRUE + var/scavenge_time = 12 SECONDS + var/allowed_tools = list(TOOL_SHOVEL = 0.6) //list of tool_behaviours with associated speed multipliers (lower is better) + var/icon_states_to_use = list("junk_pile1", "junk_pile2", "junk_pile3", "junk_pile4", "junk_pile5") + var/list/loot = list( + SCAVENGING_FOUND_NOTHING = 50, + SCAVENGING_SPAWN_MOUSE = 10, + SCAVENGING_SPAWN_MICE = 5, + SCAVENGING_SPAWN_TOM = 1, + /obj/item/flashlight/flare = 10, + /obj/item/flashlight/glowstick = 10, + /obj/item/flashlight/glowstick/blue = 10, + /obj/item/flashlight/glowstick/orange = 10, + /obj/item/flashlight/glowstick/red = 10, + /obj/item/flashlight/glowstick/yellow = 10, + /obj/item/clothing/mask/gas = 5, + /obj/item/clothing/mask/breath = 10, + /obj/item/storage/box = 10, + /obj/item/clothing/shoes/galoshes = 2, + /obj/item/clothing/shoes/sneakers/black = 10, + /obj/item/clothing/gloves/color/fyellow = 5, + /obj/item/clothing/gloves/color/yellow = 2, + /obj/item/clothing/glasses/sunglasses = 3, + /obj/item/clothing/glasses/meson = 3, + /obj/item/clothing/glasses/welding = 3, + /obj/item/clothing/head/hardhat = 10, + /obj/item/clothing/head/ushanka = 10, + /obj/item/clothing/head/welding = 5, + /obj/item/clothing/suit/hazardvest = 10, + /obj/item/clothing/under/syndicate/tacticool = 5, + /obj/item/clothing/under/pants/camo = 10, + /obj/item/stack/spacecash/c10 = 20, + /obj/item/stack/spacecash/c20 = 20, + /obj/item/stack/spacecash/c50 = 20, + /obj/item/radio/headset = 10) + + /* + * Associated values in this list are not weights but numbers of times the kery can be rolled + * before being removed from ALL piles with same kind. This is why I wanted 'scavenging' to be an element and not a component. + */ + var/list/unique_loot = list(/obj/item/clothing/gloves/color/yellow = 2, SCAVENGING_SPAWN_TOM = 1) + +/obj/structure/loot_pile/Initialize() + . = ..() + icon_state = pick(icon_states_to_use) + +/obj/structure/loot_pile/ComponentInitialize() + . = ..() + AddElement(/datum/element/scavenging, loot_amount, loot, unique_loot, scavenge_time, can_use_hands, allowed_tools, null, delete_on_depletion) + +/obj/structure/loot_pile/infinite + name = "endless pile of junk." + desc = "Lots of awful code lying around. They don't say one coder's trash is another coder's treasure though..." + loot_amount = INFINITY diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index cf10f87bf8..df5e6004ba 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -48,7 +48,7 @@ var/datum/traitor_class/class = GLOB.traitor_classes[C] var/weight = LOGISTIC_FUNCTION(1.5*class.weight,chaos_weight,class.chaos,0) weights[C] = weight * 1000 - var/choice = pickweightAllowZero(weights) + var/choice = pickweight(weights, 0) if(!choice) choice = TRAITOR_HUMAN // it's an "easter egg" var/datum/traitor_class/actual_class = GLOB.traitor_classes[choice] diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 370442d4c4..7f83bb9f9b 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -97,6 +97,8 @@ body_color = "brown" icon_state = "mouse_brown" +GLOBAL_VAR(tom_existed) + //TOM IS ALIVE! SQUEEEEEEEE~K :) /mob/living/simple_animal/mouse/brown/Tom name = "Tom" @@ -106,6 +108,10 @@ response_harm = "splats" gold_core_spawnable = NO_SPAWN +/mob/living/simple_animal/mouse/brown/Tom/Initialize() + . = ..() + GLOB.tom_existed = TRUE + /obj/item/reagent_containers/food/snacks/deadmouse name = "dead mouse" desc = "It looks like somebody dropped the bass on it. A lizard's favorite meal." diff --git a/icons/obj/loot_piles.dmi b/icons/obj/loot_piles.dmi new file mode 100644 index 0000000000..3d83d6612e Binary files /dev/null and b/icons/obj/loot_piles.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 3b3bb74df1..147c91c92e 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -516,6 +516,7 @@ #include "code\datums\elements\ghost_role_eligibility.dm" #include "code\datums\elements\mob_holder.dm" #include "code\datums\elements\polychromic.dm" +#include "code\datums\elements\scavenging.dm" #include "code\datums\elements\spellcasting.dm" #include "code\datums\elements\swimming.dm" #include "code\datums\elements\sword_point.dm" @@ -1119,6 +1120,7 @@ #include "code\game\objects\structures\lattice.dm" #include "code\game\objects\structures\life_candle.dm" #include "code\game\objects\structures\loom.dm" +#include "code\game\objects\structures\loot_pile.dm" #include "code\game\objects\structures\manned_turret.dm" #include "code\game\objects\structures\memorial.dm" #include "code\game\objects\structures\mineral_doors.dm"