Done, tested, too many options.
This commit is contained in:
@@ -530,3 +530,10 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
|
||||
#define SCAVENGING_SPAWN_MOUSE "spawn_mouse"
|
||||
#define SCAVENGING_SPAWN_MICE "spawn_mice"
|
||||
#define SCAVENGING_SPAWN_TOM "spawn_tom_the_mouse"
|
||||
|
||||
//Scavenging element defines for ckey/mind restrictions.
|
||||
#define NO_LOOT_RESTRICTION 0
|
||||
#define LOOT_RESTRICTION_MIND 1
|
||||
#define LOOT_RESTRICTION_CKEY 2
|
||||
#define LOOT_RESTRICTION_MIND_PILE 3 //limited to the current pile.
|
||||
#define LOOT_RESTRICTION_CKEY_PILE 4 //Idem
|
||||
|
||||
@@ -16,13 +16,17 @@
|
||||
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/list/search_texts = list("starts searching through", "start searching through", "You hear rummaging...")
|
||||
var/loot_restriction = NO_LOOT_RESTRICTION
|
||||
var/maximum_loot_per_player = 1 //only relevant if there is a restriction.
|
||||
var/list/scavenger_restriction_list //used for restrictions.
|
||||
|
||||
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)
|
||||
/datum/element/scavenging/Attach(atom/target, amount = 5, list/loot, list/unique, time = 12 SECONDS, hands = TRUE, list/tools, list/texts, \
|
||||
del_deplete = FALSE, restriction = NO_LOOT_RESTRICTION, max_per_player = 1)
|
||||
. = ..()
|
||||
if(. == ELEMENT_INCOMPATIBLE || !length(loot) || !amount || !istype(target) || isarea(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
@@ -40,6 +44,8 @@
|
||||
if(texts)
|
||||
search_texts = texts
|
||||
del_atom_on_depletion = del_deplete
|
||||
loot_restriction = restriction
|
||||
maximum_loot_per_player = max_per_player
|
||||
if(can_use_hands)
|
||||
RegisterSignal(target, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW), .proc/scavenge_barehanded)
|
||||
if(tool_types)
|
||||
@@ -50,25 +56,25 @@
|
||||
. = ..()
|
||||
loot_left_per_atom -= target
|
||||
progress_per_atom -= target
|
||||
if(maximum_loot_per_player == LOOT_RESTRICTION_MIND_PILE || maximum_loot_per_player == LOOT_RESTRICTION_CKEY_PILE)
|
||||
maximum_loot_per_player -= 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
|
||||
var/methods = tool_types.Copy()
|
||||
if(can_use_hands)
|
||||
if(!length(methods))
|
||||
methods = list("bare handed")
|
||||
else
|
||||
methods += "simply bare handed"
|
||||
text = english_list(methods, "", " or ")
|
||||
. += "<span class='notice'>Looks like [source.p_they()] can be scavenged[length(tool_types) ? " with either a" : ""] [text]</span>"
|
||||
methods += list("bare handed")
|
||||
if(!length(methods))
|
||||
return
|
||||
var/text = english_list(methods, "", " or ")
|
||||
examine_list += "<span class='notice'>Looks like [source.p_they()] can be scavenged [length(tool_types) ? "with" : ""][length(methods == 1) ? "" : "either "][length(tool_types) ? "a " : ""][text]</span>"
|
||||
|
||||
/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/user, params)
|
||||
if(user.a_intent == INTENT_HARM) //Robust trash disposal techniques!
|
||||
if(user.a_intent == INTENT_HARM || !I.tool_behaviour) //Robust trash disposal techniques!
|
||||
return
|
||||
var/speed_multi = tool_types[I.tool_behaviour]
|
||||
if(!speed_multi)
|
||||
@@ -76,7 +82,10 @@
|
||||
scavenge(source, user, speed_multi)
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
/// This proc has to be asynced (cough cough, do_after) in order to return the comsig values in time to stop the attack chain.
|
||||
/datum/element/scavenging/proc/scavenge(atom/source, mob/user, speed_multi = 1)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(players_busy_scavenging[user])
|
||||
return
|
||||
players_busy_scavenging[user] = TRUE
|
||||
@@ -84,37 +93,58 @@
|
||||
var/len_messages = length(search_texts)
|
||||
var/msg_first_person
|
||||
if(len_messages >= 2)
|
||||
msg_first_person = "<span class='notice'>You [progress_done ? "resume a ditched task and " : ""][search_texts[2]] [src].</span>"
|
||||
msg_first_person = "<span class='notice'>You [progress_done ? ", resume a ditched task and " : ""][search_texts[2]] [source].</span>"
|
||||
var/msg_blind
|
||||
if(len_messages >= 3)
|
||||
msg_blind = "<span class='italic'>[search_texts[3]]</span>"
|
||||
user.visible_message("<span class='notice'>[user] [search_texts[1]] [src].</span>", 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))
|
||||
user.visible_message("<span class='notice'>[user] [search_texts[1]] [source].</span>", msg_first_person, msg_blind)
|
||||
if(do_after(user, scavenge_time * speed_multi, TRUE, source, TRUE, CALLBACK(src, .proc/set_progress, source, world.time), resume_time = progress_done * speed_multi))
|
||||
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
|
||||
return TRUE
|
||||
|
||||
/datum/element/scavenging/proc/spawn_loot(atom/source, mob/user)
|
||||
progress_per_atom -= source
|
||||
|
||||
var/loot = pickweight(loot_table)
|
||||
var/special = TRUE
|
||||
var/free = FALSE
|
||||
if(!loot_left_per_atom[source])
|
||||
to_chat(user, "<span class='warning'>Looks likes there is nothing worth of interest left in [src] anymore, further attempts would be futile.</span>")
|
||||
to_chat(user, "<span class='warning'>Looks likes there is nothing worth of interest left in [source], what a shame...</span>")
|
||||
return
|
||||
|
||||
var/num_times = 0
|
||||
switch(loot_restriction)
|
||||
if(LOOT_RESTRICTION_MIND)
|
||||
num_times = LAZYACCESS(scavenger_restriction_list, user.mind)
|
||||
if(LOOT_RESTRICTION_CKEY)
|
||||
num_times = LAZYACCESS(scavenger_restriction_list, user.ckey)
|
||||
if(LOOT_RESTRICTION_MIND_PILE)
|
||||
var/list/L = LAZYACCESS(scavenger_restriction_list, source)
|
||||
if(L)
|
||||
num_times = LAZYACCESS(L, user.mind)
|
||||
if(LOOT_RESTRICTION_CKEY_PILE)
|
||||
var/list/L = LAZYACCESS(scavenger_restriction_list, source)
|
||||
if(L)
|
||||
num_times = LAZYACCESS(L, user.ckey)
|
||||
if(num_times >= maximum_loot_per_player)
|
||||
to_chat(user, "<span class='warning'>You can't find anything else vaguely useful in [source]. Another set of eyes might, however.</span>")
|
||||
return
|
||||
|
||||
switch(loot) // TODO: datumize these out.
|
||||
if(SCAVENGING_FOUND_NOTHING)
|
||||
to_chat(user, "<span class='notice'>You found nothing, better luck next time.</span>")
|
||||
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, "<span class='notice'>You found something in [src]... no wait, that's just another [nasty_rodent].</span>")
|
||||
to_chat(user, "<span class='notice'>You found something in [source]... no wait, that's just another [nasty_rodent].</span>")
|
||||
new /mob/living/simple_animal/mouse(source.loc)
|
||||
if(SCAVENGING_SPAWN_MICE)
|
||||
user.visible_message("<span class='notice'>A small gang of mice emerges from [source].</span>", \
|
||||
"<span class='notice'>You found something in [src]... no wait, that's just another- <b>no wait, that's a lot of damn mice.</b></span>")
|
||||
"<span class='notice'>You found something in [source]... no wait, that's just another- <b>no wait, that's a lot of damn mice.</b></span>")
|
||||
for(var/i in 1 to rand(4, 6))
|
||||
new /mob/living/simple_animal/mouse(source.loc)
|
||||
if(SCAVENGING_SPAWN_TOM)
|
||||
@@ -122,7 +152,7 @@
|
||||
to_chat(user, "<span class='notice'>You found nothing, better luck next time.</span>")
|
||||
free = TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You found something in [src]... no wait, that's Tom, the mouse! What is he doing here?</span>")
|
||||
to_chat(user, "<span class='notice'>You found something in [source]... no wait, that's Tom, the mouse! What is he doing here?</span>")
|
||||
new /mob/living/simple_animal/mouse/brown/Tom(source.loc)
|
||||
else
|
||||
special = FALSE
|
||||
@@ -145,7 +175,7 @@
|
||||
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]")
|
||||
to_chat(user, "You found something in [source]... it's \a [A][rarity_append]")
|
||||
|
||||
if(unique_loot[loot])
|
||||
var/loot_left = --unique_loot[loot]
|
||||
@@ -157,8 +187,29 @@
|
||||
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("<span class='warning'>[src] has been looted clean.</span>")
|
||||
qdel(source)
|
||||
if(free)
|
||||
return
|
||||
|
||||
--loot_left_per_atom[source]
|
||||
if(del_atom_on_depletion && !loot_left_per_atom[source])
|
||||
source.visible_message("<span class='warning'>[source] has been looted clean.</span>")
|
||||
qdel(source)
|
||||
return
|
||||
|
||||
if(!loot_restriction)
|
||||
return
|
||||
|
||||
LAZYINITLIST(scavenger_restriction_list)
|
||||
switch(loot_restriction)
|
||||
if(LOOT_RESTRICTION_MIND)
|
||||
scavenger_restriction_list[user.mind]++
|
||||
if(LOOT_RESTRICTION_CKEY)
|
||||
scavenger_restriction_list[user.ckey]++
|
||||
if(LOOT_RESTRICTION_MIND_PILE)
|
||||
LAZYINITLIST(scavenger_restriction_list[source])
|
||||
var/list/L = scavenger_restriction_list[source]
|
||||
L[user.mind]++
|
||||
if(LOOT_RESTRICTION_CKEY_PILE)
|
||||
LAZYINITLIST(scavenger_restriction_list[source])
|
||||
var/list/L = scavenger_restriction_list[source]
|
||||
L[user.ckey]++
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
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'
|
||||
icon_state = "randompile"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
var/loot_amount = 5
|
||||
@@ -14,43 +15,20 @@
|
||||
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)
|
||||
var/list/loot
|
||||
|
||||
/*
|
||||
* 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)
|
||||
var/list/unique_loot
|
||||
|
||||
/*
|
||||
* used for restrictions such as "one per mind", "one per ckey". Depending on the setting, these can be either limited to
|
||||
* the current pile or shared throughout all atoms attached to this element.
|
||||
*/
|
||||
var/loot_restriction = NO_LOOT_RESTRICTION
|
||||
var/maximum_loot_per_player = 1
|
||||
|
||||
/obj/structure/loot_pile/Initialize()
|
||||
. = ..()
|
||||
@@ -58,9 +36,31 @@
|
||||
|
||||
/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)
|
||||
if(loot)
|
||||
AddElement(/datum/element/scavenging, loot_amount, loot, unique_loot, scavenge_time, can_use_hands, allowed_tools, null, delete_on_depletion, loot_restriction, maximum_loot_per_player)
|
||||
|
||||
/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
|
||||
//uses the maintenance_loot global list, mostly boring stuff and mices.
|
||||
/obj/structure/loot_pile/maint
|
||||
name = "trash pile"
|
||||
desc = "A heap of garbage, but maybe there's something interesting inside?"
|
||||
density = TRUE
|
||||
layer = TABLE_LAYER
|
||||
climbable = TRUE
|
||||
pass_flags = LETPASSTHROW
|
||||
loot = list(
|
||||
SCAVENGING_FOUND_NOTHING = 50,
|
||||
SCAVENGING_SPAWN_MOUSE = 10,
|
||||
SCAVENGING_SPAWN_MICE = 5,
|
||||
SCAVENGING_SPAWN_TOM = 1,
|
||||
/obj/item/clothing/gloves/color/yellow = 0.5)
|
||||
unique_loot = list(/obj/item/clothing/gloves/color/yellow = 5, SCAVENGING_SPAWN_TOM = 1)
|
||||
|
||||
/obj/structure/loot_pile/maint/ComponentInitialize()
|
||||
var/static/safe_maint_items
|
||||
if(!safe_maint_items)
|
||||
safe_maint_items = list()
|
||||
for(var/A in GLOB.maintenance_loot)
|
||||
if(ispath(A, /obj/item))
|
||||
safe_maint_items[A] = GLOB.maintenance_loot[A]
|
||||
loot += safe_maint_items
|
||||
return ..()
|
||||
|
||||
Reference in New Issue
Block a user