This commit is contained in:
Enric Gabriel
2020-09-06 10:42:43 -03:00
43 changed files with 853 additions and 103 deletions
+3 -5
View File
@@ -24,12 +24,10 @@
/datum/asset_cache_item/New(name, file)
if (!isfile(file))
file = fcopy_rsc(file)
hash = md5(file)
hash = md5asfile(file) //icons sent to the rsc sometimes md5 incorrectly
if (!hash)
hash = md5(fcopy_rsc(file))
if (!hash)
CRASH("invalid asset sent to asset cache")
debug_world_log("asset cache unexpected success of second fcopy_rsc")
CRASH("invalid asset sent to asset cache")
src.name = name
var/extstart = findlasttext(name, ".")
if (extstart)
+46
View File
@@ -192,3 +192,49 @@
crate_type = /obj/structure/closet/crate/secure/science
dangerous = TRUE
//////// RAW ANOMALY CORES
/datum/supply_pack/science/raw_flux_anomaly
name = "Raw Flux Anomaly"
desc = "The raw core of a flux anomaly, ready to be implosion-compressed into a powerful artifact."
cost = 5000
access = ACCESS_TOX
contains = list(/obj/item/raw_anomaly_core/flux)
crate_name = "raw flux anomaly"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/raw_grav_anomaly
name = "Raw Gravitational Anomaly"
desc = "The raw core of a gravitational anomaly, ready to be implosion-compressed into a powerful artifact."
cost = 5000
access = ACCESS_TOX
contains = list(/obj/item/raw_anomaly_core/grav)
crate_name = "raw pyro anomaly"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/raw_vortex_anomaly
name = "Raw Vortex Anomaly"
desc = "The raw core of a vortex anomaly, ready to be implosion-compressed into a powerful artifact."
cost = 5000
access = ACCESS_TOX
contains = list(/obj/item/raw_anomaly_core/vortex)
crate_name = "raw vortex anomaly"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/raw_bluespace_anomaly
name = "Raw Bluespace Anomaly"
desc = "The raw core of a bluespace anomaly, ready to be implosion-compressed into a powerful artifact."
cost = 5000
access = ACCESS_TOX
contains = list(/obj/item/raw_anomaly_core/bluespace)
crate_name = "raw bluespace anomaly"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/raw_pyro_anomaly
name = "Raw Pyro Anomaly"
desc = "The raw core of a pyro anomaly, ready to be implosion-compressed into a powerful artifact."
cost = 5000
access = ACCESS_TOX
contains = list(/obj/item/raw_anomaly_core/pyro)
crate_name = "raw pyro anomaly"
crate_type = /obj/structure/closet/crate/secure/science
+2 -2
View File
@@ -22,7 +22,7 @@
max_integrity = 200
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
var/state = 0
var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book) //Things allowed in the bookcase
var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book, /obj/item/gun/magic/wand/book) //Things allowed in the bookcase
/obj/structure/bookcase/examine(mob/user)
. = ..()
@@ -192,7 +192,7 @@
desc = "Crack it open, inhale the musk of its pages, and learn something new."
throw_speed = 1
throw_range = 5
w_class = WEIGHT_CLASS_NORMAL //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever)
w_class = WEIGHT_CLASS_NORMAL //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever)
attack_verb = list("bashed", "whacked", "educated")
resistance_flags = FLAMMABLE
var/dat //Actual page content
@@ -66,6 +66,16 @@
force = 19
custom_materials = list(/datum/material/diamond=4000)
/obj/item/pickaxe/rosegold
name = "rose gold pickaxe"
icon_state = "rgpickaxe"
item_state = "rgpickaxe"
toolspeed = 0.1
desc = "A pickaxe with a light rose gold head and some red glowing runes. Extremely robust at cracking rock walls and digging up dirt."
force = 19
custom_materials = list(/datum/material/gold=4000)
digrange = 3
/obj/item/pickaxe/plasteel
name = "plasteel-tipped pickaxe"
icon_state = "titaxe"
+165 -40
View File
@@ -7,78 +7,202 @@
icon_state = "necrocrate"
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
/obj/structure/closet/crate/necropolis/tendril/random
name = "necropolis crate"
desc = "A chest for a chest, a head for a head."
/obj/structure/closet/crate/necropolis/tendril/random/PopulateContents()
var/loot = rand(1,3)
switch(loot)
if(1)
new /obj/structure/closet/crate/necropolis/tendril/magic(src)
if(2)
new /obj/structure/closet/crate/necropolis/tendril/weapon_armor(src)
if(3)
new /obj/structure/closet/crate/necropolis/tendril/misc(src)
/obj/structure/closet/crate/necropolis/tendril
desc = "It's watching you suspiciously."
/obj/structure/closet/crate/necropolis/tendril/PopulateContents()
var/loot = rand(1,29)
/obj/structure/closet/crate/necropolis/tendril/magic
name = "relic necropolis chest"
/obj/structure/closet/crate/necropolis/tendril/weapon_armor
name = "armament necropolis chest"
/obj/structure/closet/crate/necropolis/tendril/misc
/obj/structure/closet/crate/necropolis/tendril/all
desc = "It's watching you suspiciously."
/obj/structure/closet/crate/necropolis/tendril/magic/PopulateContents()
var/loot = rand(1,10)
switch(loot)
if(1)
new /obj/item/shared_storage/red(src)
if(2)
new /obj/item/clothing/suit/space/hardsuit/cult(src)
if(3)
new /obj/item/soulstone/anybody(src)
if(2)
new /obj/item/rod_of_asclepius(src)
if(3)
new /obj/item/organ/heart/cursed/wizard(src)
if(4)
new /obj/item/katana/cursed(src)
new /obj/item/book/granter/spell/summonitem(src)
if(5)
new /obj/item/clothing/glasses/godeye(src)
new /obj/item/borg/upgrade/modkit/lifesteal(src)
new /obj/item/bedsheet/cult(src)
if(6)
new /obj/item/reagent_containers/glass/bottle/potion/flight(src)
new /obj/item/clothing/neck/necklace/memento_mori(src)
if(7)
new /obj/item/pickaxe/diamond(src)
new /obj/item/warp_cube/red(src)
if(8)
new /obj/item/immortality_talisman(src)
if(9)
new /obj/item/gun/magic/wand/book/healing(src)
if(10)
new /obj/item/reagent_containers/glass/bottle/ichor/red(src)
new /obj/item/reagent_containers/glass/bottle/ichor/blue(src)
new /obj/item/reagent_containers/glass/bottle/ichor/green(src)
/obj/structure/closet/crate/necropolis/tendril/weapon_armor/PopulateContents()
var/loot = rand(1,11)
switch(loot)
if(1)
new /obj/item/clothing/suit/space/hardsuit/cult(src)
if(2)
new /obj/item/katana/lavaland(src)
if(3)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/resonator_blast(src)
else
new /obj/item/disk/design_disk/modkit_disc/rapid_repeater(src)
if(9)
new /obj/item/rod_of_asclepius(src)
if(10)
new /obj/item/organ/heart/cursed/wizard(src)
if(11)
new /obj/item/ship_in_a_bottle(src)
if(12)
if(4)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old(src)
if(13)
new /obj/item/jacobs_ladder(src)
if(14)
if(5)
new /obj/item/nullrod/scythe/talking(src)
if(15)
if(6)
new /obj/item/nullrod/armblade(src)
if(16)
new /obj/item/guardiancreator(src)
if(17)
if(7)
new /obj/item/reagent_containers/food/drinks/bottle/holywater/hell(src)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old(src)
if(8)
new /obj/item/grenade/clusterbuster/inferno(src)
if(9)
new /obj/item/gun/magic/wand/book/shock(src)
if(10)
new /obj/item/gun/magic/wand/book/page(src)
if(11)
new /obj/item/gun/magic/wand/book/spark(src)
/obj/structure/closet/crate/necropolis/tendril/misc/PopulateContents()
var/loot = rand(1,11)
switch(loot)
if(1)
new /obj/item/shared_storage/red(src)
if(2)
new /obj/item/reagent_containers/glass/bottle/potion/flight(src)
if(3)
new /obj/item/ship_in_a_bottle(src)
if(4)
new /obj/item/voodoo(src)
if(5)
new /obj/item/book_of_babel(src)
if(6)
new /obj/item/jacobs_ladder(src)
if(7)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe(src)
else
new /obj/item/disk/design_disk/modkit_disc/bounty(src)
if(18)
new /obj/item/warp_cube/red(src)
if(19)
if(8)
new /obj/item/wisp_lantern(src)
if(20)
new /obj/item/immortality_talisman(src)
if(21)
new /obj/item/gun/magic/hook(src)
if(22)
if(9)
new /obj/item/pickaxe/rosegold(src)
if(10)
new /obj/item/bedsheet/cosmos(src)
new /obj/item/melee/skateboard/hoverboard(src)
if(11)
if(prob(50))
new /obj/item/malf_upgrade
else
new /obj/item/disk/tech_disk/illegal
if(12)
new /obj/item/clothing/suit/space/hardsuit/cult(src)
if(13)
new /obj/item/katana/lavaland(src)
if(14)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/resonator_blast(src)
else
new /obj/item/disk/design_disk/modkit_disc/rapid_repeater(src)
/obj/structure/closet/crate/necropolis/tendril/all/PopulateContents()
var/loot = rand(1,31)
switch(loot)
if(1)
new /obj/item/shared_storage/red(src)
if(2)
new /obj/item/reagent_containers/glass/bottle/potion/flight(src)
if(3)
new /obj/item/ship_in_a_bottle(src)
if(4)
new /obj/item/voodoo(src)
if(23)
new /obj/item/grenade/clusterbuster/inferno(src)
if(24)
if(5)
new /obj/item/book_of_babel(src)
if(6)
new /obj/item/jacobs_ladder(src)
if(7)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe(src)
else
new /obj/item/disk/design_disk/modkit_disc/bounty(src)
if(8)
new /obj/item/wisp_lantern(src)
if(9)
new /obj/item/pickaxe/rosegold(src)
if(10)
new /obj/item/bedsheet/cosmos(src)
new /obj/item/melee/skateboard/hoverboard(src)
if(11)
new /obj/item/disk/tech_disk/illegal
if(15)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old(src)
if(16)
new /obj/item/nullrod/scythe/talking(src)
if(17)
new /obj/item/nullrod/armblade(src)
if(18)
new /obj/item/reagent_containers/food/drinks/bottle/holywater/hell(src)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old(src)
if(19)
new /obj/item/grenade/clusterbuster/inferno(src)
if(20)
new /obj/item/gun/magic/wand/book/shock(src)
if(21)
new /obj/item/gun/magic/wand/book/page(src)
if(22)
new /obj/item/gun/magic/wand/book/spark(src)
if(23)
new /obj/item/soulstone/anybody(src)
if(24)
new /obj/item/rod_of_asclepius(src)
if(25)
new /obj/item/book/granter/spell/summonitem(src)
new /obj/item/organ/heart/cursed/wizard(src)
if(26)
new /obj/item/book_of_babel(src)
new /obj/item/book/granter/spell/summonitem(src)
if(27)
new /obj/item/borg/upgrade/modkit/lifesteal(src)
new /obj/item/bedsheet/cult(src)
if(28)
new /obj/item/clothing/neck/necklace/memento_mori(src)
if(28)
new /obj/item/warp_cube/red(src)
if(29)
new /obj/item/disk/tech_disk/illegal(src)
new /obj/item/immortality_talisman(src)
if(30)
new /obj/item/gun/magic/wand/book/healing(src)
if(31)
new /obj/item/reagent_containers/glass/bottle/ichor/red(src)
new /obj/item/reagent_containers/glass/bottle/ichor/blue(src)
new /obj/item/reagent_containers/glass/bottle/ichor/green(src)
//KA modkit design discs
/obj/item/disk/design_disk/modkit_disc
@@ -744,7 +868,7 @@
new /obj/item/lava_staff(src)
if(3)
new /obj/item/book/granter/spell/sacredflame(src)
new /obj/item/gun/magic/wand/fireball(src)
new /obj/item/gun/magic/hook(src)
if(4)
new /obj/item/dragons_blood(src)
@@ -983,7 +1107,7 @@
if(2)
new /obj/item/gun/ballistic/revolver/doublebarrel/super(src)
if(3)
new /obj/item/gun/magic/staff/spellblade(src)
new /obj/item/guardiancreator(src)
/obj/structure/closet/crate/necropolis/bubblegum/crusher
name = "bloody bubblegum chest"
@@ -1072,6 +1196,7 @@
var/random_crystal = pick(choices)
new random_crystal(src)
new /obj/item/organ/vocal_cords/colossus(src)
new /obj/item/clothing/glasses/godeye(src)
/obj/structure/closet/crate/necropolis/colossus/crusher
name = "angelic colossus chest"
@@ -141,7 +141,7 @@ Difficulty: Medium
loot = list(/obj/item/staff/storm)
elimination = 0
else if(prob(20))
loot = list(/obj/structure/closet/crate/necropolis/tendril)
loot = list(/obj/structure/closet/crate/necropolis/tendril/random) //This one spawns a chest that could be any of the three types
..()
/obj/item/gps/internal/legion
@@ -25,6 +25,7 @@
var/list/attack_action_types = list()
var/can_talk = FALSE
var/obj/loot_drop = null
var/crate_type = /obj/structure/closet/crate/necropolis/tendril
var/owner
//Gives player-controlled variants the ability to swap attacks
@@ -182,7 +183,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
activator = null
obj/structure/elite_tumor/proc/spawn_elite(var/mob/dead/observer/elitemind)
/obj/structure/elite_tumor/proc/spawn_elite(var/mob/dead/observer/elitemind)
var/selectedspawn = pick(potentialspawns)
mychild = new selectedspawn(loc)
visible_message("<span class='boldwarning'>[mychild] emerges from [src]!</span>")
@@ -193,7 +194,7 @@ obj/structure/elite_tumor/proc/spawn_elite(var/mob/dead/observer/elitemind)
icon_state = "tumor_popped"
INVOKE_ASYNC(src, .proc/arena_checks)
obj/structure/elite_tumor/proc/return_elite()
/obj/structure/elite_tumor/proc/return_elite()
mychild.forceMove(loc)
visible_message("<span class='boldwarning'>[mychild] emerges from [src]!</span>")
playsound(loc,'sound/effects/phasein.ogg', 200, 0, 50, TRUE, TRUE)
@@ -271,11 +272,11 @@ obj/structure/elite_tumor/proc/return_elite()
visible_message("<span class='boldwarning'>[mychild] suddenly reappears above [src]!</span>")
playsound(loc,'sound/effects/phasein.ogg', 200, 0, 50, TRUE, TRUE)
obj/structure/elite_tumor/proc/onEliteLoss()
/obj/structure/elite_tumor/proc/onEliteLoss()
playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, 0, 50, TRUE, TRUE)
visible_message("<span class='boldwarning'>[src] begins to convulse violently before beginning to dissipate.</span>")
visible_message("<span class='boldwarning'>As [src] closes, something is forced up from down below.</span>")
var/obj/structure/closet/crate/necropolis/tendril/lootbox = new /obj/structure/closet/crate/necropolis/tendril(loc)
var/obj/structure/closet/crate/necropolis/tendril/lootbox = new mychild.crate_type(loc)
if(!boosted)
mychild = null
activator = null
@@ -290,7 +291,7 @@ obj/structure/elite_tumor/proc/onEliteLoss()
activator = null
qdel(src)
obj/structure/elite_tumor/proc/onEliteWon()
/obj/structure/elite_tumor/proc/onEliteWon()
activity = TUMOR_PASSIVE
activator = null
mychild.revive(full_heal = TRUE, admin_revive = TRUE)
@@ -40,6 +40,7 @@
mouse_opacity = MOUSE_OPACITY_ICON
deathmessage = "explodes into gore!"
loot_drop = /obj/item/crusher_trophy/broodmother_tongue
crate_type = /obj/structure/closet/crate/necropolis/tendril/weapon_armor
attack_action_types = list(/datum/action/innate/elite_attack/tentacle_patch,
/datum/action/innate/elite_attack/spawn_children,
@@ -38,7 +38,7 @@
deathsound = 'sound/magic/demon_dies.ogg'
deathmessage = "begins to shudder as it becomes transparent..."
loot_drop = /obj/item/clothing/neck/cloak/herald_cloak
crate_type = /obj/structure/closet/crate/necropolis/tendril/magic
can_talk = 1
attack_action_types = list(/datum/action/innate/elite_attack/herald_trishot,
@@ -38,7 +38,7 @@
deathsound = 'sound/magic/curse.ogg'
deathmessage = "'s arms reach out before it falls apart onto the floor, lifeless."
loot_drop = /obj/item/crusher_trophy/legionnaire_spine
crate_type = /obj/structure/closet/crate/necropolis/tendril/misc
attack_action_types = list(/datum/action/innate/elite_attack/legionnaire_charge,
/datum/action/innate/elite_attack/head_detach,
/datum/action/innate/elite_attack/bonfire_teleport,
@@ -38,7 +38,7 @@
deathsound = 'sound/magic/repulse.ogg'
deathmessage = "'s lights flicker, before its top part falls down."
loot_drop = /obj/item/clothing/accessory/pandora_hope
crate_type = /obj/structure/closet/crate/necropolis/tendril/magic
attack_action_types = list(/datum/action/innate/elite_attack/singular_shot,
/datum/action/innate/elite_attack/magic_box,
/datum/action/innate/elite_attack/pandora_teleport,
@@ -190,4 +190,4 @@
/obj/item/clothing/accessory/pandora_hope/on_uniform_dropped(obj/item/clothing/under/U, user)
var/mob/living/L = user
if(L && L.mind)
SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "hope_lavaland")
SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "hope_lavaland")
@@ -639,7 +639,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(produces_gas)
env.merge(removed)
air_update_turf()
/*********
END CITADEL CHANGES
*********/
@@ -1033,12 +1033,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(L)
switch(type)
if(FLUX_ANOMALY)
var/obj/effect/anomaly/flux/A = new(L, 300, FALSE)
var/obj/effect/anomaly/flux/A = new(L, 300, SUPERMATTER_ANOMALY_DROP_CHANCE)
A.explosive = FALSE
if(GRAVITATIONAL_ANOMALY)
new /obj/effect/anomaly/grav(L, 250, FALSE)
new /obj/effect/anomaly/grav(L, 250, SUPERMATTER_ANOMALY_DROP_CHANCE)
if(PYRO_ANOMALY)
new /obj/effect/anomaly/pyro(L, 200, FALSE)
new /obj/effect/anomaly/pyro(L, 200, SUPERMATTER_ANOMALY_DROP_CHANCE)
/obj/machinery/power/supermatter_crystal/proc/supermatter_zap(atom/zapstart = src, range = 5, zap_str = 4000, zap_flags = ZAP_SUPERMATTER_FLAGS, list/targets_hit = list())
if(QDELETED(zapstart))
@@ -43,3 +43,17 @@
/obj/item/ammo_casing/magic/locker
projectile_type = /obj/item/projectile/magic/locker
//Spell book ammo casing
/obj/item/ammo_casing/magic/book
projectile_type = /obj/item/projectile/magic/spellcard/book
/obj/item/ammo_casing/magic/book/spark
projectile_type = /obj/item/projectile/magic/spellcard/book/spark
/obj/item/ammo_casing/magic/book/heal
projectile_type = /obj/item/projectile/magic/spellcard/book/heal
harmful = FALSE
/obj/item/ammo_casing/magic/book/shock
projectile_type = /obj/item/projectile/magic/spellcard/book/shock
@@ -20,7 +20,6 @@
var/caliber
var/multiload = 1
var/start_empty = 0
var/load_delay = 0 //how long do we take to load (deciseconds)
var/list/bullet_cost
var/list/base_cost// override this one as well if you override bullet_cost
@@ -76,19 +75,12 @@
return 1
/obj/item/ammo_box/attackby(obj/item/A, mob/user, params, silent = FALSE, replace_spent = 0)
if(INTERACTING_WITH(user, src) || INTERACTING_WITH(user, A))
to_chat(user, "<span class='notice'>You're already doing that!</span>")
return FALSE
var/num_loaded = 0
if(!can_load(user))
return
if(istype(A, /obj/item/ammo_box))
var/obj/item/ammo_box/AM = A
for(var/obj/item/ammo_casing/AC in AM.stored_ammo)
if(load_delay || AM.load_delay)
var/loadtime = max(AM.load_delay, load_delay)
if(!do_after(user, loadtime, target = src))
return FALSE
var/did_load = give_round(AC, replace_spent)
if(did_load)
AM.stored_ammo -= AC
@@ -156,8 +156,6 @@
max_ammo = 4
var/pixeloffsetx = 4
start_empty = TRUE
multiload = FALSE
load_delay = 6 //6ds
/obj/item/ammo_box/shotgun/update_overlays()
. = ..()
@@ -53,8 +53,6 @@
..()
if (istype(A, /obj/item/ammo_box/magazine))
var/obj/item/ammo_box/magazine/AM = A
if(AM.load_delay && !do_after(user, AM.load_delay, target = src))
return FALSE
if (!magazine && istype(AM, mag_type))
if(user.transferItemToLoc(AM, src))
magazine = AM
@@ -51,11 +51,6 @@
cell.use(shot.energy_cost)
. = ..()
/obj/item/gun/ballistic/automatic/magrifle/emp_act(severity)
. = ..()
if(!(. & EMP_PROTECT_CONTENTS))
cell.use(round(cell.charge / severity))
/obj/item/gun/ballistic/automatic/magrifle/get_cell()
return cell
@@ -0,0 +1,66 @@
/obj/item/gun/magic/wand/book
name = "blank spellbook"
desc = "It's not just a book, it's a SPELL book!"
ammo_type = /obj/item/ammo_casing/magic
icon = 'icons/obj/library.dmi'
icon_state = "book"
w_class = WEIGHT_CLASS_NORMAL
charges = 10 //We start with max pages
max_charges = 10
variable_charges = FALSE
/obj/item/gun/magic/wand/book/zap_self(mob/living/user)
to_chat(user, "The book has [charges] pages\s remaining.</span>")
/obj/item/gun/magic/wand/book/attackby(obj/item/S, mob/living/user, params)
if(!istype(S, /obj/item/paper))
return ..()
if(charges < max_charges)
charges++
recharge_newshot()
to_chat(user, "You add a new page to [src].</span>")
qdel(S)
update_icon()
process()
else
to_chat(user, "The [src] has no more room for pages!</span>")
//////////////////////
//Spell Book - SPARK//
//////////////////////
/obj/item/gun/magic/wand/book/spark
name = "Spell Book of Spark"
desc = "A spell book that fires burn pages to set the target ablaze!"
ammo_type = /obj/item/ammo_casing/magic/book/spark
icon_state = "spellbook_spark"
//////////////////////
//Spell Book - PAGE///
//////////////////////
/obj/item/gun/magic/wand/book/page
name = "Spell Book of Throw"
desc = "A spell book that throws pages at its target!"
ammo_type = /obj/item/ammo_casing/magic/book
icon_state = "spellbook_page"
//////////////////////
//Spell Book - SHOCK//
//////////////////////
/obj/item/gun/magic/wand/book/shock
name = "Spell Book of Shock"
desc = "A spell book that uses its pages to capture energy in the air and send it in a bolt at its target!"
ammo_type = /obj/item/ammo_casing/magic/book/shock
icon_state = "spellbook_shock"
////////////////////////
//Spell Book - HEALING//
////////////////////////
/obj/item/gun/magic/wand/book/healing
name = "Spell Book of Mending"
desc = "A spell book that uses its pages to heal and repair the target! The back of the book lists what it works on, and it seems to only be of flesh and of metal beings..."
ammo_type = /obj/item/ammo_casing/magic/book/heal
icon_state = "spellbook_healing"
@@ -4,3 +4,60 @@
icon_state = "spellcard"
damage_type = BURN
damage = 2
/obj/item/projectile/magic/spellcard/book
nodamage = FALSE
name = "enchanted page"
desc = "A piece of paper enchanted to give it extreme durability and stiffness, along with a very hot burn to anyone unfortunate enough to get hit by a charged one."
icon_state = "spellcard"
damage_type = BURN
damage = 12
flag = "magic"
/obj/item/projectile/magic/spellcard/book/spark
damage = 4
var/fire_stacks = 4
/obj/item/projectile/magic/spellcard/book/spark/on_hit(atom/target, blocked = FALSE)
. = ..()
var/mob/living/carbon/M = target
if(ismob(target))
if(M.anti_magic_check())
M.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
return BULLET_ACT_BLOCK
if(iscarbon(target))
M.adjust_fire_stacks(fire_stacks)
M.IgniteMob()
return
else
damage = 20 //If we are a simplemob we deal 5x damage
/obj/item/projectile/magic/spellcard/book/shock
damage = 0
stamina = 11
stutter = 5
jitter = 20
knockdown = 10
/obj/item/projectile/magic/spellcard/book/heal
damage = 0
nodamage = TRUE
/obj/item/projectile/magic/spellcard/book/heal/on_hit(atom/target, blocked = FALSE)
. = ..()
var/mob/living/carbon/M = target
if(ismob(target))
if(M.anti_magic_check())
M.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
return BULLET_ACT_BLOCK
if(iscarbon(target))
M.visible_message("<span class='warning'>[src] mends [target]!</span>")
M.adjustBruteLoss(-5) //HEALS
M.adjustOxyLoss(-5)
M.adjustBruteLoss(-5)
M.adjustFireLoss(-5)
M.adjustToxLoss(-5, TRUE) //heals TOXINLOVERs
M.adjustCloneLoss(-5)
M.adjustStaminaLoss(-5)
return
@@ -2226,6 +2226,7 @@
color = "#f7685e"
metabolization_rate = REAGENTS_METABOLISM * 0.25
/datum/reagent/wittel
name = "Wittel"
description = "An extremely rare metallic-white substance only found on demon-class planets."
@@ -2287,6 +2288,7 @@
/datum/reagent/gravitum/on_mob_end_metabolize(mob/living/L)
L.RemoveElement(/datum/element/forced_gravity, 0)
//body bluids
/datum/reagent/consumable/semen
name = "Semen"
@@ -2463,3 +2465,56 @@ datum/reagent/eldritch
return
..()
/datum/reagent/red_ichor
name = "Red Ichor"
can_synth = FALSE
description = "A unknown red liquid, linked to healing of most moral wounds."
color = "#c10000"
metabolization_rate = REAGENTS_METABOLISM * 2.5
/datum/reagent/red_ichor/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(-50)
M.adjustOxyLoss(-50)
M.adjustBruteLoss(-50)
M.adjustFireLoss(-50)
M.adjustToxLoss(-50, TRUE) //heals TOXINLOVERs
M.adjustCloneLoss(-50)
M.adjustStaminaLoss(-50)
..()
/datum/reagent/green_ichor
name = "Green Ichor"
can_synth = FALSE
description = "A unknown green liquid, linked to healing of most internal wounds."
color = "#158c00"
metabolization_rate = REAGENTS_METABOLISM * 2.5
/datum/reagent/green_ichor/on_mob_life(mob/living/carbon/M)
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -100)
M.adjustOrganLoss(ORGAN_SLOT_HEART, -100)
M.adjustOrganLoss(ORGAN_SLOT_LIVER, -100)
M.adjustOrganLoss(ORGAN_SLOT_EARS, -100)
M.adjustOrganLoss(ORGAN_SLOT_STOMACH, -100)
M.adjustOrganLoss(ORGAN_SLOT_TONGUE, -100)
M.adjustOrganLoss(ORGAN_SLOT_EYES, -100)
..()
/datum/reagent/blue_ichor
name = "Blue Ichor"
can_synth = FALSE
description = "A unknown blue liquid, linked to healing the mind."
color = "#0914e0"
metabolization_rate = REAGENTS_METABOLISM * 2.5
/datum/reagent/blue_ichor/on_mob_life(mob/living/carbon/M)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -100)
M.cure_all_traumas(TRAUMA_RESILIENCE_MAGIC)
M.hallucination = 0
M.dizziness = 0
M.disgust = 0
M.drowsyness = 0
M.stuttering = 0
M.confused = 0
M.SetSleeping(0, 0)
..()
@@ -416,3 +416,20 @@
/obj/item/reagent_containers/glass/bottle/bromine
name = "bromine bottle"
list_reagents = list(/datum/reagent/bromine = 30)
//Ichors
/obj/item/reagent_containers/glass/bottle/ichor
possible_transfer_amounts = list(1)
volume = 1
/obj/item/reagent_containers/glass/bottle/ichor/red
name = "healing potion"
list_reagents = list(/datum/reagent/red_ichor = 1)
/obj/item/reagent_containers/glass/bottle/ichor/blue
name = "blue potion"
list_reagents = list(/datum/reagent/blue_ichor = 1)
/obj/item/reagent_containers/glass/bottle/ichor/green
name = "green potion"
list_reagents = list(/datum/reagent/green_ichor = 1)
@@ -0,0 +1,152 @@
#define MAX_RADIUS_REQUIRED 8000 //tritbomb
#define MIN_RADIUS_REQUIRED 20 //maxcap
/**
* # Explosive compressor machines
*
* The explosive compressor machine used in anomaly core production.
*
* Uses the standard toxins/tank explosion scaling to compress raw anomaly cores into completed ones. The required explosion radius increases as more cores of that type are created.
*/
/obj/machinery/research/explosive_compressor
name = "implosion compressor"
desc = "An advanced machine capable of implosion-compressing raw anomaly cores into finished artifacts."
icon = 'icons/obj/machines/research.dmi'
icon_state = "explosive_compressor"
density = TRUE
circuit = /obj/item/circuitboard/machine/explosive_compressor
/// The raw core inserted in the machine.
var/obj/item/raw_anomaly_core/inserted_core
/// The TTV inserted in the machine.
var/obj/item/transfer_valve/inserted_bomb
/// The last time we did say_requirements(), because someone will inevitably click spam this.
var/last_requirements_say = 0
/obj/machinery/research/explosive_compressor/examine(mob/user)
. = ..()
. += "<span class='notice'>Ctrl-Click to remove an inserted core.</span>"
. += "<span class='notice'>Click with an empty hand to gather information about the required radius of an inserted core. Insert a ready TTV to start the implosion process if a core is inserted.</span>"
/obj/machinery/research/explosive_compressor/attack_hand(mob/living/user)
. = ..()
if(.)
return
if(!inserted_core)
to_chat(user, "<span class='warning'>There is no core inserted.</span>")
return
if(last_requirements_say + 3 SECONDS > world.time)
return
last_requirements_say = world.time
say_requirements(inserted_core)
/obj/machinery/research/explosive_compressor/CtrlClick(mob/living/user)
. = ..()
if(!istype(user) || !user.Adjacent(src) || !(user.mobility_flags & MOBILITY_USE))
return
if(!inserted_core)
to_chat(user, "<span class='warning'>There is no core inserted.</span>")
return
inserted_core.forceMove(get_turf(user))
to_chat(user, "<span class='notice'>You remove [inserted_core] from [src].</span>")
user.put_in_hands(inserted_core)
inserted_core = null
/**
* Says (no, literally) the data of required explosive power for a certain anomaly type.
*/
/obj/machinery/research/explosive_compressor/proc/say_requirements(obj/item/raw_anomaly_core/C)
var/required = get_required_radius(C.anomaly_type)
if(isnull(required))
say("Unfortunately, due to diminishing supplies of condensed anomalous matter, [C] and any cores of its type are no longer of a sufficient quality level to be compressed into a working core.")
else
say("[C] requires a minimum of a theoretical radius of [required] to successfully implode into a charged anomaly core.")
/**
* Determines how much explosive power (last value, so light impact theoretical radius) is required to make a certain anomaly type.
*
* Returns null if the max amount has already been reached.
*
* Arguments:
* * anomaly_type - anomaly type define
*/
/obj/machinery/research/explosive_compressor/proc/get_required_radius(anomaly_type)
var/already_made = SSresearch.created_anomaly_types[anomaly_type]
var/hard_limit = SSresearch.anomaly_hard_limit_by_type[anomaly_type]
if(already_made >= hard_limit)
return //return null
// my crappy autoscale formula
// linear scaling.
var/radius_span = MAX_RADIUS_REQUIRED - MIN_RADIUS_REQUIRED
var/radius_increase_per_core = radius_span / hard_limit
var/radius = clamp(round(MIN_RADIUS_REQUIRED + radius_increase_per_core * already_made, 1), MIN_RADIUS_REQUIRED, MAX_RADIUS_REQUIRED)
return radius
/obj/machinery/research/explosive_compressor/attackby(obj/item/I, mob/living/user, params)
if(default_unfasten_wrench(user, I))
return
if(default_deconstruction_screwdriver(user, "explosive_compressor", "explosive_compressor", I))
return
if(default_deconstruction_crowbar(I))
return
. = ..()
if(istype(I, /obj/item/raw_anomaly_core))
if(inserted_core)
to_chat(user, "<span class='warning'>There is already a core in [src].</span>")
return
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand.</span>")
return
inserted_core = I
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
return
if(istype(I, /obj/item/transfer_valve))
// If they don't have a bomb core inserted, don't let them insert this. If they do, insert and do implosion.
if(!inserted_core)
to_chat(user, "<span class='warning'>There is no core inserted in [src]. What would be the point of detonating an implosion without a core?</span>")
return
var/obj/item/transfer_valve/valve = I
if(!valve.ready())
to_chat(user, "<span class='warning'>[valve] is incomplete.</span>")
return
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand.</span>")
return
inserted_bomb = I
to_chat(user, "<span class='notice'>You insert [I] and press the start button.</span>")
do_implosion()
/**
* The ""explosion"" proc.
*/
/obj/machinery/research/explosive_compressor/proc/do_implosion()
var/required_radius = get_required_radius(inserted_core.anomaly_type)
// By now, we should be sure that we have a core, a TTV, and that the TTV has both tanks in place.
var/datum/gas_mixture/mix1 = inserted_bomb.tank_one.air_contents
var/datum/gas_mixture/mix2 = inserted_bomb.tank_two.air_contents
// Snowflaked tank explosion
var/datum/gas_mixture/mix = new(70) // Standard tank volume, 70L
mix.merge(mix1)
mix.merge(mix2)
mix.react()
if(mix.return_pressure() < TANK_FRAGMENT_PRESSURE)
// They failed so miserably we're going to give them their bomb back.
inserted_bomb.forceMove(drop_location())
inserted_bomb = null
inserted_core.forceMove(drop_location())
inserted_core = null
say("Transfer valve resulted in negligible explosive power. Items ejected.")
return
mix.react() // build more pressure
var/pressure = mix.return_pressure()
var/range = (pressure - TANK_FRAGMENT_PRESSURE) / TANK_FRAGMENT_SCALE
QDEL_NULL(inserted_bomb) // bomb goes poof
if(range < required_radius)
inserted_bomb.forceMove(src)
say("Resultant detonation failed to produce enough implosive power to compress [inserted_core]. Core ejected.")
return
inserted_core.create_core(drop_location(), TRUE, TRUE)
inserted_core = null
say("Success. Resultant detonation has theoretical range of [range]. Required radius was [required_radius]. Core production complete.")
#undef MAX_RADIUS_REQUIRED
#undef MIN_RADIUS_REQUIRED
@@ -0,0 +1,73 @@
/**
* # Raw Anomaly Cores
*
* The current precursor to anomaly cores, these are manufactured into 'finished' anomaly cores for use in research, items, and more.
*
* The current amounts created is stored in SSresearch.created_anomaly_types[ANOMALY_CORE_TYPE_DEFINE] = amount
* The hard limits are in code/__DEFINES/anomalies.dm
*/
/obj/item/raw_anomaly_core
name = "raw anomaly core"
desc = "You shouldn't be seeing this. Someone screwed up."
icon = 'icons/obj/assemblies/new_assemblies.dmi'
icon_state = "broken_state"
/// Anomaly type
var/anomaly_type
/obj/item/raw_anomaly_core/bluespace
name = "raw bluespace core"
desc = "The raw core of a bluespace anomaly, glowing and full of potential."
anomaly_type = /obj/item/assembly/signaler/anomaly/bluespace
icon_state = "rawcore_bluespace"
/obj/item/raw_anomaly_core/vortex
name = "raw vortex core"
desc = "The raw core of a vortex anomaly. Feels heavy to the touch."
anomaly_type = /obj/item/assembly/signaler/anomaly/vortex
icon_state = "rawcore_vortex"
/obj/item/raw_anomaly_core/grav
name = "raw gravity core"
desc = "The raw core of a gravity anomaly. The air seems attracted to it."
anomaly_type = /obj/item/assembly/signaler/anomaly/grav
icon_state = "rawcore_grav"
/obj/item/raw_anomaly_core/pyro
desc = "The raw core of a pyro anomaly. It is warm to the touch."
name = "raw pyro core"
anomaly_type = /obj/item/assembly/signaler/anomaly/pyro
icon_state = "rawcore_pyro"
/obj/item/raw_anomaly_core/flux
name = "raw flux core"
desc = "The raw core of a flux anomaly, faintly crackling with energy."
anomaly_type = /obj/item/assembly/signaler/anomaly/flux
icon_state = "rawcore_flux"
/obj/item/raw_anomaly_core/random
name = "random raw core"
desc = "You should not see this!"
icon_state = "rawcore_bluespace"
/obj/item/raw_anomaly_core/random/Initialize(mapload)
. = ..()
var/path = pick(subtypesof(/obj/item/raw_anomaly_core))
new path(loc)
return INITIALIZE_HINT_QDEL
/**
* Created the resulting core after being "made" into it.
*
* Arguments:
* * newloc - Where the new core will be created
* * del_self - should we qdel(src)
* * count_towards_limit - should we increment the amount of created cores on SSresearch
*/
/obj/item/raw_anomaly_core/proc/create_core(newloc, del_self = FALSE, count_towards_limit = FALSE)
. = new anomaly_type(newloc)
if(count_towards_limit)
var/existing = SSresearch.created_anomaly_types[anomaly_type] || 0
SSresearch.created_anomaly_types[anomaly_type] = existing + 1
if(del_self)
qdel(src)
+41
View File
@@ -10,6 +10,12 @@
tool_behaviour = TOOL_RETRACTOR
toolspeed = 1
/obj/item/retractor/attack(mob/living/L, mob/user)
if(user.a_intent == INTENT_HELP)
to_chat(user, "<span class='warning'>You refrain from hitting [L] with [src], as you are in help intent.</span>")
return
return ..()
/obj/item/retractor/advanced
name = "mechanical pinches"
desc = "An agglomerate of rods and gears."
@@ -55,6 +61,12 @@
tool_behaviour = TOOL_HEMOSTAT
toolspeed = 1
/obj/item/hemostat/attack(mob/living/L, mob/user)
if(user.a_intent == INTENT_HELP)
to_chat(user, "<span class='warning'>You refrain from hitting [L] with [src], as you are in help intent.</span>")
return
return ..()
/obj/item/hemostat/augment
name = "hemostat"
desc = "Tiny servos power a pair of pincers to stop bleeding."
@@ -79,6 +91,12 @@
tool_behaviour = TOOL_CAUTERY
toolspeed = 1
/obj/item/cautery/attack(mob/living/L, mob/user)
if(user.a_intent == INTENT_HELP)
to_chat(user, "<span class='warning'>You refrain from hitting [L] with [src], as you are in help intent.</span>")
return
return ..()
/obj/item/cautery/augment
name = "cautery"
desc = "A heated element that cauterizes wounds."
@@ -107,6 +125,12 @@
tool_behaviour = TOOL_DRILL
toolspeed = 1
/obj/item/surgicaldrill/attack(mob/living/L, mob/user)
if(user.a_intent == INTENT_HELP)
to_chat(user, "<span class='warning'>You refrain from hitting [L] with [src], as you are in help intent.</span>")
return
return ..()
/obj/item/surgicaldrill/advanced
name = "searing tool"
desc = "It projects a high power laser used for medical application."
@@ -172,6 +196,12 @@
. = ..()
AddComponent(/datum/component/butchering, 80 * toolspeed, 100, 0)
/obj/item/scalpel/attack(mob/living/L, mob/user)
if(user.a_intent == INTENT_HELP)
to_chat(user, "<span class='warning'>You refrain from hitting [L] with [src], as you are in help intent.</span>")
return
return ..()
/obj/item/scalpel/advanced
name = "laser scalpel"
desc = "An advanced scalpel which uses laser technology to cut."
@@ -255,6 +285,11 @@
. = ..()
AddComponent(/datum/component/butchering, 40 * toolspeed, 100, 5, 'sound/weapons/circsawhit.ogg') //saws are very accurate and fast at butchering
/obj/item/circular_saw/attack(mob/living/L, mob/user)
if(user.a_intent == INTENT_HELP)
to_chat(user, "<span class='warning'>You refrain from hitting [L] with [src], as you are in help intent.</span>")
return
return ..()
/obj/item/circular_saw/augment
name = "circular saw"
@@ -392,3 +427,9 @@
attack_verb = list("corrected", "properly set")
tool_behaviour = TOOL_BONESET
toolspeed = 1
/obj/item/bonesetter/attack(mob/living/L, mob/user)
if(user.a_intent == INTENT_HELP)
to_chat(user, "<span class='warning'>You refrain from hitting [L] with [src], as you are in help intent.</span>")
return
return ..()