From 3e49f1ef293090bb1e4cc2d3a9989ba6b8f21bd4 Mon Sep 17 00:00:00 2001
From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
Date: Sun, 8 Oct 2023 14:26:42 +0100
Subject: [PATCH] Strange object refactor (#22774)
---
code/modules/research/experimentor.dm | 139 +--------------
code/modules/research/strange_objects.dm | 217 +++++++++++++++++++++++
paradise.dme | 1 +
3 files changed, 219 insertions(+), 138 deletions(-)
create mode 100644 code/modules/research/strange_objects.dm
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index 084c4bed0b3..7baeb24ecce 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -474,7 +474,7 @@
playsound(loc, 'sound/effects/supermatter.ogg', 50, 3, -1)
var/obj/item/relic/R = loaded_item
R.reveal()
- investigate_log("Experimentor has revealed a relic with [R.realProc] effect.", "experimentor")
+ investigate_log("Experimentor has revealed a relic with effect ID [R.function_id] effect.", "experimentor")
ejectItem()
//Global reactions
@@ -594,140 +594,3 @@
#undef EFFECT_PROB_VERYHIGH
#undef FAIL
-
-
-//////////////////////////////////SPECIAL ITEMS////////////////////////////////////////
-
-/obj/item/relic
- name = "strange object"
- desc = "What mysteries could this hold?"
- icon = 'icons/obj/assemblies.dmi'
- icon_state = "prox-radio1" // it is immediately overriden in New, but setting it here makes it show in mapeditor
- origin_tech = "combat=1;plasmatech=1;powerstorage=1;materials=1"
- var/realName = "defined object"
- var/revealed = FALSE
- var/realProc
- var/cooldownMax = 60
- var/cooldown
- var/floof
-
-/obj/item/relic/New()
- ..()
- icon_state = pick("shock_kit","armor-igniter-analyzer","infra-igniter0","infra-igniter1","radio-multitool","prox-radio1","radio-radio","timer-multitool0","radio-igniter-tank")
- realName = "[pick("broken","twisted","spun","improved","silly","regular","badly made")] [pick("device","object","toy","suspicious tech","gear")]"
- floof = pick(/mob/living/simple_animal/pet/dog/corgi, /mob/living/simple_animal/pet/cat, /mob/living/simple_animal/pet/dog/fox, /mob/living/simple_animal/mouse, /mob/living/simple_animal/pet/dog/pug, /mob/living/simple_animal/lizard, /mob/living/simple_animal/diona, /mob/living/simple_animal/butterfly, /mob/living/carbon/human/monkey)
-
-
-/obj/item/relic/proc/reveal()
- if(revealed) //Re-rolling your relics seems a bit overpowered, yes?
- return
- revealed = TRUE
- name = realName
- cooldownMax = rand(60, 300)
- realProc = pick("teleport","explode","rapidDupe","petSpray","flash","clean","floofcannon")
- origin_tech = pick("engineering=[rand(2,5)]","magnets=[rand(2,5)]","plasmatech=[rand(2,5)]","programming=[rand(2,5)]","powerstorage=[rand(2,5)]")
-
-/obj/item/relic/attack_self(mob/user)
- if(revealed)
- if(cooldown)
- to_chat(user, "[src] does not react!")
- return
- else if(loc == user)
- cooldown = TRUE
- call(src,realProc)(user)
- spawn(cooldownMax)
- cooldown = FALSE
- else
- to_chat(user, "You aren't quite sure what to do with this, yet.")
-
-//////////////// RELIC PROCS /////////////////////////////
-
-/obj/item/relic/proc/throwSmoke(turf/where)
- var/datum/effect_system/smoke_spread/smoke = new
- smoke.set_up(1, FALSE, where)
- smoke.start()
-
-/obj/item/relic/proc/floofcannon(mob/user)
- playsound(loc, "sparks", rand(25, 50), TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- var/mob/living/C = new floof(get_turf(user))
- C.throw_at(pick(oview(10,user)),10,rand(3,8))
- throwSmoke(get_turf(C))
- warn_admins(user, "Floof Cannon", 0)
-
-/obj/item/relic/proc/clean(mob/user)
- playsound(loc, "sparks", rand(25,50), TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- var/obj/item/grenade/chem_grenade/cleaner/CL = new/obj/item/grenade/chem_grenade/cleaner(get_turf(user))
- CL.prime()
- warn_admins(user, "Smoke", 0)
-
-/obj/item/relic/proc/flash(mob/user)
- playsound(loc, "sparks", rand(25,50), TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- var/obj/item/grenade/flashbang/CB = new/obj/item/grenade/flashbang(get_turf(user))
- CB.prime()
- warn_admins(user, "Flash")
-
-/obj/item/relic/proc/petSpray(mob/user)
- var/message = "[src] begins to shake, and in the distance the sound of rampaging animals arises!"
- visible_message(message)
- to_chat(user, message)
- var/animals = rand(1,25)
- var/counter
- var/list/valid_animals = list(/mob/living/simple_animal/parrot,/mob/living/simple_animal/butterfly,/mob/living/simple_animal/pet/cat,/mob/living/simple_animal/pet/dog/corgi,/mob/living/simple_animal/crab,/mob/living/simple_animal/pet/dog/fox,/mob/living/simple_animal/lizard,/mob/living/simple_animal/mouse,/mob/living/simple_animal/pet/dog/pug,/mob/living/simple_animal/hostile/bear,/mob/living/simple_animal/hostile/poison/bees,/mob/living/simple_animal/hostile/carp)
- for(counter = 1; counter < animals; counter++)
- var/mobType = pick(valid_animals)
- new mobType(get_turf(src))
- warn_admins(user, "Mass Mob Spawn")
- if(prob(60))
- to_chat(user, "[src] falls apart!")
- qdel(src)
-
-/obj/item/relic/proc/rapidDupe(mob/user)
- audible_message("[src] emits a loud pop!")
- var/list/dupes = list()
- var/counter
- var/max = rand(5,10)
- for(counter = 1; counter < max; counter++)
- var/obj/item/relic/R = new type(get_turf(src))
- R.name = name
- R.desc = desc
- R.realName = realName
- R.realProc = realProc
- R.revealed = TRUE
- dupes |= R
- spawn()
- R.throw_at(pick(oview(7,get_turf(src))),10,1)
- counter = 0
- spawn(rand(10, 100))
- for(counter = 1; counter <= dupes.len; counter++)
- var/obj/item/relic/R = dupes[counter]
- qdel(R)
- warn_admins(user, "Rapid duplicator", 0)
-
-/obj/item/relic/proc/explode(mob/user)
- to_chat(user, "[src] begins to heat up!")
- spawn(rand(35,100))
- if(loc == user)
- visible_message("[src]'s top opens, releasing a powerful blast!")
- explosion(user.loc, -1, rand(1,5), rand(1,5), rand(1,5), rand(1,5), flame_range = 2)
- warn_admins(user, "Explosion")
- qdel(src) //Comment this line to produce a light grenade (the bomb that keeps on exploding when used)!!
-
-/obj/item/relic/proc/teleport(mob/user)
- to_chat(user, "[src] begins to vibrate!")
- spawn(rand(10, 30))
- var/turf/userturf = get_turf(user)
- if(loc == user && is_teleport_allowed(userturf.z)) //Because Nuke Ops bringing this back on their shuttle, then looting the ERT area is 2fun4you!
- visible_message("[src] twists and bends, relocating itself!")
- throwSmoke(userturf)
- do_teleport(user, userturf, 8, sound_in = 'sound/effects/phasein.ogg')
- throwSmoke(get_turf(user))
- warn_admins(user, "Teleport", 0)
-
-//Admin Warning proc for relics
-/obj/item/relic/proc/warn_admins(mob/user, RelicType, priority = 1)
- var/turf/T = get_turf(src)
- var/log_msg = "[RelicType] relic used by [key_name(user)] in ([T.x],[T.y],[T.z])"
- if(priority) //For truly dangerous relics that may need an admin's attention. BWOINK!
- message_admins("[RelicType] relic activated by [key_name_admin(user)] in ([T.x], [T.y], [T.z] - JMP)",0,1)
- log_game(log_msg)
- investigate_log(log_msg, "experimentor")
diff --git a/code/modules/research/strange_objects.dm b/code/modules/research/strange_objects.dm
new file mode 100644
index 00000000000..38137e88d1d
--- /dev/null
+++ b/code/modules/research/strange_objects.dm
@@ -0,0 +1,217 @@
+#define STRANGEOBJECT_FUNCTION_TELEPORT 1
+#define STRANGEOBJECT_FUNCTION_EXPLODE 2
+#define STRANGEOBJECT_FUNCTION_RAPID_DUPE 3
+#define STRANGEOBJECT_FUNCTION_MASS_SPAWN 4
+#define STRANGEOBJECT_FUNCTION_FLASH 5
+#define STRANGEOBJECT_FUNCTION_CLEAN 6
+#define STRANGEOBJECT_FUNCTION_PET_SPAWN 7
+
+/obj/item/relic
+ name = "strange object"
+ desc = "What mysteries could this hold?"
+ icon = 'icons/obj/assemblies.dmi'
+ icon_state = "prox-radio1" // it is immediately overriden in New, but setting it here makes it show in mapeditor
+ origin_tech = "combat=1;plasmatech=1;powerstorage=1;materials=1"
+ /// The name this object will get when it is discovered
+ var/real_name = "defined object"
+ /// Has this object been discovered?
+ var/revealed = FALSE
+ /// What is the real function of this object?
+ var/function_id
+ /// Duration of the cooldown
+ var/cooldown_duration = 60
+ /// Actual cooldown
+ var/last_use_time
+ /// Mob this object should spawn if [STRANGEOBJECT_FUNCTION_PET_SPAWN] is picked.
+ var/petspawn_mob
+
+/obj/item/relic/Initialize(mapload)
+ . = ..()
+
+ icon_state = pick(
+ "shock_kit",
+ "armor-igniter-analyzer",
+ "infra-igniter0",
+ "infra-igniter1",
+ "radio-multitool",
+ "prox-radio1",
+ "radio-radio",
+ "timer-multitool0",
+ "radio-igniter-tank",
+ )
+
+ var/realname_part1 = pick("broken","twisted","spun","improved","silly","regular","badly made")
+ var/realname_part2 = pick("device","object","toy","suspicious tech","gear")
+
+ real_name = "[realname_part1] [realname_part2]"
+
+ petspawn_mob = pick(
+ /mob/living/simple_animal/pet/dog/corgi,
+ /mob/living/simple_animal/pet/cat,
+ /mob/living/simple_animal/pet/dog/fox,
+ /mob/living/simple_animal/mouse,
+ /mob/living/simple_animal/pet/dog/pug,
+ /mob/living/simple_animal/lizard,
+ /mob/living/simple_animal/diona,
+ /mob/living/simple_animal/butterfly,
+ /mob/living/carbon/human/monkey,
+ )
+
+
+/obj/item/relic/proc/reveal()
+ if(revealed) //Re-rolling your relics seems a bit overpowered, yes?
+ return
+
+ revealed = TRUE
+ name = real_name
+ cooldown_duration = rand(60, 300)
+
+ function_id = pick(
+ STRANGEOBJECT_FUNCTION_TELEPORT,
+ STRANGEOBJECT_FUNCTION_EXPLODE,
+ STRANGEOBJECT_FUNCTION_RAPID_DUPE,
+ STRANGEOBJECT_FUNCTION_MASS_SPAWN,
+ STRANGEOBJECT_FUNCTION_FLASH,
+ STRANGEOBJECT_FUNCTION_CLEAN,
+ STRANGEOBJECT_FUNCTION_PET_SPAWN,
+ )
+
+ origin_tech = pick(
+ "engineering=[rand(2,5)]",
+ "magnets=[rand(2,5)]",
+ "plasmatech=[rand(2,5)]",
+ "programming=[rand(2,5)]",
+ "powerstorage=[rand(2,5)]",
+ )
+
+
+/obj/item/relic/attack_self(mob/user)
+ if(revealed)
+ if((last_use_time + cooldown_duration) > world.time)
+ to_chat(user, "[src] does not react!")
+ return
+ else if(loc == user)
+ last_use_time = world.time
+
+ // Figure out our real function
+ switch(function_id)
+ if(STRANGEOBJECT_FUNCTION_TELEPORT)
+ to_chat(user, "[src] begins to vibrate!")
+ addtimer(CALLBACK(src, PROC_REF(teleport_callback), user), rand(10, 30))
+
+ if(STRANGEOBJECT_FUNCTION_EXPLODE)
+ to_chat(user, "[src] begins to heat up!")
+ addtimer(CALLBACK(src, PROC_REF(explode_callback), user), rand(35, 100))
+
+ if(STRANGEOBJECT_FUNCTION_RAPID_DUPE)
+ audible_message("[src] emits a loud pop!")
+ for(var/i in 1 to rand(5, 10))
+ var/obj/item/relic/R = new type(get_turf(src))
+ R.name = name
+ R.desc = desc
+ R.function_id = function_id
+ R.revealed = TRUE
+ QDEL_IN(R, rand(10, 100))
+ INVOKE_ASYNC(R, TYPE_PROC_REF(/atom/movable, throw_at), pick(oview(7, get_turf(src))), 10, 1)
+
+ warn_admins(user, "Rapid duplicator", 0)
+
+ if(STRANGEOBJECT_FUNCTION_MASS_SPAWN)
+ // This is the unlucky one
+ var/message = "[src] begins to shake, and in the distance the sound of rampaging animals arises!"
+ visible_message(message)
+ to_chat(user, message)
+ var/animal_spawncount = rand(1,25)
+
+ var/list/valid_animals = list(
+ /mob/living/simple_animal/parrot,
+ /mob/living/simple_animal/butterfly,
+ /mob/living/simple_animal/pet/cat,
+ /mob/living/simple_animal/pet/dog/corgi,
+ /mob/living/simple_animal/crab,
+ /mob/living/simple_animal/pet/dog/fox,
+ /mob/living/simple_animal/lizard,
+ /mob/living/simple_animal/mouse,
+ /mob/living/simple_animal/pet/dog/pug,
+ /mob/living/simple_animal/hostile/bear,
+ /mob/living/simple_animal/hostile/poison/bees,
+ /mob/living/simple_animal/hostile/carp
+ )
+
+ for(var/counter in 1 to animal_spawncount)
+ var/mob_type = pick(valid_animals)
+ new mob_type(get_turf(src))
+
+ warn_admins(user, "Mass Mob Spawn")
+ if(prob(60))
+ to_chat(user, "[src] falls apart!")
+ qdel(src)
+
+ if(STRANGEOBJECT_FUNCTION_FLASH)
+ playsound(loc, "sparks", rand(25,50), TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
+ var/obj/item/grenade/flashbang/CB = new/obj/item/grenade/flashbang(get_turf(user))
+ CB.prime()
+ warn_admins(user, "Flash")
+
+ if(STRANGEOBJECT_FUNCTION_CLEAN)
+ playsound(loc, "sparks", rand(25,50), TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
+ var/obj/item/grenade/chem_grenade/cleaner/CL = new/obj/item/grenade/chem_grenade/cleaner(get_turf(user))
+ CL.prime()
+ warn_admins(user, "Clean", 0)
+
+ if(STRANGEOBJECT_FUNCTION_PET_SPAWN)
+ playsound(loc, "sparks", rand(25, 50), TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
+ var/mob/living/C = new petspawn_mob(get_turf(user))
+ C.throw_at(pick(oview(10,user)),10,rand(3,8))
+ throw_smoke(get_turf(C))
+ warn_admins(user, "Pet Spawn", 0)
+
+ else
+ to_chat(user, "You aren't quite sure what to do with this, yet.")
+
+
+// Callbacks for timers
+/obj/item/relic/proc/teleport_callback(mob/user)
+ var/turf/userturf = get_turf(user)
+ if(loc == user && is_teleport_allowed(userturf.z)) //Because Nuke Ops bringing this back on their shuttle, then looting the ERT area is 2fun4you!
+ visible_message("[src] twists and bends, relocating itself!")
+ throw_smoke(userturf)
+ do_teleport(user, userturf, 8, sound_in = 'sound/effects/phasein.ogg')
+ throw_smoke(get_turf(user))
+ warn_admins(user, "Teleport", 0)
+
+
+/obj/item/relic/proc/explode_callback(mob/user)
+ if(loc == user)
+ visible_message("[src]'s top opens, releasing a powerful blast!")
+ explosion(user.loc, -1, rand(1,5), rand(1,5), rand(1,5), rand(1,5), flame_range = 2)
+ warn_admins(user, "Explosion")
+ qdel(src)
+
+
+// Admin Warning proc for relics
+/obj/item/relic/proc/warn_admins(mob/user, RelicType, alert_admins = TRUE)
+ var/turf/T = get_turf(src)
+ var/log_msg = "[RelicType] relic used by [key_name(user)] in ([T.x],[T.y],[T.z])"
+
+ if(alert_admins) //For truly dangerous relics that may need an admin's attention. BWOINK!
+ message_admins("[RelicType] relic activated by [key_name_admin(user)] in ([T.x], [T.y], [T.z] - JMP)",0,1)
+
+ log_game(log_msg)
+ investigate_log(log_msg, "experimentor")
+
+
+// Make some magic smoke
+/obj/item/relic/proc/throw_smoke(turf/where)
+ var/datum/effect_system/smoke_spread/smoke = new
+ smoke.set_up(1, FALSE, where)
+ smoke.start()
+
+
+#undef STRANGEOBJECT_FUNCTION_TELEPORT
+#undef STRANGEOBJECT_FUNCTION_EXPLODE
+#undef STRANGEOBJECT_FUNCTION_RAPID_DUPE
+#undef STRANGEOBJECT_FUNCTION_MASS_SPAWN
+#undef STRANGEOBJECT_FUNCTION_FLASH
+#undef STRANGEOBJECT_FUNCTION_CLEAN
+#undef STRANGEOBJECT_FUNCTION_PET_SPAWN
diff --git a/paradise.dme b/paradise.dme
index 21e2a953b7f..8a9f3b08384 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -2553,6 +2553,7 @@
#include "code\modules\research\rdmachines.dm"
#include "code\modules\research\research.dm"
#include "code\modules\research\server.dm"
+#include "code\modules\research\strange_objects.dm"
#include "code\modules\research\anomaly\anomaly.dm"
#include "code\modules\research\designs\AI_module_designs.dm"
#include "code\modules\research\designs\autolathe_designs.dm"