From 60b9e9dafe2113808d1c1885cdfada9f672c2270 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 10 Jul 2020 21:06:53 +0100
Subject: [PATCH 01/14] trader event/mob
---
code/modules/events/travelling_trader.dm | 115 +++++++++++++++++++++++
tgstation.dme | 1 +
2 files changed, 116 insertions(+)
create mode 100644 code/modules/events/travelling_trader.dm
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
new file mode 100644
index 0000000000..918bc94029
--- /dev/null
+++ b/code/modules/events/travelling_trader.dm
@@ -0,0 +1,115 @@
+/datum/round_event_control/travelling_trader
+ name = "Travelling Trader"
+ typepath = /datum/round_event/travelling_trader
+ weight = 10
+ max_occurrences = 3
+ earliest_start = 0 MINUTES
+
+/datum/round_event/travelling_trader
+ startWhen = 0
+ endWhen = 600 //you effectively have 10 minutes to complete the traders request, before they disappear
+ var/mob/living/carbon/human/dummy/travelling_trader/trader
+ var/atom/spawn_location //where the trader appears
+
+/datum/round_event/travelling_trader/setup()
+ //find position to place trader at, same as how jacq works for poofing
+ var/list/targets = list()
+ for(var/H in GLOB.network_holopads)
+ var/area/A = get_area(H)
+ if(!A || findtextEx(A.name, "AI") || !is_station_level(H))
+ continue
+ targets += H
+
+ if(!targets)
+ targets = GLOB.generic_event_spawns
+
+ spawn_location = pick(targets)
+
+/datum/round_event/travelling_trader/start()
+ //spawn a type of trader
+ trader = pick(subtypesof(/mob/living/carbon/human/dummy/travelling_trader))
+ var/datum/effect_system/smoke_spread/smoke = new
+ smoke.set_up(1, spawn_location)
+ smoke.start()
+ trader.visible_message("[src] suddenly appears in a puff of smoke!")
+
+/datum/round_event/travelling_trader/announce(fake)
+ priority_announce("A mysterious figure has been detected on sensors at [get_area(spawn_location)]", "Mysterious Figure")
+
+/datum/round_event/travelling_trader/end()
+ if(trader)
+ trader.visible_message("The [src] has given up on waiting!")
+ qdel(trader)
+
+//the actual trader mob
+/mob/living/carbon/human/dummy/travelling_trader //subtype of dummy because we want to be resource-efficient
+ real_name = "Debug Travelling Trader"
+ status_flags = GODMODE //avoid scenarios of people trying to kill the trader
+ move_resist = MOVE_FORCE_VERY_STRONG //you can't bluespace bodybag them!
+ var/datum/outfit/trader_outfit
+ var/list/possible_wanted_items //weighted list of possible things to request
+ var/list/possible_rewards //weighted list of possible things to give in return for the requested item
+ var/atom/requested_item //the thing they chose from possible_wanted_items
+ var/last_speech //last time someone tried interacting with them using their hand
+ var/last_refusal //last time they vocally refused an item given to them
+ var/initial_speech = "It looks like the coders did a mishap!" //first thing they say when interacted with, like a description
+ var/speech_verb = "says"
+ var/request_speech = "Please bring me a requested_item you shall be greatly rewarded!" //second thing they say when interacted with
+ var/acceptance_speech = "This is exactly what I wanted! I shall be on my way now, thank you.!"
+ var/refusal_speech = "A given_item? I wanted a requested_item!" //what they say when refusing an item
+ var/active = TRUE
+
+/mob/living/carbon/human/dummy/travelling_trader/proc/setup_speech(var/input_speech, var/obj/item/given_item)
+ if(requested_item)
+ input_speech = replacetext(input_speech, "requested_item", requested_item.name)
+ if(given_item)
+ input_speech = replacetext(input_speech, "given_item", given_item.name)
+ return input_speech
+
+/mob/living/carbon/human/dummy/travelling_trader/attack_hand(mob/living/carbon/human/H)
+ if(active && last_speech + 3 SECONDS < world.realtime) //can only talk once per 3 seconds, to avoid spam
+ last_speech = world.realtime
+ if(initial_speech)
+ visible_message("[src] [speech_verb] \"[setup_speech(initial_speech)]\"")
+ sleep(15)
+ if(active && request_speech) //they might not be active anymore because of the prior sleep!
+ visible_message("[src] [speech_verb] \"[setup_speech(request_speech)]\"")
+
+/mob/living/carbon/human/dummy/travelling_trader/attackby(obj/item/I, mob/user)
+ if(active)
+ if(check_item(I))
+ active = FALSE
+ visible_message("[src] [speech_verb] \"[setup_speech(acceptance_speech, I)]\"")
+ qdel(I)
+ sleep(20)
+ give_reward()
+ qdel(src)
+ else
+ if(last_refusal + 3 SECONDS < world.realtime)
+ last_refusal = world.realtime
+ visible_message("[src] [speech_verb] \"[setup_speech(refusal_speech, I)]\"")
+
+/mob/living/carbon/human/dummy/travelling_trader/proc/check_item(var/obj/item/supplied_item) //sometimes we might want to care about the properties of the item, etc
+ return istype(supplied_item, requested_item)
+
+/mob/living/carbon/human/dummy/travelling_trader/proc/give_reward()
+ var/reward = pickweight(possible_rewards)
+ new reward(get_turf(src))
+
+/mob/living/carbon/human/dummy/travelling_trader/Initialize()
+ ADD_TRAIT(src,TRAIT_PIERCEIMMUNE, "trader_pierce_immune") //don't let people take their blood
+ trader_outfit.equip(src, TRUE)
+ for(var/obj/item/item in src.get_equipped_items())
+ ADD_TRAIT(item, TRAIT_NODROP, "trader_no_drop") //don't let people steal the travellers clothes!
+ item.resistance_flags |= INDESTRUCTIBLE //don't let people burn their clothes off, either.
+ requested_item = pickweight(possible_wanted_items)
+ ..()
+
+/mob/living/carbon/human/dummy/travelling_trader/Destroy()
+ var/datum/effect_system/smoke_spread/smoke = new
+ smoke.set_up(1, loc)
+ smoke.start()
+ visible_message("[src] disappears in a puff of smoke, leaving something on the ground!")
+ ..()
+
+//travelling trader subtypes (the types that can actually spawn)
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index 8be5ae2a46..78a665a033 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1954,6 +1954,7 @@
#include "code\modules\events\spider_infestation.dm"
#include "code\modules\events\spontaneous_appendicitis.dm"
#include "code\modules\events\stray_cargo.dm"
+#include "code\modules\events\travelling_trader.dm"
#include "code\modules\events\vent_clog.dm"
#include "code\modules\events\wisdomcow.dm"
#include "code\modules\events\wormholes.dm"
From 045169e1ee60b5da419cb344419f42b825222d01 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 10 Jul 2020 22:50:22 +0100
Subject: [PATCH 02/14] actual trader subtypes
---
code/modules/events/travelling_trader.dm | 103 +++++++++++++++++++++--
1 file changed, 98 insertions(+), 5 deletions(-)
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index 918bc94029..e6cbb28f30 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -7,7 +7,7 @@
/datum/round_event/travelling_trader
startWhen = 0
- endWhen = 600 //you effectively have 10 minutes to complete the traders request, before they disappear
+ endWhen = 900 //you effectively have 15 minutes to complete the traders request, before they disappear
var/mob/living/carbon/human/dummy/travelling_trader/trader
var/atom/spawn_location //where the trader appears
@@ -27,7 +27,8 @@
/datum/round_event/travelling_trader/start()
//spawn a type of trader
- trader = pick(subtypesof(/mob/living/carbon/human/dummy/travelling_trader))
+ var/trader_type = pick(subtypesof(/mob/living/carbon/human/dummy/travelling_trader))
+ trader = new trader_type(spawn_location)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(1, spawn_location)
smoke.start()
@@ -81,7 +82,7 @@
active = FALSE
visible_message("[src] [speech_verb] \"[setup_speech(acceptance_speech, I)]\"")
qdel(I)
- sleep(20)
+ sleep(15)
give_reward()
qdel(src)
else
@@ -102,7 +103,8 @@
for(var/obj/item/item in src.get_equipped_items())
ADD_TRAIT(item, TRAIT_NODROP, "trader_no_drop") //don't let people steal the travellers clothes!
item.resistance_flags |= INDESTRUCTIBLE //don't let people burn their clothes off, either.
- requested_item = pickweight(possible_wanted_items)
+ if(!requested_item) //sometimes we already picked one
+ requested_item = pickweight(possible_wanted_items)
..()
/mob/living/carbon/human/dummy/travelling_trader/Destroy()
@@ -112,4 +114,95 @@
visible_message("[src] disappears in a puff of smoke, leaving something on the ground!")
..()
-//travelling trader subtypes (the types that can actually spawn)
\ No newline at end of file
+//travelling trader subtypes (the types that can actually spawn)
+//so far there's: cook / botanist / animal hunter
+
+//cook
+/mob/living/carbon/human/dummy/travelling_trader/cook
+ name = "Otherworldly Chef"
+ trader_outfit = /datum/outfit/job/cook
+ initial_speech = "Mama-mia! I have came to this plane of existence, searching the greatest of foods!"
+ request_speech = "Can you fetch me the delicacy known as requested_item? I would pay you for your service!"
+ acceptance_speech = "Grazie! You have done me a service, my friend."
+ refusal_speech = "A given_item? Surely you must be joking!"
+ possible_rewards = list()
+
+
+/mob/living/carbon/human/dummy/travelling_trader/cook/Initialize()
+ //pick a random crafted food item as the requested item
+ requested_item = pick(subtypesof(/datum/crafting_recipe/food)).result
+ ..()
+
+//botanist
+/mob/living/carbon/human/dummy/travelling_trader/gardener
+ name = "Otherworldly Gardener"
+ trader_outfit = /datum/outfit/job/botanist
+ initial_speech = "I have come across this realm in search of rare plants and believe this station may be able to help me.."
+ request_speech = "Are you able to bring me a requested_item? I could see that you get some reward for this task."
+ acceptance_speech = "Amazing! Ill finally be able to make that salad. Goodbye for now!"
+ refusal_speech = "A given_item? Did nobody ever teach you the basics of gardening?"
+ possible_rewards = list()
+
+
+/mob/living/carbon/human/dummy/travelling_trader/gardener/Initialize()
+ requested_item = pick(subtypesof(/obj/item/reagent_containers/food/snacks/grown))
+ ..()
+
+//animal hunter
+/mob/living/carbon/human/dummy/travelling_trader/animal_hunter
+ name = "Otherworldly Animal Specialist"
+ trader_outfit = /datum/outfit/synthetic
+ initial_speech = "Greetings, lifeform. I am here to locate a special creature aboard your station."
+ request_speech = "Find me the creature known as 'requested_item' and you shall be rewarded for your efforts."
+ refusal_speech = "Do you think me to be a fool, lifeform? I know a requested_item when I see one."
+ possible_wanted_items = list(/mob/living/simple_animal/pet/dog/corgi/Ian = 1, /mob/living/simple_animal/sloth/paperwork = 1, /mob/living/carbon/monkey/punpun = 1, /mob/living/simple_animal/pet/fox/Renault = 1, /mob/living/simple_animal/hostile/carp/cayenne = 1)
+
+mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
+ acceptance_speech = pick(list("This lifeform shall make for a great stew, thank you.", "This lifeform shall be of a true use to our cause, thank you.", "The lifeform is adequate. Goodbye.", "This lifeform shall make a great addition to my collection."))
+ ..()
+
+/mob/living/carbon/human/dummy/travelling_trader/animal_hunter/check_item(var/obj/item/supplied_item) //item is likely to be in contents of whats supplied
+ if(supplied_item.contents[requested_item])
+ //delete the contents, item given is correct, but we don't want the contents to spill out when the parent is deleted
+ for(var/atom/thing in supplied_item.contents)
+ qdel(thing)
+ return TRUE
+ return FALSE
+
+//bartender
+/mob/living/carbon/human/dummy/travelling_trader/bartender
+ name = "Otherworldly Bartender"
+ trader_outfit = /datum/outfit/job/bartender
+ initial_speech = "Greetings, station inhabitor. I came to this dimension in the pursuit of a particular drink."
+ request_speech = "Bring me thirty units of the beverage known as 'requested_item'."
+ acceptance_speech = "This is truly the drink I have been seeking. Thank you."
+ refusal_speech = "Do not mess with me, simpleton, I do not wish for that which you are trying to give me."
+
+/mob/living/carbon/human/dummy/travelling_trader/bartender/Initialize() //pick a subtype of ethanol that isn't found in the default set of the booze dispensers reagents
+ requested_item = pick(subtypesof(/datum/reagent/consumable/ethanol) - list(/datum/reagent/consumable/ethanol/beer,
+ /datum/reagent/consumable/ethanol/kahlua,
+ /datum/reagent/consumable/ethanol/whiskey,
+ /datum/reagent/consumable/ethanol/wine,
+ /datum/reagent/consumable/ethanol/vodka,
+ /datum/reagent/consumable/ethanol/gin,
+ /datum/reagent/consumable/ethanol/rum,
+ /datum/reagent/consumable/ethanol/tequila,
+ /datum/reagent/consumable/ethanol/vermouth,
+ /datum/reagent/consumable/ethanol/cognac,
+ /datum/reagent/consumable/ethanol/ale,
+ /datum/reagent/consumable/ethanol/absinthe,
+ /datum/reagent/consumable/ethanol/hcider,
+ /datum/reagent/consumable/ethanol/creme_de_menthe,
+ /datum/reagent/consumable/ethanol/creme_de_cacao,
+ /datum/reagent/consumable/ethanol/creme_de_coconut,
+ /datum/reagent/consumable/ethanol/triple_sec,
+ /datum/reagent/consumable/ethanol/sake,
+ /datum/reagent/consumable/ethanol/applejack))
+ ..()
+
+/mob/living/carbon/human/dummy/travelling_trader/bartender/check_item(var/obj/item/supplied_item) //you need to check its reagents
+ var/obj/item/reagent_container/container = supplied_item
+ if(container)
+ if(container.reagents.has_reagent(requested_item, 30))
+ return TRUE
+ return FALSE
From 75b9eef74ef42add0872f89ad73aeeb6e660b8fc Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Fri, 10 Jul 2020 22:52:08 +0100
Subject: [PATCH 03/14] bug fixes
---
code/modules/events/travelling_trader.dm | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index e6cbb28f30..16533a0108 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -201,8 +201,8 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
..()
/mob/living/carbon/human/dummy/travelling_trader/bartender/check_item(var/obj/item/supplied_item) //you need to check its reagents
- var/obj/item/reagent_container/container = supplied_item
- if(container)
- if(container.reagents.has_reagent(requested_item, 30))
+ var/obj/item/reagent_container/supplied_container = supplied_item
+ if(supplied_container)
+ if(supplied_container.reagents.has_reagent(requested_item, 30))
return TRUE
return FALSE
From e571400b1bdb50bbbb95105b41b9216ffeb39006 Mon Sep 17 00:00:00 2001
From: timothyteakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sat, 11 Jul 2020 03:35:15 +0100
Subject: [PATCH 04/14] lots of bug fixes
---
code/modules/events/travelling_trader.dm | 39 ++++++++++--------------
1 file changed, 16 insertions(+), 23 deletions(-)
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index 16533a0108..d7eece79d1 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -12,23 +12,13 @@
var/atom/spawn_location //where the trader appears
/datum/round_event/travelling_trader/setup()
- //find position to place trader at, same as how jacq works for poofing
- var/list/targets = list()
- for(var/H in GLOB.network_holopads)
- var/area/A = get_area(H)
- if(!A || findtextEx(A.name, "AI") || !is_station_level(H))
- continue
- targets += H
-
- if(!targets)
- targets = GLOB.generic_event_spawns
-
- spawn_location = pick(targets)
+ spawn_location = pick(GLOB.generic_event_spawns)
/datum/round_event/travelling_trader/start()
//spawn a type of trader
var/trader_type = pick(subtypesof(/mob/living/carbon/human/dummy/travelling_trader))
- trader = new trader_type(spawn_location)
+ message_admins("we picked trader [trader_type] at location [spawn_location]")
+ trader = new trader_type(get_turf(spawn_location))
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(1, spawn_location)
smoke.start()
@@ -43,7 +33,7 @@
qdel(trader)
//the actual trader mob
-/mob/living/carbon/human/dummy/travelling_trader //subtype of dummy because we want to be resource-efficient
+/mob/living/carbon/human/dummy/travelling_trader //similar to a dummy because we want to be resource-efficient
real_name = "Debug Travelling Trader"
status_flags = GODMODE //avoid scenarios of people trying to kill the trader
move_resist = MOVE_FORCE_VERY_STRONG //you can't bluespace bodybag them!
@@ -62,13 +52,15 @@
/mob/living/carbon/human/dummy/travelling_trader/proc/setup_speech(var/input_speech, var/obj/item/given_item)
if(requested_item)
- input_speech = replacetext(input_speech, "requested_item", requested_item.name)
+ var/atom/temp_requested = new requested_item
+ input_speech = replacetext(input_speech, "requested_item", temp_requested.name)
+ qdel(temp_requested)
if(given_item)
input_speech = replacetext(input_speech, "given_item", given_item.name)
return input_speech
/mob/living/carbon/human/dummy/travelling_trader/attack_hand(mob/living/carbon/human/H)
- if(active && last_speech + 3 SECONDS < world.realtime) //can only talk once per 3 seconds, to avoid spam
+ if(active && last_speech + 3 < world.realtime) //can only talk once per 3 seconds, to avoid spam
last_speech = world.realtime
if(initial_speech)
visible_message("[src] [speech_verb] \"[setup_speech(initial_speech)]\"")
@@ -86,7 +78,7 @@
give_reward()
qdel(src)
else
- if(last_refusal + 3 SECONDS < world.realtime)
+ if(last_refusal + 3 < world.realtime)
last_refusal = world.realtime
visible_message("[src] [speech_verb] \"[setup_speech(refusal_speech, I)]\"")
@@ -98,14 +90,14 @@
new reward(get_turf(src))
/mob/living/carbon/human/dummy/travelling_trader/Initialize()
+ ..()
ADD_TRAIT(src,TRAIT_PIERCEIMMUNE, "trader_pierce_immune") //don't let people take their blood
- trader_outfit.equip(src, TRUE)
+ equipOutfit(trader_outfit, TRUE)
for(var/obj/item/item in src.get_equipped_items())
ADD_TRAIT(item, TRAIT_NODROP, "trader_no_drop") //don't let people steal the travellers clothes!
item.resistance_flags |= INDESTRUCTIBLE //don't let people burn their clothes off, either.
if(!requested_item) //sometimes we already picked one
requested_item = pickweight(possible_wanted_items)
- ..()
/mob/living/carbon/human/dummy/travelling_trader/Destroy()
var/datum/effect_system/smoke_spread/smoke = new
@@ -130,7 +122,8 @@
/mob/living/carbon/human/dummy/travelling_trader/cook/Initialize()
//pick a random crafted food item as the requested item
- requested_item = pick(subtypesof(/datum/crafting_recipe/food)).result
+ var/category = pick(list(/obj/item/reagent_containers/food/snacks/burger,/obj/item/reagent_containers/food/snacks/pie,/obj/item/reagent_containers/food/snacks/pizza,/obj/item/reagent_containers/food/snacks/soup,/obj/item/reagent_containers/food/snacks/store/bread))
+ requested_item = pick(subtypesof(category))
..()
//botanist
@@ -162,7 +155,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
..()
/mob/living/carbon/human/dummy/travelling_trader/animal_hunter/check_item(var/obj/item/supplied_item) //item is likely to be in contents of whats supplied
- if(supplied_item.contents[requested_item])
+ if(requested_item in supplied_item.contents)
//delete the contents, item given is correct, but we don't want the contents to spill out when the parent is deleted
for(var/atom/thing in supplied_item.contents)
qdel(thing)
@@ -201,8 +194,8 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
..()
/mob/living/carbon/human/dummy/travelling_trader/bartender/check_item(var/obj/item/supplied_item) //you need to check its reagents
- var/obj/item/reagent_container/supplied_container = supplied_item
- if(supplied_container)
+ if(istype(supplied_item, /obj/item/reagent_containers))
+ var/obj/item/reagent_containers/supplied_container = supplied_item
if(supplied_container.reagents.has_reagent(requested_item, 30))
return TRUE
return FALSE
From c1592ad162f3e428781beba144ba0a7329e274d0 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sat, 11 Jul 2020 23:27:29 +0100
Subject: [PATCH 05/14] more rewards
---
code/game/objects/items/kitchen.dm | 6 +
code/game/objects/items/pet_carrier.dm | 5 +-
code/game/objects/items/stacks/tape.dm | 13 +-
code/game/objects/items/storage/boxes.dm | 6 +
code/modules/events/travelling_trader.dm | 156 +++++++++++++++---
code/modules/mining/money_bag.dm | 6 +-
.../living/simple_animal/friendly/bumbles.dm | 1 +
.../simple_animal/friendly/farm_animals.dm | 9 +
code/modules/reagents/reagent_dispenser.dm | 39 +++++
9 files changed, 213 insertions(+), 28 deletions(-)
diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm
index dda41494ff..1d4610488d 100644
--- a/code/game/objects/items/kitchen.dm
+++ b/code/game/objects/items/kitchen.dm
@@ -54,6 +54,12 @@
else
return ..()
+/obj/item/kitchen/fork/throwing
+ name = "throwing fork"
+ desc = "A fork, sharpened to perfection, making it a great weapon for throwing."
+ throwforce = 15
+ embedding = list("pain_mult" = 2, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 100)
+ sharpness = IS_SHARP_ACCURATE
/obj/item/kitchen/knife
name = "kitchen knife"
diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm
index 8b322d20cb..8ebb497fe1 100644
--- a/code/game/objects/items/pet_carrier.dm
+++ b/code/game/objects/items/pet_carrier.dm
@@ -106,7 +106,7 @@
if(user == target)
to_chat(user, "Why would you ever do that?")
return
- if(ishostile(target) && !allows_hostiles && target.move_resist < MOVE_FORCE_VERY_STRONG) //don't allow goliaths into pet carriers
+ if(ishostile(target) && (!allows_hostiles || istype(target, /mob/living/simple_animal/hostile/carp/cayenne))) || target.move_resist < MOVE_FORCE_VERY_STRONG) //don't allow goliaths into pet carriers, but let cayenne in!
to_chat(user, "You have a feeling you shouldn't keep this as a pet.")
load_occupant(user, target)
@@ -253,7 +253,8 @@
occupant_gas_supply = new
if(isanimal(occupant))
var/mob/living/simple_animal/animal = occupant
- occupant_gas_supply.set_temperature(animal.minbodytemp) //simple animals only care about temperature when their turf isnt a location
+ occupant_gas_supply[/datum/gas/oxygen] = 0.0064 //make sure it has some gas in so it isn't depressurized
+ occupant_gas_supply.set_temperature(animal.minbodytemp) //simple animals only care about temperature/pressure when their turf isnt a location
else
if(ishuman(occupant)) //humans require resistance to cold/heat and living in no air while inside, and lose this when outside
ADD_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist")
diff --git a/code/game/objects/items/stacks/tape.dm b/code/game/objects/items/stacks/tape.dm
index 177260febb..8e8e2eaf52 100644
--- a/code/game/objects/items/stacks/tape.dm
+++ b/code/game/objects/items/stacks/tape.dm
@@ -15,6 +15,8 @@
var/list/conferred_embed = EMBED_HARMLESS
var/overwrite_existing = FALSE
+ var/apply_time = 30
+
/obj/item/stack/sticky_tape/afterattack(obj/item/I, mob/living/user)
if(!istype(I))
return
@@ -25,17 +27,24 @@
user.visible_message("[user] begins wrapping [I] with [src].", "You begin wrapping [I] with [src].")
- if(do_after(user, 30, target=I))
+ if(do_after(user, apply_time, target=I))
I.embedding = conferred_embed
I.updateEmbedding()
to_chat(user, "You finish wrapping [I] with [src].")
- use(1)
+ if(max_amount > 0)
+ use(1)
I.name = "[prefix] [I.name]"
if(istype(I, /obj/item/grenade))
var/obj/item/grenade/sticky_bomb = I
sticky_bomb.sticky = TRUE
+/obj/item/stack/sticky_tape/infinite //endless tape that applies far faster, for maximum honks
+ name = "endless sticky tape"
+ desc = "This roll of sticky tape somehow has no end."
+ max_amount = 0
+ apply_time = 10
+
/obj/item/stack/sticky_tape/super
name = "super sticky tape"
singular_name = "super sticky tape"
diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm
index cdd3781748..02ae867240 100644
--- a/code/game/objects/items/storage/boxes.dm
+++ b/code/game/objects/items/storage/boxes.dm
@@ -1418,3 +1418,9 @@ obj/item/storage/box/stingbangs
new /obj/item/reagent_containers/glass/beaker/meta(src)
new /obj/item/reagent_containers/glass/beaker/noreact(src)
new /obj/item/reagent_containers/glass/beaker/bluespace(src)
+
+/obj/item/storage/box/strange_seeds_5pack
+
+/obj/item/storage/box/strange_seeds_5pack/PopulateContents()
+ for(var/i in 1 to 5)
+ new /obj/item/seeds/random(src)
\ No newline at end of file
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index d7eece79d1..e19b2bfdee 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -12,12 +12,15 @@
var/atom/spawn_location //where the trader appears
/datum/round_event/travelling_trader/setup()
- spawn_location = pick(GLOB.generic_event_spawns)
+ if(GLOB.generic_event_spawns)
+ spawn_location = pick(GLOB.generic_event_spawns)
+ else
+ message_admins("No event spawn landmarks exist on the map while placing a travelling trader, resorting to random station turf. (go yell at a mapper)")
+ spawn_location = get_random_station_turf()
/datum/round_event/travelling_trader/start()
//spawn a type of trader
var/trader_type = pick(subtypesof(/mob/living/carbon/human/dummy/travelling_trader))
- message_admins("we picked trader [trader_type] at location [spawn_location]")
trader = new trader_type(get_turf(spawn_location))
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(1, spawn_location)
@@ -34,7 +37,7 @@
//the actual trader mob
/mob/living/carbon/human/dummy/travelling_trader //similar to a dummy because we want to be resource-efficient
- real_name = "Debug Travelling Trader"
+ var/trader_name = "Debug Travelling Trader"
status_flags = GODMODE //avoid scenarios of people trying to kill the trader
move_resist = MOVE_FORCE_VERY_STRONG //you can't bluespace bodybag them!
var/datum/outfit/trader_outfit
@@ -75,7 +78,7 @@
visible_message("[src] [speech_verb] \"[setup_speech(acceptance_speech, I)]\"")
qdel(I)
sleep(15)
- give_reward()
+ give_reward(user)
qdel(src)
else
if(last_refusal + 3 < world.realtime)
@@ -98,6 +101,7 @@
item.resistance_flags |= INDESTRUCTIBLE //don't let people burn their clothes off, either.
if(!requested_item) //sometimes we already picked one
requested_item = pickweight(possible_wanted_items)
+ name = trader_name //gets changed in humans initialisation so we set it here
/mob/living/carbon/human/dummy/travelling_trader/Destroy()
var/datum/effect_system/smoke_spread/smoke = new
@@ -107,69 +111,113 @@
..()
//travelling trader subtypes (the types that can actually spawn)
-//so far there's: cook / botanist / animal hunter
+//so far there's: cook / botanist / bartender / animal hunter / artifact dealer / surgeon (6 types!)
//cook
/mob/living/carbon/human/dummy/travelling_trader/cook
- name = "Otherworldly Chef"
+ trader_name = "Otherworldly Chef"
trader_outfit = /datum/outfit/job/cook
initial_speech = "Mama-mia! I have came to this plane of existence, searching the greatest of foods!"
request_speech = "Can you fetch me the delicacy known as requested_item? I would pay you for your service!"
acceptance_speech = "Grazie! You have done me a service, my friend."
refusal_speech = "A given_item? Surely you must be joking!"
- possible_rewards = list()
-
+ possible_rewards = list(/obj/item/paper/secretrecipe = 1,
+ /obj/item/pizzabox/infinite = 1,
+ /obj/item/kitchen/fork/throwing = 1,
+ /mob/living/simple_animal/cow/random = 1)
/mob/living/carbon/human/dummy/travelling_trader/cook/Initialize()
//pick a random crafted food item as the requested item
- var/category = pick(list(/obj/item/reagent_containers/food/snacks/burger,/obj/item/reagent_containers/food/snacks/pie,/obj/item/reagent_containers/food/snacks/pizza,/obj/item/reagent_containers/food/snacks/soup,/obj/item/reagent_containers/food/snacks/store/bread))
- requested_item = pick(subtypesof(category))
+ requested_item = GLOB.crafting_recipes[pick(subtypesof( /datum/crafting_recipe/food))].result
..()
//botanist
/mob/living/carbon/human/dummy/travelling_trader/gardener
- name = "Otherworldly Gardener"
+ trader_name = "Otherworldly Gardener"
trader_outfit = /datum/outfit/job/botanist
initial_speech = "I have come across this realm in search of rare plants and believe this station may be able to help me.."
request_speech = "Are you able to bring me a requested_item? I could see that you get some reward for this task."
acceptance_speech = "Amazing! Ill finally be able to make that salad. Goodbye for now!"
refusal_speech = "A given_item? Did nobody ever teach you the basics of gardening?"
- possible_rewards = list()
+ possible_rewards = list(/obj/item/seeds/cherry/bomb = 1,
+ /obj/item/storage/box/strange_seeds_5pack = 6,
+ /obj/item/clothing/suit/hooded/bee_costume = 2,
+ /obj/item/seeds/gatfruit = 1) //overall you have less chance of seeing them than a lifebringer just bringing the seeds to you directly
/mob/living/carbon/human/dummy/travelling_trader/gardener/Initialize()
- requested_item = pick(subtypesof(/obj/item/reagent_containers/food/snacks/grown))
+ requested_item = pick(subtypesof(/obj/item/reagent_containers/food/snacks/grown) - list(/obj/item/reagent_containers/food/snacks/grown/shell,
+ /obj/item/reagent_containers/food/snacks/grown/shell/gatfruit,
+ /obj/item/reagent_containers/food/snacks/grown/cherry_bomb))
..()
//animal hunter
/mob/living/carbon/human/dummy/travelling_trader/animal_hunter
- name = "Otherworldly Animal Specialist"
- trader_outfit = /datum/outfit/synthetic
+ trader_name = "Otherworldly Animal Specialist"
+ trader_outfit = /datum/outfit/job/doctor
initial_speech = "Greetings, lifeform. I am here to locate a special creature aboard your station."
- request_speech = "Find me the creature known as 'requested_item' and you shall be rewarded for your efforts."
+ request_speech = "Find me the creature known as 'requested_item' and you shall be rewarded for your efforts."
refusal_speech = "Do you think me to be a fool, lifeform? I know a requested_item when I see one."
- possible_wanted_items = list(/mob/living/simple_animal/pet/dog/corgi/Ian = 1, /mob/living/simple_animal/sloth/paperwork = 1, /mob/living/carbon/monkey/punpun = 1, /mob/living/simple_animal/pet/fox/Renault = 1, /mob/living/simple_animal/hostile/carp/cayenne = 1)
+ possible_wanted_items = list(/mob/living/simple_animal/pet/dog/corgi/Ian = 1,
+ /mob/living/simple_animal/sloth/paperwork = 1,
+ /mob/living/carbon/monkey/punpun = 1,
+ /mob/living/simple_animal/pet/fox/Renault = 1,
+ /mob/living/simple_animal/hostile/carp/cayenne = 1,
+ /mob/living/simple_animal/pet/bumbles = 1,
+ /mob/living/simple_animal/parrot/Poly = 1)
+ possible_rewards = list(/mob/living/simple_animal/pet/dog/corgi/exoticcorgi = 1, //rewards are animals, friendly to only the person who handed the reward in!
+ /mob/living/simple_animal/cockroach = 1,
+ /mob/living/simple_animal/hostile/skeleton = 1,
+ /mob/living/simple_animal/hostile/stickman = 1,
+ /mob/living/simple_animal/hostile/stickman/dog = 1,
+ /mob/living/simple_animal/hostile/asteroid/fugu = 1,
+ /mob/living/simple_animal/hostile/bear = 1,
+ /mob/living/simple_animal/hostile/retaliate/clown/fleshclown = 1,
+ /mob/living/simple_animal/hostile/tree = 1,
+ /mob/living/simple_animal/hostile/mimic = 1
+ /mob/living/simple_animal/hostile/shark/laser = 1
+ )
mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
acceptance_speech = pick(list("This lifeform shall make for a great stew, thank you.", "This lifeform shall be of a true use to our cause, thank you.", "The lifeform is adequate. Goodbye.", "This lifeform shall make a great addition to my collection."))
+ //make sure they only ask for animals that are still alive
+ for(var/mob/living/animal in possible_wanted_items)
+ if(!(animal in GLOB.mob_living_list))
+ possible_wanted_items -= animal
+ if(!possible_wanted_items)
+ //all the pets are dead, so ask for a monkey, or sometimes a corgi (corgis are more annoying to get a hold of)
+ possible_wanted_items = list(/mob/living/simple_animal/pet/dog/corgi = 1, /mob/living/carbon/monkey = 3)
..()
/mob/living/carbon/human/dummy/travelling_trader/animal_hunter/check_item(var/obj/item/supplied_item) //item is likely to be in contents of whats supplied
- if(requested_item in supplied_item.contents)
- //delete the contents, item given is correct, but we don't want the contents to spill out when the parent is deleted
- for(var/atom/thing in supplied_item.contents)
- qdel(thing)
- return TRUE
+ for(var/atom/something in supplied_item.contents)
+ if(istype(something, requested_item))
+ qdel(something) //typically things holding mobs release the mob when the container is deleted, so delete the mob first here
+ return TRUE
return FALSE
+/mob/living/carbon/human/dummy/travelling_trader/animal_hunter/give_reward(var/mob/giver) //the reward is actually given in a jar, because releasing it onto the station might be a bad idea
+ var/mob/living/animal = pickweight(possible_rewards)
+ if(giver && giver.tag)
+ animal.faction += "/[[giver.tag]/]"
+ var/obj/item/pet_carrier/bluespace/jar = new(get_turf(src))
+ jar.add_occupant(animal)
+ jar.name = "WARNING: [animal] INSIDE"
+
//bartender
/mob/living/carbon/human/dummy/travelling_trader/bartender
- name = "Otherworldly Bartender"
+ trader_name = "Otherworldly Bartender"
trader_outfit = /datum/outfit/job/bartender
initial_speech = "Greetings, station inhabitor. I came to this dimension in the pursuit of a particular drink."
request_speech = "Bring me thirty units of the beverage known as 'requested_item'."
acceptance_speech = "This is truly the drink I have been seeking. Thank you."
refusal_speech = "Do not mess with me, simpleton, I do not wish for that which you are trying to give me."
+ possible_rewards = list(/obj/structure/reagent_dispensers/keg/neurotoxin = 1, //all kegs have 250u aside from neurotoxin/hearty punch which have 100u
+ /obj/structure/reagent_dispensers/keg/hearty_punch = 3,
+ /obj/structure/reagent_dispensers/keg/red_queen = 3,
+ /obj/structure/reagent_dispensers/keg/narsour = 3
+ /obj/structure/reagent_dispensers/keg/quintuple_sec = 3)
+
/mob/living/carbon/human/dummy/travelling_trader/bartender/Initialize() //pick a subtype of ethanol that isn't found in the default set of the booze dispensers reagents
requested_item = pick(subtypesof(/datum/reagent/consumable/ethanol) - list(/datum/reagent/consumable/ethanol/beer,
@@ -199,3 +247,65 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
if(supplied_container.reagents.has_reagent(requested_item, 30))
return TRUE
return FALSE
+
+//artifact dealer
+/mob/living/carbon/human/dummy/travelling_trader/artifact_dealer
+ trader_name = "Otherworldly Artifact Dealer"
+ trader_outfit = /datum/outfit/artifact_dealer //he's cool enough to get his own outfit
+ inital_speech = "I have come here due to sensing the existence of an object of great power and importance."
+ request_speech = "Give to me a requested_item and I shall make it worth your while, traveller."
+ acceptance_speech = "This is truly an artifact worthy of my collection, thank you."
+ refusal_speech = "A given_item? Hah! Worthless."
+ possible_wanted_items = list(/obj/item/pen/fountain/captain = 1, //various rare things and high risk but not useful things (i.e. champion belt, bedsheet, pen)
+ /obj/item/storage/belt/champion = 1
+ /obj/item/clothing/shoes/wheelys = 1
+ /obj/item/relic = 1
+ /obj/item/flashlight/lamp/bananalamp = 1
+ /obj/item/storage/box/hug = 1
+ /obj/item/clothing/gloves/color/yellow = 1
+ /obj/item/instrument/saxophone = 1,
+ /obj/item/bedsheet/captain = 1,
+ /obj/item/slime_extract/green = 1,
+ /obj/item/chainsaw = 1,
+ /obj/item/clothing/head/crown = 1)
+ possible_rewards = list(/obj/item/storage/bag/money/c5000 = 5,
+ /obj/item/circuitboard/computer/arcade/amputation = 2,
+ /obj/item/stack/sticky_tape/infinite = 2,
+ /obj/item/clothing/suit/hooded/wintercoat/cosmic = 2)
+
+/mob/living/carbon/human/dummy/travelling_trader/artifact_dealer/Initialize()
+ possible_rewards[pick(subtypesof(/obj/item/clothing/head/collectable)) = 1] //this is slightly lower because it's absolutely useless
+ ..()
+
+/datum/outfit/artifact_dealer
+ uniform = /obj/item/clothing/under/suit/black_really
+ shoes = /obj/item/clothing/shoes/combat
+ head = /obj/item/clothing/head/that
+ glasses = /obj/item/clothing/glasses/monocle
+
+//surgeon
+/mob/living/carbon/human/dummy/travelling_trader/surgeon
+ trader_name = "Otherworldly Surgeon"
+ trader_outfit = /datum/outfit/otherworldly_surgeon
+ initial_speech = "Hello there, meatbag. You can provide me with something I want."
+ request_speech = "Find me a requested_item. I shall make sure it's worth your efforts."
+ acceptance_speech = "This shall do. Goodbye, meatbag."
+ refusal_speech = "That is not what I wish for. Give me a requested_item, or I shall take one by force."
+ possible_wanted_items = list(/obj/item/bodypart/l_arm = 4, //limbs are the most common, with brain/head being the least so, organs in the middle
+ /obj/item/bodypart/r_arm = 4,
+ /obj/item/bodypart/l_leg = 4,
+ /obj/item/bodypart/r_leg = 4,
+ /obj/item/organ/tongue = 2,
+ /obj/item/organ/liver = 2,
+ /obj/item/organ/lungs = 2,
+ /obj/item/organ/heart = 2,
+ /obj/item/bodypart/eyes = 1.
+ /obj/item/organ/brain = 1,
+ /obj/item/bodypart/head = 1)
+
+/datum/outfit/otherworldly_surgeon
+ uniform = /obj/item/clothing/under/pants/white
+ shoes = /obj/item/clothing/shoes/sneakers/white
+ gloves = /obj/item/clothing/gloves/color/latex
+ mask = /obj/item/clothing/mask/surgical
+ suit = /obj/item/clothing/suit/apron/surgical
\ No newline at end of file
diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm
index 66f99ec40c..7dd13a6fc1 100644
--- a/code/modules/mining/money_bag.dm
+++ b/code/modules/mining/money_bag.dm
@@ -24,4 +24,8 @@
new /obj/item/coin/silver(src)
new /obj/item/coin/gold(src)
new /obj/item/coin/gold(src)
- new /obj/item/coin/adamantine(src)
\ No newline at end of file
+ new /obj/item/coin/adamantine(src)
+
+/obj/item/storage/bag/money/c5000/PopulateContents()
+ for(var/i = 0, i < 5, i++)
+ new /obj/item/stack/spacecash/c1000(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/friendly/bumbles.dm b/code/modules/mob/living/simple_animal/friendly/bumbles.dm
index 2d236a4327..3707aa33f8 100644
--- a/code/modules/mob/living/simple_animal/friendly/bumbles.dm
+++ b/code/modules/mob/living/simple_animal/friendly/bumbles.dm
@@ -30,6 +30,7 @@
verb_yell = "buzzes intensely"
emote_see = list("buzzes.", "makes a loud buzz.", "rolls several times.", "buzzes happily.")
speak_chance = 1
+ unique_name = TRUE
/mob/living/simple_animal/pet/bumbles/Initialize()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index ba9cdfda64..b42216c2cc 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -192,6 +192,15 @@
else
..()
+//a cow that produces a random reagent in its udder
+/mob/living/simple_animal/cow/random
+ name = "strange cow"
+ desc = "Something seems off about the milk this cow is producing."
+
+/mob/living/simple_animal/cow/random/Initialize()
+ milk_reagent = get_random_reagent_id() //this has a blacklist so don't worry about romerol cows, etc
+
+
//Wisdom cow, speaks and bestows great wisdoms
/mob/living/simple_animal/cow/wisdom
name = "wisdom cow"
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index bc4e214161..927da6d625 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -247,3 +247,42 @@
icon_state = "bluekeg"
reagent_id = /datum/reagent/consumable/ethanol/gargle_blaster
tank_volume = 100
+
+//kegs given by the travelling trader's bartender subtype
+
+/obj/structure/reagent_dispensers/keg/quintuple_sec
+ name = "keg of quintuple sec"
+ desc = "A keg of pure justice."
+ icon_state = "redkeg"
+ reagent_id = /datum/reagent/consumable/ethanol/quintuple_sec
+ tank_volume = 250
+
+/obj/structure/reagent_dispensers/keg/narsour
+ name = "keg of narsour"
+ desc = "A keg of eldritch terrors."
+ icon_state = "redkeg"
+ reagent_id = /datum/reagent/consumable/ethanol/narsour
+ tank_volume = 250
+
+/obj/structure/reagent_dispensers/keg/red_queen
+ name = "keg of red queen"
+ desc = "A strange keg, filled with a kind of tea."
+ icon_state = "redkeg"
+ reagent_id = /datum/reagent/consumable/red_queen
+ tank_volume = 250
+
+/obj/structure/reagent_dispensers/keg/hearty_punch
+ name = "keg of hearty punch"
+ desc = "A keg that will get you right back on your feet."
+ icon_state = "redkeg"
+ reagent_id = /datum/reagent/consumable/hearty_punch
+ tank_volume = 100 //this usually has a 15:1 ratio when being made, so we provide less of it
+
+/obj/structure/reagent_dispensers/keg/neurotoxin
+ name = "keg of neurotoxin"
+ desc = "A keg of the sickly substance known as 'neurotoxin'."
+ icon_state = "bluekeg"
+ reagent_id = /datum/reagent/consumable/ethanol/neurotoxin
+ tank_volume = 100 //2.5x less than the other kegs because it's harder to get
+
+
From 8712dd6de49c4423d1b19b10396397f016b18414 Mon Sep 17 00:00:00 2001
From: timothyteakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 12 Jul 2020 00:31:45 +0100
Subject: [PATCH 06/14] bugfixes
---
code/game/objects/items/pet_carrier.dm | 2 +-
code/modules/events/travelling_trader.dm | 42 ++++++++++++++--------
code/modules/reagents/reagent_dispenser.dm | 2 +-
3 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm
index 8ebb497fe1..a60aa02ce1 100644
--- a/code/game/objects/items/pet_carrier.dm
+++ b/code/game/objects/items/pet_carrier.dm
@@ -106,7 +106,7 @@
if(user == target)
to_chat(user, "Why would you ever do that?")
return
- if(ishostile(target) && (!allows_hostiles || istype(target, /mob/living/simple_animal/hostile/carp/cayenne))) || target.move_resist < MOVE_FORCE_VERY_STRONG) //don't allow goliaths into pet carriers, but let cayenne in!
+ if(ishostile(target) && (!allows_hostiles || istype(target, /mob/living/simple_animal/hostile/carp/cayenne)) || target.move_resist < MOVE_FORCE_VERY_STRONG) //don't allow goliaths into pet carriers, but let cayenne in!
to_chat(user, "You have a feeling you shouldn't keep this as a pet.")
load_occupant(user, target)
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index e19b2bfdee..6c2692dc65 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -174,7 +174,7 @@
/mob/living/simple_animal/hostile/bear = 1,
/mob/living/simple_animal/hostile/retaliate/clown/fleshclown = 1,
/mob/living/simple_animal/hostile/tree = 1,
- /mob/living/simple_animal/hostile/mimic = 1
+ /mob/living/simple_animal/hostile/mimic = 1,
/mob/living/simple_animal/hostile/shark/laser = 1
)
@@ -199,7 +199,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
/mob/living/carbon/human/dummy/travelling_trader/animal_hunter/give_reward(var/mob/giver) //the reward is actually given in a jar, because releasing it onto the station might be a bad idea
var/mob/living/animal = pickweight(possible_rewards)
if(giver && giver.tag)
- animal.faction += "/[[giver.tag]/]"
+ animal.faction += "\[[giver.tag]\]"
var/obj/item/pet_carrier/bluespace/jar = new(get_turf(src))
jar.add_occupant(animal)
jar.name = "WARNING: [animal] INSIDE"
@@ -215,7 +215,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
possible_rewards = list(/obj/structure/reagent_dispensers/keg/neurotoxin = 1, //all kegs have 250u aside from neurotoxin/hearty punch which have 100u
/obj/structure/reagent_dispensers/keg/hearty_punch = 3,
/obj/structure/reagent_dispensers/keg/red_queen = 3,
- /obj/structure/reagent_dispensers/keg/narsour = 3
+ /obj/structure/reagent_dispensers/keg/narsour = 3,
/obj/structure/reagent_dispensers/keg/quintuple_sec = 3)
@@ -252,17 +252,17 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
/mob/living/carbon/human/dummy/travelling_trader/artifact_dealer
trader_name = "Otherworldly Artifact Dealer"
trader_outfit = /datum/outfit/artifact_dealer //he's cool enough to get his own outfit
- inital_speech = "I have come here due to sensing the existence of an object of great power and importance."
+ initial_speech = "I have come here due to sensing the existence of an object of great power and importance."
request_speech = "Give to me a requested_item and I shall make it worth your while, traveller."
acceptance_speech = "This is truly an artifact worthy of my collection, thank you."
refusal_speech = "A given_item? Hah! Worthless."
possible_wanted_items = list(/obj/item/pen/fountain/captain = 1, //various rare things and high risk but not useful things (i.e. champion belt, bedsheet, pen)
- /obj/item/storage/belt/champion = 1
- /obj/item/clothing/shoes/wheelys = 1
- /obj/item/relic = 1
- /obj/item/flashlight/lamp/bananalamp = 1
- /obj/item/storage/box/hug = 1
- /obj/item/clothing/gloves/color/yellow = 1
+ /obj/item/storage/belt/champion = 1,
+ /obj/item/clothing/shoes/wheelys = 1,
+ /obj/item/relic = 1,
+ /obj/item/flashlight/lamp/bananalamp = 1,
+ /obj/item/storage/box/hug = 1,
+ /obj/item/clothing/gloves/color/yellow = 1,
/obj/item/instrument/saxophone = 1,
/obj/item/bedsheet/captain = 1,
/obj/item/slime_extract/green = 1,
@@ -274,7 +274,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
/obj/item/clothing/suit/hooded/wintercoat/cosmic = 2)
/mob/living/carbon/human/dummy/travelling_trader/artifact_dealer/Initialize()
- possible_rewards[pick(subtypesof(/obj/item/clothing/head/collectable)) = 1] //this is slightly lower because it's absolutely useless
+ possible_rewards += list(pick(subtypesof(/obj/item/clothing/head/collectable)) = 1) //this is slightly lower because it's absolutely useless
..()
/datum/outfit/artifact_dealer
@@ -291,7 +291,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
request_speech = "Find me a requested_item. I shall make sure it's worth your efforts."
acceptance_speech = "This shall do. Goodbye, meatbag."
refusal_speech = "That is not what I wish for. Give me a requested_item, or I shall take one by force."
- possible_wanted_items = list(/obj/item/bodypart/l_arm = 4, //limbs are the most common, with brain/head being the least so, organs in the middle
+ possible_wanted_items = list(/obj/item/bodypart/l_arm = 4,
/obj/item/bodypart/r_arm = 4,
/obj/item/bodypart/l_leg = 4,
/obj/item/bodypart/r_leg = 4,
@@ -299,13 +299,27 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
/obj/item/organ/liver = 2,
/obj/item/organ/lungs = 2,
/obj/item/organ/heart = 2,
- /obj/item/bodypart/eyes = 1.
+ /obj/item/organ/eyes = 1,
/obj/item/organ/brain = 1,
/obj/item/bodypart/head = 1)
+ possible_rewards = list(/obj/item/organ/cyberimp/mouth/breathing_tube = 1,
+ /obj/item/organ/eyes/robotic/thermals = 1,
+ /obj/item/organ/cyberimp/arm/toolset = 1,
+ /obj/item/organ/cyberimp/arm/surgery = 1,
+ /obj/item/organ/cyberimp/arm/janitor = 1,
+ /obj/item/organ/cyberimp/arm/flash = 1,
+ /obj/item/organ/cyberimp/arm/shield = 1,
+ /obj/item/organ/cyberimp/eyes/hud/medical = 1,
+ /obj/item/organ/cyberimp/arm/baton = 1)
+
+/mob/living/carbon/human/dummy/travelling_trader/surgeon/give_reward()
+ var/obj/item/organ/implant = pickweight(possible_rewards)
+ var/obj/item/autosurgeon/reward = new(get_turf(src))
+ reward.insert_organ(implant)
/datum/outfit/otherworldly_surgeon
uniform = /obj/item/clothing/under/pants/white
shoes = /obj/item/clothing/shoes/sneakers/white
gloves = /obj/item/clothing/gloves/color/latex
mask = /obj/item/clothing/mask/surgical
- suit = /obj/item/clothing/suit/apron/surgical
\ No newline at end of file
+ suit = /obj/item/clothing/suit/apron/surgical
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 927da6d625..2b79533e31 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -275,7 +275,7 @@
name = "keg of hearty punch"
desc = "A keg that will get you right back on your feet."
icon_state = "redkeg"
- reagent_id = /datum/reagent/consumable/hearty_punch
+ reagent_id = /datum/reagent/consumable/ethanol/hearty_punch
tank_volume = 100 //this usually has a 15:1 ratio when being made, so we provide less of it
/obj/structure/reagent_dispensers/keg/neurotoxin
From ab01a69c1ff06e7de5eca410b8e1f2645941b1f4 Mon Sep 17 00:00:00 2001
From: timothyteakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 12 Jul 2020 00:53:31 +0100
Subject: [PATCH 07/14] bugfix
---
code/modules/events/travelling_trader.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index 6c2692dc65..2dd2c80b00 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -313,7 +313,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
/obj/item/organ/cyberimp/arm/baton = 1)
/mob/living/carbon/human/dummy/travelling_trader/surgeon/give_reward()
- var/obj/item/organ/implant = pickweight(possible_rewards)
+ var/obj/item/organ/implant = new pickweight(possible_rewards)
var/obj/item/autosurgeon/reward = new(get_turf(src))
reward.insert_organ(implant)
From cff2e3d680ddcaddbdd0e59fc68be3990417e2e1 Mon Sep 17 00:00:00 2001
From: timothyteakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 12 Jul 2020 00:58:34 +0100
Subject: [PATCH 08/14] never set max amount to 0
---
code/game/objects/items/stacks/tape.dm | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/code/game/objects/items/stacks/tape.dm b/code/game/objects/items/stacks/tape.dm
index 8e8e2eaf52..d33d106d11 100644
--- a/code/game/objects/items/stacks/tape.dm
+++ b/code/game/objects/items/stacks/tape.dm
@@ -15,6 +15,7 @@
var/list/conferred_embed = EMBED_HARMLESS
var/overwrite_existing = FALSE
+ var/endless = FALSE
var/apply_time = 30
/obj/item/stack/sticky_tape/afterattack(obj/item/I, mob/living/user)
@@ -31,7 +32,7 @@
I.embedding = conferred_embed
I.updateEmbedding()
to_chat(user, "You finish wrapping [I] with [src].")
- if(max_amount > 0)
+ if(!endless)
use(1)
I.name = "[prefix] [I.name]"
@@ -42,7 +43,7 @@
/obj/item/stack/sticky_tape/infinite //endless tape that applies far faster, for maximum honks
name = "endless sticky tape"
desc = "This roll of sticky tape somehow has no end."
- max_amount = 0
+ endless = TRUE
apply_time = 10
/obj/item/stack/sticky_tape/super
From 8e31e3c5340fbfc824101c73f9d353931f25857b Mon Sep 17 00:00:00 2001
From: timothyteakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 12 Jul 2020 01:56:24 +0100
Subject: [PATCH 09/14] a tonne of fixes
---
code/modules/events/travelling_trader.dm | 33 ++++++++++++++----------
1 file changed, 19 insertions(+), 14 deletions(-)
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index 2dd2c80b00..9de8f75fd3 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -128,7 +128,10 @@
/mob/living/carbon/human/dummy/travelling_trader/cook/Initialize()
//pick a random crafted food item as the requested item
- requested_item = GLOB.crafting_recipes[pick(subtypesof( /datum/crafting_recipe/food))].result
+ var/recipe = pick(subtypesof(/datum/crafting_recipe/food))
+ var/datum/crafting_recipe/food/new_recipe = new recipe
+ requested_item = new_recipe.result
+ qdel(new_recipe) //we don't need it anymore
..()
//botanist
@@ -136,7 +139,7 @@
trader_name = "Otherworldly Gardener"
trader_outfit = /datum/outfit/job/botanist
initial_speech = "I have come across this realm in search of rare plants and believe this station may be able to help me.."
- request_speech = "Are you able to bring me a requested_item? I could see that you get some reward for this task."
+ request_speech = "Are you able to bring me the plant known to you as: 'requested_item'? I could see that you get some reward for this task."
acceptance_speech = "Amazing! Ill finally be able to make that salad. Goodbye for now!"
refusal_speech = "A given_item? Did nobody ever teach you the basics of gardening?"
possible_rewards = list(/obj/item/seeds/cherry/bomb = 1,
@@ -175,8 +178,9 @@
/mob/living/simple_animal/hostile/retaliate/clown/fleshclown = 1,
/mob/living/simple_animal/hostile/tree = 1,
/mob/living/simple_animal/hostile/mimic = 1,
- /mob/living/simple_animal/hostile/shark/laser = 1
- )
+ /mob/living/simple_animal/hostile/shark = 1,
+ /mob/living/simple_animal/hostile/netherworld/blankbody = 1,
+ /mob/living/simple_animal/hostile/retaliate/goose = 1)
mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
acceptance_speech = pick(list("This lifeform shall make for a great stew, thank you.", "This lifeform shall be of a true use to our cause, thank you.", "The lifeform is adequate. Goodbye.", "This lifeform shall make a great addition to my collection."))
@@ -197,12 +201,13 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
return FALSE
/mob/living/carbon/human/dummy/travelling_trader/animal_hunter/give_reward(var/mob/giver) //the reward is actually given in a jar, because releasing it onto the station might be a bad idea
- var/mob/living/animal = pickweight(possible_rewards)
- if(giver && giver.tag)
- animal.faction += "\[[giver.tag]\]"
var/obj/item/pet_carrier/bluespace/jar = new(get_turf(src))
- jar.add_occupant(animal)
- jar.name = "WARNING: [animal] INSIDE"
+ var/chosen_animal = pickweight(possible_rewards)
+ var/mob/living/new_animal = new chosen_animal(jar)
+ if(giver && giver.tag)
+ new_animal.faction += "\[[giver.tag]\]"
+ jar.add_occupant(new_animal)
+ jar.name = "WARNING: [new_animal]"
//bartender
/mob/living/carbon/human/dummy/travelling_trader/bartender
@@ -218,7 +223,6 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
/obj/structure/reagent_dispensers/keg/narsour = 3,
/obj/structure/reagent_dispensers/keg/quintuple_sec = 3)
-
/mob/living/carbon/human/dummy/travelling_trader/bartender/Initialize() //pick a subtype of ethanol that isn't found in the default set of the booze dispensers reagents
requested_item = pick(subtypesof(/datum/reagent/consumable/ethanol) - list(/datum/reagent/consumable/ethanol/beer,
/datum/reagent/consumable/ethanol/kahlua,
@@ -253,7 +257,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
trader_name = "Otherworldly Artifact Dealer"
trader_outfit = /datum/outfit/artifact_dealer //he's cool enough to get his own outfit
initial_speech = "I have come here due to sensing the existence of an object of great power and importance."
- request_speech = "Give to me a requested_item and I shall make it worth your while, traveller."
+ request_speech = "Give to me the great object known as: requested_item and I shall make it worth your while, traveller."
acceptance_speech = "This is truly an artifact worthy of my collection, thank you."
refusal_speech = "A given_item? Hah! Worthless."
possible_wanted_items = list(/obj/item/pen/fountain/captain = 1, //various rare things and high risk but not useful things (i.e. champion belt, bedsheet, pen)
@@ -288,7 +292,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
trader_name = "Otherworldly Surgeon"
trader_outfit = /datum/outfit/otherworldly_surgeon
initial_speech = "Hello there, meatbag. You can provide me with something I want."
- request_speech = "Find me a requested_item. I shall make sure it's worth your efforts."
+ request_speech = "Find me the appendage you call 'requested_item'. I shall make sure it's worth your efforts."
acceptance_speech = "This shall do. Goodbye, meatbag."
refusal_speech = "That is not what I wish for. Give me a requested_item, or I shall take one by force."
possible_wanted_items = list(/obj/item/bodypart/l_arm = 4,
@@ -313,9 +317,10 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
/obj/item/organ/cyberimp/arm/baton = 1)
/mob/living/carbon/human/dummy/travelling_trader/surgeon/give_reward()
- var/obj/item/organ/implant = new pickweight(possible_rewards)
+ var/chosen_implant = pickweight(possible_rewards)
+ var/new_implant = new chosen_implant
var/obj/item/autosurgeon/reward = new(get_turf(src))
- reward.insert_organ(implant)
+ reward.insert_organ(new_implant)
/datum/outfit/otherworldly_surgeon
uniform = /obj/item/clothing/under/pants/white
From fbb9fe2d9cba7e9ec548950c3f5a4c39a355373b Mon Sep 17 00:00:00 2001
From: timothyteakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 12 Jul 2020 02:14:50 +0100
Subject: [PATCH 10/14] better fork
---
code/game/objects/items/kitchen.dm | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm
index 1d4610488d..a06461180c 100644
--- a/code/game/objects/items/kitchen.dm
+++ b/code/game/objects/items/kitchen.dm
@@ -58,7 +58,9 @@
name = "throwing fork"
desc = "A fork, sharpened to perfection, making it a great weapon for throwing."
throwforce = 15
- embedding = list("pain_mult" = 2, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 100)
+ throw_speed = 3
+ throw_range = 6
+ embedding = list("pain_mult" = 2, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
sharpness = IS_SHARP_ACCURATE
/obj/item/kitchen/knife
From 3e5f98182521e36e051d2289f0de273113d8022a Mon Sep 17 00:00:00 2001
From: timothyteakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 12 Jul 2020 03:17:50 +0100
Subject: [PATCH 11/14] speed 4 for embeds
---
code/game/objects/items/kitchen.dm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm
index a06461180c..2c00265ce8 100644
--- a/code/game/objects/items/kitchen.dm
+++ b/code/game/objects/items/kitchen.dm
@@ -58,10 +58,10 @@
name = "throwing fork"
desc = "A fork, sharpened to perfection, making it a great weapon for throwing."
throwforce = 15
- throw_speed = 3
+ throw_speed = 4
throw_range = 6
embedding = list("pain_mult" = 2, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
- sharpness = IS_SHARP_ACCURATE
+ sharpness = IS_SHARP
/obj/item/kitchen/knife
name = "kitchen knife"
From 070513044844c2c0611b27dbb8a47d36d168f6d4 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 12 Jul 2020 17:31:37 +0100
Subject: [PATCH 12/14] small edgecase
---
code/modules/events/travelling_trader.dm | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index 9de8f75fd3..b3cd8cecaa 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -130,7 +130,10 @@
//pick a random crafted food item as the requested item
var/recipe = pick(subtypesof(/datum/crafting_recipe/food))
var/datum/crafting_recipe/food/new_recipe = new recipe
- requested_item = new_recipe.result
+ if(istype(new_recipe.result, /obj/item/reagent_containers/food)) //not all food recipes make food objects (like cak/butterbear)
+ requested_item = new_recipe.result
+ else
+ requested_item = /obj/item/reagent_containers/food/snacks/copypasta
qdel(new_recipe) //we don't need it anymore
..()
From c0687886e4f5e4efd3b6de848ae4a2d0bded884f Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 12 Jul 2020 21:38:09 +0100
Subject: [PATCH 13/14] using initial is better practice
---
code/modules/events/travelling_trader.dm | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index b3cd8cecaa..b7afc3440e 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -55,9 +55,7 @@
/mob/living/carbon/human/dummy/travelling_trader/proc/setup_speech(var/input_speech, var/obj/item/given_item)
if(requested_item)
- var/atom/temp_requested = new requested_item
- input_speech = replacetext(input_speech, "requested_item", temp_requested.name)
- qdel(temp_requested)
+ input_speech = replacetext(input_speech, "requested_item", initial(requested_item.name))
if(given_item)
input_speech = replacetext(input_speech, "given_item", given_item.name)
return input_speech
@@ -128,13 +126,12 @@
/mob/living/carbon/human/dummy/travelling_trader/cook/Initialize()
//pick a random crafted food item as the requested item
- var/recipe = pick(subtypesof(/datum/crafting_recipe/food))
- var/datum/crafting_recipe/food/new_recipe = new recipe
- if(istype(new_recipe.result, /obj/item/reagent_containers/food)) //not all food recipes make food objects (like cak/butterbear)
- requested_item = new_recipe.result
+ var/datum/crafting_recipe/food_recipe = pick(subtypesof(/datum/crafting_recipe/food))
+ var/result = initial(food_recipe.result)
+ if(ispath(result, /obj/item/reagent_containers/food)) //not all food recipes make food objects (like cak/butterbear)
+ requested_item = result
else
requested_item = /obj/item/reagent_containers/food/snacks/copypasta
- qdel(new_recipe) //we don't need it anymore
..()
//botanist
From 29628dd82a08b2a917b43686a5fcd42bf2d67f91 Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Sun, 12 Jul 2020 21:40:16 +0100
Subject: [PATCH 14/14] cows
---
code/modules/mob/living/simple_animal/friendly/farm_animals.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index b42216c2cc..6749c771be 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -199,7 +199,7 @@
/mob/living/simple_animal/cow/random/Initialize()
milk_reagent = get_random_reagent_id() //this has a blacklist so don't worry about romerol cows, etc
-
+ ..()
//Wisdom cow, speaks and bestows great wisdoms
/mob/living/simple_animal/cow/wisdom