/datum/element/lootable var/chance_nothing = 0 // Unlucky people might need to loot multiple spots to find things. var/chance_uncommon = 10 // Probability of pulling from the uncommon_loot list. var/chance_rare = 1 // Ditto, but for rare_loot list. var/chance_gamma = 0 // Singledrop global loot table shared with all piles. var/allow_multiple_looting = TRUE // If true, the same person can loot multiple times. Mostly for debugging. var/loot_depletion = FALSE // If true, loot piles can be 'depleted' after a certain number of searches by different players, where no more loot can be obtained. var/loot_left = 0 // Maximum number of times a pile can be looted before no loot will remain for anyone var/delete_on_depletion = FALSE // If true, and if the loot gets depleted as above, the pile is deleted. var/list/unlucky_loot = list() // Unlucky is the worst tier. Only people with the unlucky trait can get this stuff. Primed grenades, dangerous syringes, etc. var/list/common_loot = list() // Common is generally less-than-useful junk and filler, at least for maint loot piles. var/list/uncommon_loot = list() // Uncommon is actually maybe some useful items, usually the reason someone bothers looking inside. var/list/rare_loot = list() // Rare is really powerful, or at least unique items. var/static/list/piles_looted = list() // Keeps track of the number of times a specific pile has been looted if the specific lootable type has loot_depletion on /datum/element/lootable/Attach(atom/target) . = ..() if(!isatom(target)) return ELEMENT_INCOMPATIBLE RegisterSignal(target, COMSIG_LOOT_REWARD, PROC_REF(loot)) /datum/element/lootable/Detach(atom/target) . = ..() if(loot_depletion) piles_looted -= REF(target) UnregisterSignal(target, COMSIG_LOOT_REWARD) /// Calculates and drops loot, the source's turf is where it will be dropped, L is the searching mob, and searched_by is a passed list for storing who has searched a loot pile. /datum/element/lootable/proc/loot(atom/source,mob/living/L,var/list/searched_by, wake_chance = 0) SIGNAL_HANDLER // The loot's all gone. if(loot_depletion) var/looted_count = piles_looted[REF(source)] if(looted_count >= loot_left) to_chat(L, span_warning("\The [source] has been picked clean.")) return // You got unlucky. if(chance_nothing && prob(chance_nothing)) to_chat(L, span_warning("Nothing in \the [source] really catches your eye...")) return if(L && islist(searched_by)) // This can handle no mob and no list if you just want to use this as a way to hold drop tables //You already searched this one if((L.ckey in searched_by) && !allow_multiple_looting) to_chat(L, span_warning("You can't find anything else vaguely useful in \the [source]. Another set of eyes might, however.")) return searched_by |= L.ckey // List is stored in the caller! // You found something! var/obj/item/loot = null var/span = "notice" // Blue if(HAS_TRAIT(L, TRAIT_UNLUCKY) && unlucky_loot.len) // If you're unlucky, you will always find bad stuff. loot = produce_unlucky_item(source) span = "cult" // Purple and bold. if(prob(1)) to_chat(L, span_danger("You cut your hand on something in the trash!")) L.apply_damage(2, BRUTE, pick(BP_L_HAND, BP_R_HAND), used_weapon = "sharp object") var/datum/disease/advance/random/random_disease = new /datum/disease/advance/random() random_disease.spread_flags |= DISEASE_SPREAD_NON_CONTAGIOUS L.ForceContractDisease(random_disease) else if(prob(chance_uncommon) && uncommon_loot.len) // You might still get something good. loot = produce_uncommon_item(source) span = "alium" // Green else if(prob(chance_rare) && rare_loot.len) // You won THE GRAND PRIZE! loot = produce_rare_item(source) span = "cult" // Purple and bold. else if(prob(chance_gamma) && GLOB.unique_gamma_loot.len) // ULTRA GRAND PRIZE loot = produce_gamma_item(source) span = "cult" // Purple and bold. else // Welp. loot = produce_common_item(source) // Handle randomized items in our tables. if(istype(loot,/obj/random)) var/obj/random/randy = loot var/new_I = randy.spawn_item() QDEL_SWAP(loot,new_I) //We either have an item to hand over or we don't, at this point! if(!loot) return loot.forceMove(get_turf(source)) var/final_message = "You found \a [loot]!" switch(span) if("notice") final_message = span_notice(final_message) if("cult") final_message = span_cult(final_message) if("alium") final_message = span_alium(final_message) to_chat(L, span_info(final_message)) var/disturbed_sleep = rand(1,100) //spawning of mobs, for now only the trash panda. if(disturbed_sleep <= wake_chance) new /mob/living/simple_mob/animal/passive/raccoon(get_turf(source)) source.visible_message("A raccoon jumps out of the trash!.") // Check if we should delete on depletion if(!loot_depletion) return // Add to looted piles if not already one if(!(REF(source) in piles_looted)) piles_looted[REF(source)] = 0 // Increase the looted count till we've hit our limit piles_looted[REF(source)] += 1 if(piles_looted[REF(source)] < loot_left) return to_chat(L, span_warning("You seem to have gotten the last of the spoils in \the [source].")) if(delete_on_depletion) qdel(source) /datum/element/lootable/proc/produce_unlucky_item(atom/source) var/path = pick(unlucky_loot) return new path(source) /datum/element/lootable/proc/produce_common_item(atom/source) var/path = pick(common_loot) return new path(source) /datum/element/lootable/proc/produce_uncommon_item(atom/source) var/path = pick(uncommon_loot) return new path(source) /datum/element/lootable/proc/produce_rare_item(atom/source) var/path = pick(rare_loot) return new path(source) /// These are types that can only spawn once, and then will be removed from this list. /datum/element/lootable/proc/produce_gamma_item(atom/source) var/path = pick_n_take(GLOB.unique_gamma_loot) if(!path) //Tapped out, reallocate? for(var/P in GLOB.allocated_gamma_loot) var/datum/weakref/WF = GLOB.allocated_gamma_loot[P] var/obj/item/I = WF?.resolve() if(QDELETED(I) || istype(I.loc,/obj/machinery/computer/cryopod)) restore_gamma_loot(P) path = P break if(path) var/obj/item/I = new path(source) GLOB.allocated_gamma_loot[path] = WEAKREF(I) return I return produce_rare_item(source) /// Restores a removed gamma loot item back to the loot table /proc/restore_gamma_loot(var/w_type) GLOB.allocated_gamma_loot -= w_type GLOB.unique_gamma_loot += w_type