From 28e569b35679dd0849291f08715acbf314567684 Mon Sep 17 00:00:00 2001 From: Steelpoint Date: Fri, 3 Jun 2016 15:32:46 +0800 Subject: [PATCH 01/50] InitalCommit --- code/modules/clothing/head/helmet.dm | 2 +- code/modules/clothing/head/jobs.dm | 6 +++--- code/modules/clothing/suits/armor.dm | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 6aa577594d7..21301636ada 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -4,7 +4,7 @@ icon_state = "helmet" flags = HEADBANGPROTECT item_state = "helmet" - armor = list(melee = 30, bullet = 25, laser = 25,energy = 10, bomb = 25, bio = 0, rad = 0) + armor = list(melee = 40, bullet = 30, laser = 30,energy = 10, bomb = 25, bio = 0, rad = 0) flags_inv = HIDEEARS cold_protection = HEAD min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 79ac02bad92..12fb3241c2a 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -107,7 +107,7 @@ name = "warden's police hat" desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts." icon_state = "policehelm" - armor = list(melee = 30, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) + armor = list(melee = 40, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0) strip_delay = 60 dog_fashion = /datum/dog_fashion/head/warden @@ -116,7 +116,7 @@ name = "security beret" desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficent protection." icon_state = "beret_badge" - armor = list(melee = 30, bullet = 25, laser = 25,energy = 10, bomb = 25, bio = 0, rad = 0) + armor = list(melee = 40, bullet = 30, laser = 30,energy = 10, bomb = 25, bio = 0, rad = 0) strip_delay = 60 dog_fashion = null @@ -129,7 +129,7 @@ name = "warden's beret" desc = "A special beret with the Warden's insignia emblazoned on it. For wardens with class." icon_state = "wardenberet" - armor = list(melee = 30, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) + armor = list(melee = 40, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0) strip_delay = 60 /obj/item/clothing/head/beret/sec/navyofficer diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 228ba63a9c7..139c11b9e1a 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -15,7 +15,7 @@ icon_state = "armoralt" item_state = "armoralt" blood_overlay_type = "armor" - armor = list(melee = 25, bullet = 15, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) + armor = list(melee = 30, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0) dog_fashion = /datum/dog_fashion/back /obj/item/clothing/suit/armor/vest/alt From 0bdc996ba05ab1dd0411fc849f63f8ee34abf7bd Mon Sep 17 00:00:00 2001 From: Incoming5643 Date: Fri, 3 Jun 2016 16:58:41 -0400 Subject: [PATCH 02/50] The ghost of poly won't interfere directly in the lives of mortals --- code/modules/mob/living/simple_animal/parrot.dm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 3568d43dc52..c3be1a4b443 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -943,7 +943,12 @@ status_flags = GODMODE incorporeal_move = 1 butcher_results = list(/obj/item/weapon/ectoplasm = 1) - + /mob/living/simple_animal/parrot/Poly/ghost/New() memory_saved = 1 //At this point nothing is saved ..() + +/mob/living/simple_animal/parrot/Poly/ghost/handle_automated_movement() + isliving(parrot_interest) + parrot_interest = null + ..() From 10313507beb187650f3295d5ce4381571f474f45 Mon Sep 17 00:00:00 2001 From: Incoming5643 Date: Fri, 3 Jun 2016 17:08:09 -0400 Subject: [PATCH 03/50] man I'm really slipping --- code/modules/mob/living/simple_animal/parrot.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index c3be1a4b443..4cde8ce5c32 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -943,12 +943,12 @@ status_flags = GODMODE incorporeal_move = 1 butcher_results = list(/obj/item/weapon/ectoplasm = 1) - + /mob/living/simple_animal/parrot/Poly/ghost/New() memory_saved = 1 //At this point nothing is saved ..() /mob/living/simple_animal/parrot/Poly/ghost/handle_automated_movement() - isliving(parrot_interest) + if(isliving(parrot_interest)) parrot_interest = null ..() From 80065468d425251fedbac863839caa0fe19c0322 Mon Sep 17 00:00:00 2001 From: GunHog Date: Sun, 5 Jun 2016 11:57:39 -0500 Subject: [PATCH 04/50] Hyper KA for mining borgies <3 - Mining Cyborgs may now be upgraded with Hyper-Kenetic Accelerators - Same cost and reqs as human version. --- .../objects/items/robot/robot_upgrades.dm | 20 +++++++++++++++++++ .../projectiles/guns/energy/special.dm | 4 ++++ .../designs/mechfabricator_designs.dm | 10 ++++++++++ 3 files changed, 34 insertions(+) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index c3c90724557..1ca25b3b218 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -194,6 +194,26 @@ return 1 +/obj/item/borg/upgrade/hyperka + name = "mining cyborg hyper-kinetic accelerator" + desc = "A satchel of holding replacement for mining cyborg's ore satchel module." + icon_state = "cyborg_upgrade3" + require_module = 1 + module_type = /obj/item/weapon/robot_module/miner + origin_tech = "materials=6;powerstorage=4;engineering=4;magnets=4;combat=4" + +/obj/item/borg/upgrade/hyperka/action(mob/living/silicon/robot/R) + if(..()) + return + + for(var/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg/H in R.module.modules) + qdel(H) + + R.module.modules += new /obj/item/weapon/gun/energy/kinetic_accelerator/hyper/cyborg(R.module) + R.module.rebuild() + + return 1 + /obj/item/borg/upgrade/syndicate name = "illegal equipment module" desc = "Unlocks the hidden, deadlier functions of a cyborg" diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index e607230872a..ba65e278713 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -119,6 +119,10 @@ holds_charge = TRUE unique_frequency = TRUE +/obj/item/weapon/gun/energy/kinetic_accelerator/hyper/cyborg + holds_charge = TRUE + unique_frequency = TRUE + /obj/item/weapon/gun/energy/kinetic_accelerator/New() . = ..() if(!holds_charge) diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 0518e393ecd..26b9fdc5b16 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -648,6 +648,16 @@ construction_time = 120 category = list("Cyborg Upgrade Modules") +/datum/design/borg_upgrade_hyperka + name = "Cyborg (Hyper-Kinetic Accelerator)" + id = "borg_upgrade_hyperka" + req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 5, "magnets" = 5, "combat" = 4) + build_type = MECHFAB //Reqs same as human Hyper KA + materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) + build_path = /obj/item/borg/upgrade/hyperka + construction_time = 120 + category = list("Cyborg Upgrade Modules") + /datum/design/borg_syndicate_module name = "Cyborg Upgrade (Illegal Modules)" id = "borg_syndicate_module" From 6b647e63ec10fafe7eb5b6d2ef1fa19cf9a48148 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sun, 5 Jun 2016 14:19:19 -0500 Subject: [PATCH 05/50] Raises Nuke Min Requirement --- code/game/gamemodes/nuclear/nuclear.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 33ac8c417b5..90129ab1ef2 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -5,7 +5,7 @@ /datum/game_mode/nuclear name = "nuclear emergency" config_tag = "nuclear" - required_players = 30 // 30 players - 5 players to be the nuke ops = 25 players remaining + required_players = 38 required_enemies = 5 recommended_enemies = 5 antag_flag = ROLE_OPERATIVE From 70c9cff6742a448ec4df0d553b9d50b6f5d9e3ef Mon Sep 17 00:00:00 2001 From: PKPenguin321 Date: Sun, 5 Jun 2016 21:49:59 -0700 Subject: [PATCH 06/50] fixes hulks attacking with dual eswords --- code/game/objects/items/weapons/twohanded.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index fbae342c1d9..4d764ef21c5 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -222,6 +222,11 @@ /obj/item/weapon/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user) ..() + if(user.has_dna()) + if(user.dna.check_mutation(HULK)) + user << "You grip the blade too hard and accidentally close it!" + unwield() + return if(user.disabilities & CLUMSY && (wielded) && prob(40)) impale(user) return From 9721bdb4a9293f7cc891f2975ab20550cefab3fd Mon Sep 17 00:00:00 2001 From: JJRcop Date: Mon, 6 Jun 2016 01:23:36 -0400 Subject: [PATCH 07/50] Admin granted to loopback connections or opening .dmb with DS --- code/modules/client/client_procs.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index e98855092f4..1698bef1a0e 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -113,6 +113,12 @@ var/next_external_rsc = 0 directory[ckey] = src //Admin Authorisation + var/localhost_addresses = list("127.0.0.1", "::1") + if(!address || (address in localhost_addresses)) + var/datum/admin_rank/localhost_rank = new("!localhost!", 65535) + if(localhost_rank) + var/datum/admins/localhost_holder = new(localhost_rank, ckey) + localhost_holder.associate(src) if(protected_config.autoadmin) if(!admin_datums[ckey]) var/datum/admin_rank/autorank @@ -127,7 +133,7 @@ var/next_external_rsc = 0 admin_datums[ckey] = D holder = admin_datums[ckey] if(holder) - admins += src + admins |= src holder.owner = src //preferences datum - also holds some persistant data for the client (because we may as well keep these datums to a minimum) From 86c6a60021496e16ed7838c35c3ee1414eb35b18 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Mon, 6 Jun 2016 01:58:22 -0700 Subject: [PATCH 08/50] Fixes ghost images not having byond member iconstates (these icon states will still not show if the user requests they don't see such things, but now should show when they do.) --- code/modules/mob/dead/observer/observer.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index d1ea9204c6e..4b44e8ba77c 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -163,6 +163,7 @@ var/list/image/ghost_images_simple = list() //this is a list of all ghost images if(new_form) icon_state = new_form + ghostimage.icon_state = new_form if(icon_state in ghost_forms_with_directions_list) ghostimage_default.icon_state = new_form + "_nodir" //if this icon has dirs, the default ghostimage must use its nodir version or clients with the preference set to default sprites only will see the dirs else From 745b4b87825a1abd5a71d9b3535007fc6de37522 Mon Sep 17 00:00:00 2001 From: Lzimann Date: Mon, 6 Jun 2016 10:52:34 -0300 Subject: [PATCH 09/50] Number of nuke ops now scale with population --- code/game/gamemodes/nuclear/nuclear.dm | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 33ac8c417b5..11b073e8ff2 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -5,8 +5,8 @@ /datum/game_mode/nuclear name = "nuclear emergency" config_tag = "nuclear" - required_players = 30 // 30 players - 5 players to be the nuke ops = 25 players remaining - required_enemies = 5 + required_players = 30 // 30 players - 3 players to be the nuke ops = 27 players remaining + required_enemies = 2 recommended_enemies = 5 antag_flag = ROLE_OPERATIVE enemy_minimum_age = 14 @@ -23,15 +23,11 @@ world << "A nuclear explosive was being transported by Nanotrasen to a military base. The transport ship mysteriously lost contact with Space Traffic Control (STC). About that time a strange disk was discovered around [station_name()]. It was identified by Nanotrasen as a nuclear auth. disk and now Syndicate Operatives have arrived to retake the disk and detonate SS13! Also, most likely Syndicate star ships are in the vicinity so take care not to lose the disk!\nSyndicate: Reclaim the disk and detonate the nuclear bomb anywhere on SS13.\nPersonnel: Hold the disk and escape with the disk on the shuttle!" /datum/game_mode/nuclear/pre_setup() - var/agent_number = 0 - if(antag_candidates.len > agents_possible) - agent_number = agents_possible - else - agent_number = antag_candidates.len - var/n_players = num_players() - if(agent_number > n_players) - agent_number = n_players/2 + var/n_agents = min(round(n_players / 10, 1), agents_possible) + + if(antag_candidates.len < n_agents) //In the case of having less candidates than the selected number of agents + n_agents = agent_candidate.len while(agent_number > 0) var/datum/mind/new_syndicate = pick(antag_candidates) @@ -85,7 +81,7 @@ greet_syndicate(synd_mind) equip_syndicate(synd_mind.current) - if (nuke_code) + if(nuke_code) synd_mind.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) synd_mind.current << "The nuclear authorization code is: [nuke_code]" @@ -128,7 +124,7 @@ if(A) A.command = TRUE - if (nuke_code) + if(nuke_code) var/obj/item/weapon/paper/P = new P.info = "The nuclear authorization code is: [nuke_code]" P.name = "nuclear bomb code" @@ -149,7 +145,7 @@ /datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1) - if (you_are) + if(you_are) syndicate.current << "You are a [syndicate_name()] agent!" var/obj_count = 1 for(var/datum/objective/objective in syndicate.objectives) From c73e410250c8d4cb0f62315bf07ea0342f55a97a Mon Sep 17 00:00:00 2001 From: Lzimann Date: Mon, 6 Jun 2016 11:12:08 -0300 Subject: [PATCH 10/50] Always remember to re-read everything --- code/game/gamemodes/nuclear/nuclear.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 11b073e8ff2..d45219edea9 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -27,13 +27,13 @@ var/n_agents = min(round(n_players / 10, 1), agents_possible) if(antag_candidates.len < n_agents) //In the case of having less candidates than the selected number of agents - n_agents = agent_candidate.len + n_agents = agent_candidates.len - while(agent_number > 0) + while(n_agents > 0) var/datum/mind/new_syndicate = pick(antag_candidates) syndicates += new_syndicate antag_candidates -= new_syndicate //So it doesn't pick the same guy each time. - agent_number-- + n_agents-- for(var/datum/mind/synd_mind in syndicates) synd_mind.assigned_role = "Syndicate" From 2e945f67b5228330b4566cb43b8f361e967077cb Mon Sep 17 00:00:00 2001 From: Lzimann Date: Mon, 6 Jun 2016 11:30:08 -0300 Subject: [PATCH 11/50] Don't code while you are tired --- code/game/gamemodes/nuclear/nuclear.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index d45219edea9..c8c8eea8984 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -27,7 +27,7 @@ var/n_agents = min(round(n_players / 10, 1), agents_possible) if(antag_candidates.len < n_agents) //In the case of having less candidates than the selected number of agents - n_agents = agent_candidates.len + n_agents = antag_candidates.len while(n_agents > 0) var/datum/mind/new_syndicate = pick(antag_candidates) From ffcde7ffe5fa6c60f72b149b580d51542f38e90c Mon Sep 17 00:00:00 2001 From: MMMiracles Date: Mon, 6 Jun 2016 14:56:02 -0400 Subject: [PATCH 12/50] what is testing code? --- .../LavaRuins/lavaland_surface_cultaltar.dmm | 10 +++++----- code/modules/ruins/lavaland_ruin_code.dm | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm index 25f4664aa66..7d817f7cbf0 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm @@ -33,7 +33,7 @@ }, /obj/effect/step_trigger/sound_effect{ name = "turn around"; - sound = "turn_around"; + sound = 'sound/hallucinations/turn_around1.ogg'; triggerer_only = 1 }, /turf/open/floor/plasteel/cult{ @@ -98,7 +98,7 @@ }, /obj/effect/step_trigger/sound_effect{ name = "turn around"; - sound = "turn_around"; + sound = 'sound/hallucinations/turn_around1.ogg'; triggerer_only = 1 }, /turf/open/floor/plasteel/cult{ @@ -117,7 +117,7 @@ /obj/effect/step_trigger/sound_effect{ happens_once = 1; name = "a grave mistake"; - sound = "i_see_you"; + sound = 'sound/hallucinations/i_see_you1.ogg'; triggerer_only = 1 }, /obj/effect/step_trigger/message{ @@ -138,7 +138,7 @@ }, /obj/effect/step_trigger/sound_effect{ name = "turn around"; - sound = "turn_around"; + sound = 'sound/hallucinations/turn_around1.ogg'; triggerer_only = 1 }, /turf/open/floor/plasteel/cult{ @@ -165,7 +165,7 @@ }, /obj/effect/step_trigger/sound_effect{ name = "turn around"; - sound = "turn_around"; + sound = 'sound/hallucinations/turn_around1.ogg'; triggerer_only = 1 }, /turf/open/floor/plasteel/cult{ diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index 4558125cdfe..755fbde1da1 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -412,27 +412,27 @@ mob_species = /datum/species/human flavour_text = {"Doomed to walk this eternal hellscape due to means you barely remember at this point, every day is a struggle for survival as you barely scrape by in your makeshift housing."} -/obj/effect/mob_spawn/human/hermit/special(mob/living/new_spawn) +/obj/effect/mob_spawn/human/hermit/New() var/arrpee = rand(1,4) switch(arrpee) if(1) - new_spawn << "You were the sole survivor of a raid-party's onslaught on a small orbital tradestation. You were forced to early-eject your pod to escape, the horrifed faces of the remaining crew when the raiders blew apart the room's airlock forever ingrained in your mind." + flavour_text = {"You were the sole survivor of a raid-party's onslaught on a small orbital tradestation. You were forced to early-eject your pod to escape, the horrifed faces of the remaining crew when the raiders blew apart the room's airlock forever ingrained in your mind."} uniform = /obj/item/clothing/under/assistantformal shoes = /obj/item/clothing/shoes/sneakers/black back = /obj/item/weapon/storage/backpack if(2) - new_spawn << "A castaway from a far-off civilization, banished for crimes of heresy against the church. You awoke from hypersleep your pod crashlanding into this hellscape, only the essentials left to make a new life for yourself." + flavour_text = {"A castaway from a far-off civilization, banished for crimes of heresy against the church. You awoke from hypersleep your pod crashlanding into this hellscape, only the essentials left to make a new life for yourself."} uniform = /obj/item/clothing/under/rank/prisoner shoes = /obj/item/clothing/shoes/sneakers/orange back = /obj/item/weapon/storage/backpack if(3) - new_spawn << "A runaway from the tyranny of Nanotrasen and everything all these damnned corporations stand for. From a metaphorical hell to a literal one, you do your best to put your station-life behind you to try and survive in this harsh land." + flavour_text = {"A runaway from the tyranny of Nanotrasen and everything all these damnned corporations stand for. From a metaphorical hell to a literal one, you do your best to put your station-life behind you to try and survive in this harsh land."} uniform = /obj/item/clothing/under/rank/medical suit = /obj/item/clothing/suit/toggle/labcoat back = /obj/item/weapon/storage/backpack/medic shoes = /obj/item/clothing/shoes/sneakers/black if(4) - new_spawn << "You weren't exactly the sharpest tool in the shed, hitting that big red button on the escape pod wondering what it'd do. Whether this 'special' attribute of yours is a defect of cloning or just genuine stupidity, the fact you've survived this long in a literal hellhole is enough to make Darwin roll in his grave." + flavour_text = {"You weren't exactly the sharpest tool in the shed, hitting that big red button on the escape pod wondering what it'd do. Whether this 'special' attribute of yours is a defect of cloning or just genuine stupidity, the fact you've survived this long in a literal hellhole is enough to make Darwin roll in his grave."} uniform = /obj/item/clothing/under/color/grey/glorf shoes = /obj/item/clothing/shoes/sneakers/black back = /obj/item/weapon/storage/backpack \ No newline at end of file From 46df7c7b311a2e8766cd0b2bf116b106f7e79201 Mon Sep 17 00:00:00 2001 From: xxalpha Date: Mon, 6 Jun 2016 22:59:40 +0100 Subject: [PATCH 13/50] SmoOoOoOoOoOoOoOoooOoooOoooOoths the lava. --- code/game/turfs/simulated/floor/plating.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 2d23beac576..70642200b56 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -289,8 +289,9 @@ baseturf = /turf/open/floor/plating/lava/smooth icon = 'icons/turf/floors/lava.dmi' icon_state = "unsmooth" - canSmoothWith = list(/turf/closed/wall, /turf/closed/mineral, /turf/open/floor/plating/lava/smooth, /turf/open/floor/plating/lava/smooth/lava_land_surface - ) + smooth = SMOOTH_MORE | SMOOTH_BORDER + canSmoothWith = list(/turf/closed/wall, /turf/closed/mineral, /turf/open/floor/plating/lava/smooth, /turf/open/floor/plating/lava/smooth/lava_land_surface) + /turf/open/floor/plating/lava/smooth/airless initial_gas_mix = "TEMP=2.7" From cd4855688d2d1c79172a4ef9754649bb699c00b7 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Mon, 6 Jun 2016 18:49:14 -0500 Subject: [PATCH 14/50] Sad Trombone Implant --- .../items/weapons/implants/implant_clown.dm | 30 +++++++++++++++++++ code/modules/jobs/job_types/civilian.dm | 4 +++ tgstation.dme | 1 + 3 files changed, 35 insertions(+) create mode 100644 code/game/objects/items/weapons/implants/implant_clown.dm diff --git a/code/game/objects/items/weapons/implants/implant_clown.dm b/code/game/objects/items/weapons/implants/implant_clown.dm new file mode 100644 index 00000000000..4cb6be7c1b9 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_clown.dm @@ -0,0 +1,30 @@ +/obj/item/weapon/implant/sad_trombone + name = "sad trombone implant" + activated = 0 + +/obj/item/weapon/implant/sad_trombone/get_data() + var/dat = {"Implant Specifications:
+ Name: Honk Co. Sad Trombone Implant
+ Life: Activates upon death.
+ "} + return dat + +/obj/item/weapon/implant/sad_trombone/trigger(emote, mob/source) + if(emote == "deathgasp") + playsound(loc, 'sound/misc/sadtrombone.ogg', 50, 0) + +/obj/item/weapon/implanter/sad_trombone + name = "implanter (sad_trombone)" + +/obj/item/weapon/implanter/sad_trombone/New() + imp = new /obj/item/weapon/implant/explosive(src) + ..() + + +/obj/item/weapon/implantcase/sad_trombone + name = "implant case - 'Sad Trombone'" + desc = "A glass case containing a sad trombone implant." + +/obj/item/weapon/implantcase/sad_trombone/New() + imp = new /obj/item/weapon/implant/sad_trombone(src) + ..() diff --git a/code/modules/jobs/job_types/civilian.dm b/code/modules/jobs/job_types/civilian.dm index 33d0b81700d..51de2d1b845 100644 --- a/code/modules/jobs/job_types/civilian.dm +++ b/code/modules/jobs/job_types/civilian.dm @@ -51,6 +51,10 @@ Clown if(visualsOnly) return + var/obj/item/weapon/implant/sad_trombone/S = new/obj/item/weapon/implant/sad_trombone(H) + S.imp_in = H + S.implanted = 1 + H.dna.add_mutation(CLOWNMUT) H.rename_self("clown") diff --git a/tgstation.dme b/tgstation.dme index 2f3858e6137..ba874267ed8 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -678,6 +678,7 @@ #include "code\game\objects\items\weapons\grenades\syndieminibomb.dm" #include "code\game\objects\items\weapons\implants\implant.dm" #include "code\game\objects\items\weapons\implants\implant_chem.dm" +#include "code\game\objects\items\weapons\implants\implant_clown.dm" #include "code\game\objects\items\weapons\implants\implant_explosive.dm" #include "code\game\objects\items\weapons\implants\implant_freedom.dm" #include "code\game\objects\items\weapons\implants\implant_krav_maga.dm" From 5d76e239ef4db29bd7dfe6fac5f7b2546d37b415 Mon Sep 17 00:00:00 2001 From: PKPenguin321 Date: Mon, 6 Jun 2016 17:02:08 -0700 Subject: [PATCH 15/50] moves the parent call --- code/game/objects/items/weapons/twohanded.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 4d764ef21c5..6d5861759c6 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -221,12 +221,12 @@ return /obj/item/weapon/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user) - ..() if(user.has_dna()) if(user.dna.check_mutation(HULK)) user << "You grip the blade too hard and accidentally close it!" unwield() return + ..() if(user.disabilities & CLUMSY && (wielded) && prob(40)) impale(user) return From 3526562fa207a5db1370a70b80798bab4433c865 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Mon, 6 Jun 2016 19:08:48 -0500 Subject: [PATCH 16/50] The joke was on me all along --- code/game/objects/items/weapons/implants/implant_clown.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/implants/implant_clown.dm b/code/game/objects/items/weapons/implants/implant_clown.dm index 4cb6be7c1b9..01f1e9715b0 100644 --- a/code/game/objects/items/weapons/implants/implant_clown.dm +++ b/code/game/objects/items/weapons/implants/implant_clown.dm @@ -17,7 +17,7 @@ name = "implanter (sad_trombone)" /obj/item/weapon/implanter/sad_trombone/New() - imp = new /obj/item/weapon/implant/explosive(src) + imp = new /obj/item/weapon/implant/sad_trombone(src) ..() From 8cbb10cab2e7a5c713a4851a5694ce3d6e162c4a Mon Sep 17 00:00:00 2001 From: Jack Edge Date: Mon, 6 Jun 2016 00:14:31 +0100 Subject: [PATCH 17/50] Moved dragon loot into necropolis_chests.dm In addition: - Added an admin notification when dragon blood causes the dragon transformation. - Fixes #18275, lava staff can no longer turn transit tiles to lava. --- code/__DEFINES/is_helpers.dm | 1 + code/game/objects/items/weapons/explosives.dm | 2 +- .../mining/lavaland/necropolis_chests.dm | 187 +++++++++++++++++- .../simple_animal/hostile/megafauna/dragon.dm | 170 ---------------- 4 files changed, 186 insertions(+), 174 deletions(-) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 459e8912bec..aacbfc3a556 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -16,6 +16,7 @@ #define ispodperson(A) (is_species(A, /datum/species/podperson)) #define isflyperson(A) (is_species(A, /datum/species/fly)) #define iszombie(A) (is_species(A, /datum/species/zombie)) +#define ishumanbasic(A) (is_species(A, /datum/species/human)) #define ismonkey(A) (istype(A, /mob/living/carbon/monkey)) diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index b9863412fd5..caf1235aef2 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -1,4 +1,4 @@ -//In this file: C4 and Syndicate Bombs +//In this file: C4 /obj/item/weapon/c4 name = "C-4" diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index fdc514247a3..a205133b73b 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -418,7 +418,7 @@ icon = 'icons/obj/lavaland/artefacts.dmi' icon_state = "potionflask" w_class = 2 - var/used = 0 + var/used = FALSE /obj/item/weapon/wingpotion/attack_self(mob/living/M) if(used) @@ -426,10 +426,11 @@ else if(iscarbon(M)) var/mob/living/carbon/C = M + CHECK_DNA_AND_SPECIES(C) if(C.wear_mask) C << "It's pretty hard to drink something with a mask on!" else - if(C.dna.species.id != "human") //implying xenoshumans are holy + if(ishumanbasic(C)) //implying xenoshumans are holy C << "You down the elixir, noting nothing else but a terrible aftertaste." else C << "You down the elixir, a terrible pain travels down your back as wings burst out!" @@ -438,4 +439,184 @@ C.adjustBruteLoss(20) C.emote("scream") playsound(loc, 'sound/items/drink.ogg', 50, 1, -1) - src.used = 1 \ No newline at end of file + src.used = TRUE + + +/obj/structure/closet/crate/necropolis/dragon + name = "dragon chest" + +/obj/structure/closet/crate/necropolis/dragon/New() + ..() + var/loot = rand(1,2) + switch(loot) + if(1) + new /obj/item/weapon/melee/ghost_sword(src) + if(2) + new /obj/item/weapon/lava_staff(src) + +/obj/item/weapon/melee/ghost_sword + name = "spectral blade" + desc = "A rusted and dulled blade. It doesn't look like it'd do much damage. It glows weakly." + icon_state = "spectral" + item_state = "spectral" + flags = CONDUCT + sharpness = IS_SHARP + w_class = 4 + force = 1 + throwforce = 1 + hitsound = 'sound/effects/ghost2.ogg' + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended") + var/summon_cooldown = 0 + var/list/mob/dead/observer/spirits + +/obj/item/weapon/melee/ghost_sword/New() + ..() + spirits = list() + SSobj.processing += src + poi_list |= src + +/obj/item/weapon/melee/ghost_sword/Destroy() + for(var/mob/dead/observer/G in spirits) + G.invisibility = initial(G.invisibility) + spirits.Cut() + SSobj.processing -= src + poi_list -= src + . = ..() + +/obj/item/weapon/melee/ghost_sword/attack_self(mob/user) + if(summon_cooldown > world.time) + user << "You just recently called out for aid. You don't want to annoy the spirits." + return + user << "You call out for aid, attempting to summon spirits to your side." + + notify_ghosts("[user] is raising their [src], calling for your help!", + enter_link="(Click to help)", + source = user, action=NOTIFY_ORBIT) + + summon_cooldown = world.time + 600 + +/obj/item/weapon/melee/ghost_sword/Topic(href, href_list) + if(href_list["orbit"]) + var/mob/dead/observer/ghost = usr + if(istype(ghost)) + ghost.ManualFollow(src) + +/obj/item/weapon/melee/ghost_sword/process() + ghost_check() + +/obj/item/weapon/melee/ghost_sword/proc/ghost_check() + var/ghost_counter = 0 + var/turf/T = get_turf(src) + var/list/contents = T.GetAllContents() + var/mob/dead/observer/current_spirits = list() + for(var/mob/dead/observer/G in dead_mob_list) + if(G.orbiting in contents) + ghost_counter++ + G.invisibility = 0 + current_spirits |= G + + for(var/mob/dead/observer/G in spirits - current_spirits) + G.invisibility = initial(G.invisibility) + + spirits = current_spirits + + return ghost_counter + +/obj/item/weapon/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user) + force = 0 + var/ghost_counter = ghost_check() + + force = Clamp((ghost_counter * 4), 0, 75) + user.visible_message("[user] strikes with the force of [ghost_counter] vengeful spirits!") + ..() + +/obj/item/weapon/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) + var/ghost_counter = ghost_check() + final_block_chance += Clamp((ghost_counter * 5), 0, 75) + owner.visible_message("[owner] is protected by a ring of [ghost_counter] ghosts!") + return ..() + +//Blood + +/obj/item/weapon/dragons_blood + name = "bottle of dragons blood" + desc = "You're not actually going to drink this, are you?" + icon = 'icons/obj/wizard.dmi' + icon_state = "vial" + +/obj/item/weapon/dragons_blood/attack_self(mob/living/carbon/human/user) + if(!istype(user)) + return + + var/mob/living/carbon/human/H = user + var/random = rand(1,3) + + switch(random) + if(1) + user << "Other than tasting terrible, nothing really happens." + if(2) + user << "Your flesh begins to melt! Miraculously, you seem fine otherwise." + H.set_species(/datum/species/skeleton) + if(3) + user << "You don't feel so good..." + message_admins("[key_name_admin(user)](FLW) has started transforming into a dragon via dragon's blood.") + H.ForceContractDisease(new /datum/disease/transformation/dragon(0)) + + playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1) + qdel(src) + +/datum/disease/transformation/dragon + name = "dragon transformation" + cure_text = "nothing" + cures = list("adminordrazine") + agent = "dragon's blood" + desc = "What do dragons have to do with Space Station 13?" + stage_prob = 20 + severity = BIOHAZARD + visibility_flags = 0 + stage1 = list("Your bones ache.") + stage2 = list("Your skin feels scaley.") + stage3 = list("You have an overwhelming urge to terrorize some peasants.", "Your teeth feel sharper.") + stage4 = list("Your blood burns.") + stage5 = list("You're a fucking dragon.") + new_form = /mob/living/simple_animal/hostile/megafauna/dragon/lesser + + +//Lava Staff + +/obj/item/weapon/lava_staff + name = "staff of lava" + desc = "The ability to fill the emergency shuttle with lava. What more could you want out of life?" + icon_state = "staffofstorms" + item_state = "staffofstorms" + icon = 'icons/obj/guns/magic.dmi' + slot_flags = SLOT_BACK + item_state = "staffofstorms" + w_class = 4 + force = 25 + damtype = BURN + burn_state = LAVA_PROOF + hitsound = 'sound/weapons/sear.ogg' + var/turf_type = /turf/open/floor/plating/lava/smooth + var/cooldown = 200 + var/timer = 0 + var/banned_turfs + +/obj/item/weapon/lava_staff/New() + . = ..() + banned_turfs = typecacheof(list(/turf/open/space/transit, /turf/closed)) + +/obj/item/weapon/lava_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + ..() + if(timer > world.time) + return + + if(is_type_in_typecache(target, banned_turfs)) + return + + if(target in view(user.client.view, get_turf(user))) + var/turf/open/O = target + user.visible_message("[user] turns \the [O] into lava!") + O.ChangeTurf(turf_type) + playsound(get_turf(src),'sound/magic/Fireball.ogg', 200, 1) + timer = world.time + cooldown diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm index a45c69de727..6033303c1bd 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm @@ -216,98 +216,12 @@ return swoop_attack(1, A) - /obj/item/device/gps/internal/dragon icon_state = null gpstag = "Fiery Signal" desc = "Here there be dragons." invisibility = 100 - -//The part you've all been waiting for: Loot - -/obj/item/weapon/melee/ghost_sword - name = "spectral blade" - desc = "A rusted and dulled blade. It doesn't look like it'd do much damage. It glows weakly." - icon_state = "spectral" - item_state = "spectral" - flags = CONDUCT - sharpness = IS_SHARP - w_class = 4 - force = 1 - throwforce = 1 - hitsound = 'sound/effects/ghost2.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended") - var/summon_cooldown = 0 - var/list/mob/dead/observer/spirits - -/obj/item/weapon/melee/ghost_sword/New() - ..() - spirits = list() - SSobj.processing += src - poi_list |= src - -/obj/item/weapon/melee/ghost_sword/Destroy() - for(var/mob/dead/observer/G in spirits) - G.invisibility = initial(G.invisibility) - spirits.Cut() - SSobj.processing -= src - poi_list -= src - . = ..() - -/obj/item/weapon/melee/ghost_sword/attack_self(mob/user) - if(summon_cooldown > world.time) - user << "You just recently called out for aid. You don't want to annoy the spirits." - return - user << "You call out for aid, attempting to summon spirits to your side." - - notify_ghosts("[user] is raising their [src], calling for your help!", - enter_link="(Click to help)", - source = user, action=NOTIFY_ORBIT) - - summon_cooldown = world.time + 600 - -/obj/item/weapon/melee/ghost_sword/Topic(href, href_list) - if(href_list["orbit"]) - var/mob/dead/observer/ghost = usr - if(istype(ghost)) - ghost.ManualFollow(src) - -/obj/item/weapon/melee/ghost_sword/process() - ghost_check() - -/obj/item/weapon/melee/ghost_sword/proc/ghost_check() - var/ghost_counter = 0 - var/turf/T = get_turf(src) - var/list/contents = T.GetAllContents() - var/mob/dead/observer/current_spirits = list() - for(var/mob/dead/observer/G in dead_mob_list) - if(G.orbiting in contents) - ghost_counter++ - G.invisibility = 0 - current_spirits |= G - - for(var/mob/dead/observer/G in spirits - current_spirits) - G.invisibility = initial(G.invisibility) - - spirits = current_spirits - - return ghost_counter - -/obj/item/weapon/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user) - force = 0 - var/ghost_counter = ghost_check() - - force = Clamp((ghost_counter * 4), 0, 75) - user.visible_message("[user] strikes with the force of [ghost_counter] vengeful spirits!") - ..() - -/obj/item/weapon/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) - var/ghost_counter = ghost_check() - final_block_chance += Clamp((ghost_counter * 5), 0, 75) - owner.visible_message("[owner] is protected by a ring of [ghost_counter] ghosts!") - return ..() - /mob/living/simple_animal/hostile/megafauna/dragon/lesser name = "lesser ash drake" maxHealth = 750 @@ -317,87 +231,3 @@ damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) loot = list() -//Blood - -/obj/item/weapon/dragons_blood - name = "bottle of dragons blood" - desc = "You're not actually going to drink this, are you?" - icon = 'icons/obj/wizard.dmi' - icon_state = "vial" - -/obj/item/weapon/dragons_blood/attack_self(mob/living/carbon/human/user) - if(!istype(user)) - return - - var/mob/living/carbon/human/H = user - var/random = rand(1,3) - - switch(random) - if(1) - user << "Other than tasting terrible, nothing really happens." - if(2) - user << "Your flesh begins to melt! Miraculously, you seem fine otherwise." - H.set_species(/datum/species/skeleton) - if(3) - user << "You don't feel so good..." - H.ForceContractDisease(new /datum/disease/transformation/dragon(0)) - playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1) - qdel(src) - -/datum/disease/transformation/dragon - name = "dragon transformation" - cure_text = "nothing" - cures = list("adminordrazine") - agent = "dragon's blood" - desc = "What do dragons have to do with Space Station 13?" - stage_prob = 20 - severity = BIOHAZARD - visibility_flags = 0 - stage1 = list("Your bones ache.") - stage2 = list("Your skin feels scaley.") - stage3 = list("You have an overwhelming urge to terrorize some peasants.", "Your teeth feel sharper.") - stage4 = list("Your blood burns.") - stage5 = list("You're a fucking dragon.") - new_form = /mob/living/simple_animal/hostile/megafauna/dragon/lesser - - -//Lava Staff - -/obj/item/weapon/lava_staff - name = "staff of lava" - desc = "The ability to fill the emergency shuttle with lava. What more could you want out of life?" - icon_state = "staffofstorms" - item_state = "staffofstorms" - icon = 'icons/obj/guns/magic.dmi' - slot_flags = SLOT_BACK - item_state = "staffofstorms" - w_class = 4 - force = 25 - damtype = BURN - burn_state = LAVA_PROOF - hitsound = 'sound/weapons/sear.ogg' - var/lava_cooldown = 0 - -/obj/item/weapon/lava_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters) - ..() - if(lava_cooldown > world.time) - return - var/turf/T = get_turf(user) - if(istype(target, /turf/open) && (target in view(user.client.view,T))) - var/turf/open/O = target - user.visible_message("[user] turns \the [O] into lava!") - O.ChangeTurf(/turf/open/floor/plating/lava/smooth) - playsound(get_turf(src),'sound/magic/Fireball.ogg', 200, 1) - lava_cooldown = world.time + 200 - -/obj/structure/closet/crate/necropolis/dragon - name = "dragon chest" - -/obj/structure/closet/crate/necropolis/dragon/New() - ..() - var/loot = rand(1,2) - switch(loot) - if(1) - new /obj/item/weapon/melee/ghost_sword(src) - if(2) - new /obj/item/weapon/lava_staff(src) From 36176f2c1833dfe12b165bf81bbe2a8426bdc3a6 Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Mon, 6 Jun 2016 22:31:42 -0400 Subject: [PATCH 18/50] Buffs anima fragments --- code/game/gamemodes/clock_cult/clock_cult.dm | 9 +++- code/game/gamemodes/clock_cult/clock_mobs.dm | 41 ++++++++++++++----- .../gamemodes/clock_cult/clock_scripture.dm | 9 ++-- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 3686a6ccda2..1dabbfeaad5 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -40,10 +40,10 @@ This file's folder contains: return M && istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.servants_of_ratvar) /proc/is_eligible_servant(mob/M) - return M && istype(M) && M.mind && !M.mind.special_role && !isloyal(M) + return M && istype(M) && M.mind && !is_servant_of_ratvar(M) && !iscultist(M) && !isconstruct(M) && !isloyal(M) /proc/add_servant_of_ratvar(mob/M, silent = FALSE) - if(!is_eligible_servant(M) || !ticker || !ticker.mode) + if(!ticker || !ticker.mode) return 0 if(iscarbon(M)) if(!silent) @@ -60,6 +60,11 @@ This file's folder contains: M.visible_message("[M] whirs as it resists an outside influence!", \ "Corrupt data purged. Resetting cortex chip to factory defaults... complete.") return 0 + else if(!silent) + M << "Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar lies in exile, derelict and forgotten in an unseen realm." + if(!is_eligible_servant(M)) + M.visible_message("[M] seems to resist an unseen force!", "And yet, you somehow push it all away.") + return 0 if(!silent) M.visible_message("[M]'s eyes glow a blazing yellow!", \ "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \ diff --git a/code/game/gamemodes/clock_cult/clock_mobs.dm b/code/game/gamemodes/clock_cult/clock_mobs.dm index f838c379bc7..c9caf1f975d 100644 --- a/code/game/gamemodes/clock_cult/clock_mobs.dm +++ b/code/game/gamemodes/clock_cult/clock_mobs.dm @@ -1,11 +1,12 @@ -/mob/living/simple_animal/hostile/anima_fragment //Anima fragment: Low health but high melee power. Created by inserting a soul vessel into an empty fragment. +/mob/living/simple_animal/hostile/anima_fragment //Anima fragment: High health and high melee damage, but slows down when struck. Created by inserting a soul vessel into an empty fragment. name = "anima fragment" desc = "An ominous humanoid shell with a spinning cogwheel as its head, lifted by a jet of blazing red flame." faction = list("ratvar") icon = 'icons/mob/clockwork_mobs.dmi' icon_state = "anime_fragment" - health = 75 //Glass cannon - maxHealth = 75 + health = 120 + maxHealth = 120 + speed = -1 minbodytemp = 0 atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) //Robotic healable = FALSE @@ -13,9 +14,13 @@ melee_damage_upper = 25 attacktext = "crushes" attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg' - var/playstyle_string = "You are an anima fragment, a clockwork creation of Ratvar. As a fragment, you are weak but possess powerful melee capabilities \ - in addition to being immune to extreme temperatures and pressures. Your goal is to serve the Justiciar and his servants in any way you can. You yourself are one of these servants, and will \ - be able to utilize anything they can, assuming it doesn't require opposable thumbs." + loot = list(/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment, /obj/item/device/mmi/posibrain/soul_vessel) + del_on_death = TRUE + death_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' + var/playstyle_string = "You are an anima fragment, a clockwork creation of Ratvar. As a fragment, you have medium health, do decent damage, and move at \ + extreme speed in addition to being immune to extreme temperatures and pressures. Taking damage will temporarily slow you down, however. Your goal is to serve the Justiciar and his servants \ + in any way you can. You yourself are one of these servants, and will be able to utilize anything they can, assuming it doesn't require opposable thumbs." + var/movement_delay_time //how long the fragment is slowed after being hit /mob/living/simple_animal/hostile/anima_fragment/New() ..() @@ -24,16 +29,32 @@ real_name = name desc = "I-it's not like I want to show you the light of the Justiciar or anything, B-BAKA!" +/mob/living/simple_animal/hostile/anima_fragment/Stat() + ..() + if(statpanel("Status") && movement_delay_time > world.time && !ratvar_awakens) + stat(null, "Movement delay(seconds): [max(round((movement_delay_time - world.time)*0.1, 0.1), 0)]") + /mob/living/simple_animal/hostile/anima_fragment/death(gibbed) ..(TRUE) visible_message("[src]'s flame jets cut out as it falls to the floor with a tremendous crash. A cube of metal tumbles out, whirring and sputtering.", \ "Your gears seize up. Your flame jets flicker. Your soul vessel belches smoke as you helplessly crash down.") - playsound(src, 'sound/magic/clockwork/anima_fragment_death.ogg', 100, 1) - new/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment(get_turf(src)) - new/obj/item/device/mmi/posibrain/soul_vessel(get_turf(src)) //Notice the lack of transfer - it's a standard soul vessel with no mind in it! - qdel(src) return 1 +/mob/living/simple_animal/hostile/anima_fragment/Process_Spacemove(movement_dir = 0) + return 1 + +/mob/living/simple_animal/hostile/anima_fragment/movement_delay() + . = ..() + if(movement_delay_time > world.time && !ratvar_awakens) + . += min((movement_delay_time - world.time) * 0.1, 10) //the more delay we have, the slower we go + +/mob/living/simple_animal/hostile/anima_fragment/adjustHealth(amount) + . = ..() + if(!ratvar_awakens) //if ratvar is up we ignore movement delay + if(movement_delay_time > world.time) + movement_delay_time = movement_delay_time + amount*2 + else + movement_delay_time = world.time + amount*2 /mob/living/simple_animal/hostile/clockwork_marauder //Clockwork marauder: Slow but with high damage, resides inside of a servant. Created via the Memory Allocation scripture. diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm index 07f48bba367..4fff557704e 100644 --- a/code/game/gamemodes/clock_cult/clock_scripture.dm +++ b/code/game/gamemodes/clock_cult/clock_scripture.dm @@ -645,7 +645,8 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed /datum/clockwork_scripture/create_object/anima_fragment //Anima Fragment: Creates an empty anima fragment name = "Anima Fragment" - desc = "Creates a large shell fitted for soul vessels. The result is a powerful construct with low damage tolerance but exceptional melee power." + desc = "Creates a large shell fitted for soul vessels. Adding an active sould vessel to it results in a powerful construct with decent health, notable melee power, \ + and exceptional speed, though taking damage will temporarily slow it down." invocations = list("Pnyy sbegu...", "...gur fbyqvref-bs Nezbere.") channel_time = 50 required_components = list("belligerent_eye" = 2, "guvax_capacitor" = 1, "replicant_alloy" = 2) @@ -731,14 +732,14 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed return 0 invoker.notransform = FALSE slab.busy = null - var/list/marauder_candidates = get_candidates(ROLE_SERVANT_OF_RATVAR) + var/list/marauder_candidates = pollCandidates("Do you want to play as the clockwork marauder of [invoker.real_name]?", ROLE_SERVANT_OF_RATVAR, null, FALSE, 100) if(!marauder_candidates.len) invoker.visible_message("The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!", \ "The tendril was unsuccessful! Perhaps you should try again another time.") return 0 - var/client/new_marauder = pick(marauder_candidates) + var/mob/dead/observer/theghost = pick(marauder_candidates) var/mob/living/simple_animal/hostile/clockwork_marauder/M = new(invoker) - M.client = new_marauder + M.key = theghost.key M.host = invoker M << M.playstyle_string M << "Your true name is \"[M.true_name]\". You can change this once by using the Change True Name verb in your Marauder tab." From de8946105832071a0b1b3d299cd9256166b23a83 Mon Sep 17 00:00:00 2001 From: sybil-tgstation13 Date: Tue, 7 Jun 2016 05:28:47 +0000 Subject: [PATCH 19/50] Automatic changelog compile, [ci skip] --- html/changelog.html | 106 ++++++++++++--------- html/changelogs/.all_changelog.yml | 89 +++++++++++++++++ html/changelogs/AutoChangeLog-pr-17934.yml | 5 - html/changelogs/AutoChangeLog-pr-17968.yml | 4 - html/changelogs/AutoChangeLog-pr-18108.yml | 5 - html/changelogs/AutoChangeLog-pr-18197.yml | 4 - html/changelogs/AutoChangeLog-pr-18218.yml | 8 -- html/changelogs/AutoChangeLog-pr-18241.yml | 7 -- html/changelogs/AutoChangeLog-pr-18259.yml | 4 - html/changelogs/AutoChangeLog-pr-18263.yml | 4 - html/changelogs/AutoChangeLog-pr-18264.yml | 4 - html/changelogs/AutoChangeLog-pr-18292.yml | 22 ----- 12 files changed, 149 insertions(+), 113 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-17934.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-17968.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18108.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18197.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18218.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18241.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18259.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18263.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18264.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18292.yml diff --git a/html/changelog.html b/html/changelog.html index 37a3acc125e..ba19896e817 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,66 @@ -->
+

07 June 2016

+

Bobylein updated:

+
    +
  • Nanotrasen is finally able to source transparent bottles for chemistry.
  • +
+

Iamgoofball updated:

+
    +
  • The Greytide Virus got some teeth.
  • +
+

Joan updated:

+
    +
  • This is a bunch of Clockwork Cult changes.
  • +
  • Added the Clockwork Obelisk, an Application scripture that produces a clockwork obelisk, which can Hierophant Broadcast a large message to all servants or open a Spatial Gateway with 5 uses and a 10 second duration to any conscious servant or clockwork obelisk.
  • +
  • Spatial Gateways of any source have doubled uses and duration when the target is a clockwork obelisk.
  • +
  • Added the Mania Motor, an Application scripture that produces a mania motor, which, while active, causes hallucinations and brain damage in all nearby humans.
  • +
  • The Mania Motor will try to convert any non-servant human directly adjacent to it at an additional power cost and will remove brain damage, hallucinations, and the druggy effect from servants.
  • +
  • Added the Vitality Matrix, an Application scripture that produces a sigil that will slowly drain health from non-servants that remain on it. Servants that remain on the sigil will instead be healed with the vitality drained from non-servants.
  • +
  • The Vitality Matrix can revive dead servants for a cost of 25 vitality plus all non-oxygen damage the servant has. If it cannot immediately revive a servant, it will still heal their corpse.
  • +
  • Most clockwork structures, including the Mending Motor, Interdiction Lens, and the newly added Clockwork Obelisk and Mania Motor, now require power to function.
  • +
  • Mending Motors can still use alloy for power.
  • +
  • The Sigil of Transmission has been remade into a power battery and will power directly adjecent clockwork structures. Sigils of Transmission start off with 4000 power and can be recharged with Volt Void.
  • +
  • Volt Void drains somewhat more power, but will not damage the invoker unless they drain too much power. Invokers with augmented limbs will instead have those limbs healed unless they drain especially massive amounts of power.
  • +
  • Using Volt Void on top of a Sigil of Transmission will transfer most of the power drained to the Sigil of Transmission, effectively making it far less likely to damage the invoker.
  • +
  • You can no longer stack most sigils and clockwork objects with themself. You can still have multiple different objects or sigils on a tile, however.
  • +
  • The Break Will Script has been renamed to Dementia Doctrine, is slightly faster, and causes slightly more brain damage.
  • +
  • The Judicial Visor now uses an action button instead of alt-click. Cultists of Nar-Sie judged by the visor will be stunned for half duration, but will be set on fire.
  • +
  • Multiple scriptures have had their component requirements changed. The Summon Judicial Visor Script has been reduced from a Script to a Driver.
  • +
  • Recollection will now show both required and consumed components.
  • +
  • Clockwork Marauders can now emerge from their host if their host is at or below 60% total health(for humans, this is 20 health out of crit)
  • +
  • Clockwork Marauders will slowly heal if directly adjacent to their host and have a slightly larger threshold for their no-Fatigue bonus damage.
  • +
+

Quiltyquilty updated:

+
    +
  • Botany, atmospherics and cargo now all have access to high-capacity watertanks.
  • +
  • The bar has now been outfitted with custom bar stools.
  • +
+

Xhuis updated:

+
    +
  • Removed the global message played when Nar-Sie _begins_ to spawn (but not when it actually spawns).
  • +
  • Drunkenness recovery speed now increases with how drunk the imbiber is and is much quicker when the imbiber is asleep.
  • +
  • Suit storage units now take three seconds to enter (up from one) and have different sounds and messages for UV ray cauterization.
  • +
  • Fixed some bugs with the suit storage unit, inserting mobs, and contents to seemed to duplicate themselves.
  • +
  • The Summon Nar-Sie rune can now only be drawn on original station tiles and fails to invoke if scribed on the station then moved elsewhere.
  • +
+

coiax updated:

+
    +
  • Bluespace shelter capsules can no longer be used on shuttles.
  • +
  • Bluespace shelters may have different capsules stored. View what your capsule has inside by examining it.
  • +
  • The Nar'sie rune cannot be scribed on shuttles or off Z-level.
  • +
  • The Raise Dead rune automatically grabs the ghost of the raised corpse.
  • +
  • Deadchat is now notified when a sentient mob dies.
  • +
+

phil235 updated:

+
    +
  • Monkeys and all other animals that should have blood now has it. Beating them up will make you and your weapon bloody, just like beating a human does. Dragging them when wounded and lying will leave a blood trail. Their blood is still mostly cosmetic, they suffer no effects from low blood level, unlike humans.
  • +
  • When a mob leaves a blood trail while dragged, it loses blood. You can no longer drag a corpse to make an inifinite amount of blood trails, because once the victim's blood reaches a certain threshold it no longer leaves a blood trail (and no longer lose any more blood). The threshold depends on how much damage the mob has taken. You can always avoid hurting the dragged mob by making them stand up or by buckling them to something or by putting them in a container.
  • +
  • You can no longer empty a mob of its blood entirely with a syringe, once the mob's blood volume reaches a critically low level you are unable to draw any more blood from it.
  • +
  • A changeling absorbing a human now sucks all their blood.
  • +
+

05 June 2016

Joan updated:

    @@ -1146,52 +1206,6 @@
    • Honk! Nanotrasen's clowning and development department has invented the clown megaphone, standard in all clowning loadouts! Honk honk!
    - -

    05 April 2016

    -

    Erwgd updated:

    -
      -
    • Utility belts of all kinds can now accept gloves. Most belts, except janitorial belts, may now also hold station bounced radios.
    • -
    • Hazard vests and most jackets can carry a station bounced radio as well. Labcoats can be used to store a handheld crew monitor.
    • -
    • The autolathe can now make toolboxes.
    • -
    -

    Joan updated:

    -
      -
    • Adds protector holoparasites to traitor holoparasite injectors.
    • -
    • Protector holoparasites cause the summoner to teleport to them when out of range, instead of the other way around.
    • -
    • Protector holoparasites have two modes; Combat, where they do and take medium damage, and Protection, where they do and take almost no damage, but move slightly slower.
    • -
    • Explosive Holoparasites no longer teleport non-mobs when attacking, but have a higher chance to teleport mobs.
    • -
    • Explosive Holoparasite bombs no longer trigger on their summoner or any other parasites their summoner has.
    • -
    • Ranged Holoparasites no longer have nightvision active by default. It can still be toggled on.
    • -
    • Ranged Holoparasite snares no longer alert if the crossing mob is their summoner or one of the parasites their summoner has.
    • -
    • Ranged Holoparasites are slightly less visible in scout mode.
    • -
    • Standard Holoparasites attack 20% faster than other parasite types.
    • -
    • Support Holoparasite beacons no longer require safe atmospheric conditions, but the warp channel takes slightly longer, and is preceded with a visible message.
    • -
    • Zombies can no longer destroy more than one airlock at a time.
    • -
    • The mining station has been updated.
    • -
    -

    MrStonedOne updated:

    -
      -
    • Centcom is glad to announce the end of sending workers to our control group for space exposure testing, a fake station in "space" that noticeably had air in "space".
    • -
    -

    TechnoAlchemisto updated:

    -
      -
    • Detective scanners are now smaller.
    • -
    • Pickaxes now fit in explorer suit exosuit slots.
    • -
    -

    bgobandit updated:

    -
      -
    • Alt-clicking a fire extinguisher cabinet opens and closes it. That is all.
    • -
    - -

    04 April 2016

    -

    TechnoAlchemisto updated:

    -
      -
    • The recipes for some Trekchems are now back in the game
    • -
    • Bicaridine can be made with carbon, oxygen, and sugar.
    • -
    • Kelotane can be made with silicon and carbon.
    • -
    • Antitoxin can be made with nitrogen, silicon, and potassium
    • -
    • tricordrazine can be made by combining all three.
    • -
GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index d25985dd36f..4ba647bd0fd 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -5362,3 +5362,92 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - rscadd: Gravity Guns! It is a mildly expensive R&D gun that has a 5 second cooldown between shots, but doesn't need to be recharged. It has two modes, attract and repulse. For all your gravity-manipulation needs! +2016-06-07: + Bobylein: + - rscadd: Nanotrasen is finally able to source transparent bottles for chemistry. + Iamgoofball: + - experiment: The Greytide Virus got some teeth. + Joan: + - wip: This is a bunch of Clockwork Cult changes. + - rscadd: Added the Clockwork Obelisk, an Application scripture that produces a + clockwork obelisk, which can Hierophant Broadcast a large message to all servants + or open a Spatial Gateway with 5 uses and a 10 second duration to any conscious + servant or clockwork obelisk. + - wip: Spatial Gateways of any source have doubled uses and duration when the target + is a clockwork obelisk. + - rscadd: Added the Mania Motor, an Application scripture that produces a mania + motor, which, while active, causes hallucinations and brain damage in all nearby + humans. + - wip: The Mania Motor will try to convert any non-servant human directly adjacent + to it at an additional power cost and will remove brain damage, hallucinations, + and the druggy effect from servants. + - rscadd: Added the Vitality Matrix, an Application scripture that produces a sigil + that will slowly drain health from non-servants that remain on it. Servants + that remain on the sigil will instead be healed with the vitality drained from + non-servants. + - wip: The Vitality Matrix can revive dead servants for a cost of 25 vitality plus + all non-oxygen damage the servant has. If it cannot immediately revive a servant, + it will still heal their corpse. + - experiment: Most clockwork structures, including the Mending Motor, Interdiction + Lens, and the newly added Clockwork Obelisk and Mania Motor, now require power + to function. + - wip: Mending Motors can still use alloy for power. + - tweak: The Sigil of Transmission has been remade into a power battery and will + power directly adjecent clockwork structures. Sigils of Transmission start off + with 4000 power and can be recharged with Volt Void. + - tweak: Volt Void drains somewhat more power, but will not damage the invoker unless + they drain too much power. Invokers with augmented limbs will instead have those + limbs healed unless they drain especially massive amounts of power. + - wip: Using Volt Void on top of a Sigil of Transmission will transfer most of the + power drained to the Sigil of Transmission, effectively making it far less likely + to damage the invoker. + - rscdel: You can no longer stack most sigils and clockwork objects with themself. + You can still have multiple different objects or sigils on a tile, however. + - tweak: The Break Will Script has been renamed to Dementia Doctrine, is slightly + faster, and causes slightly more brain damage. + - tweak: The Judicial Visor now uses an action button instead of alt-click. Cultists + of Nar-Sie judged by the visor will be stunned for half duration, but will be + set on fire. + - tweak: Multiple scriptures have had their component requirements changed. The + Summon Judicial Visor Script has been reduced from a Script to a Driver. + - rscadd: Recollection will now show both required and consumed components. + - tweak: Clockwork Marauders can now emerge from their host if their host is at + or below 60% total health(for humans, this is 20 health out of crit) + - tweak: Clockwork Marauders will slowly heal if directly adjacent to their host + and have a slightly larger threshold for their no-Fatigue bonus damage. + Quiltyquilty: + - rscadd: Botany, atmospherics and cargo now all have access to high-capacity watertanks. + - rscadd: The bar has now been outfitted with custom bar stools. + Xhuis: + - rscdel: Removed the global message played when Nar-Sie _begins_ to spawn (but + not when it actually spawns). + - tweak: Drunkenness recovery speed now increases with how drunk the imbiber is + and is much quicker when the imbiber is asleep. + - tweak: Suit storage units now take three seconds to enter (up from one) and have + different sounds and messages for UV ray cauterization. + - bugfix: Fixed some bugs with the suit storage unit, inserting mobs, and contents + to seemed to duplicate themselves. + - bugfix: The Summon Nar-Sie rune can now only be drawn on original station tiles + and fails to invoke if scribed on the station then moved elsewhere. + coiax: + - rscdel: Bluespace shelter capsules can no longer be used on shuttles. + - rscadd: Bluespace shelters may have different capsules stored. View what your + capsule has inside by examining it. + - rscdel: The Nar'sie rune cannot be scribed on shuttles or off Z-level. + - rscadd: The Raise Dead rune automatically grabs the ghost of the raised corpse. + - rscadd: Deadchat is now notified when a sentient mob dies. + phil235: + - rscadd: Monkeys and all other animals that should have blood now has it. Beating + them up will make you and your weapon bloody, just like beating a human does. + Dragging them when wounded and lying will leave a blood trail. Their blood is + still mostly cosmetic, they suffer no effects from low blood level, unlike humans. + - rscadd: When a mob leaves a blood trail while dragged, it loses blood. You can + no longer drag a corpse to make an inifinite amount of blood trails, because + once the victim's blood reaches a certain threshold it no longer leaves a blood + trail (and no longer lose any more blood). The threshold depends on how much + damage the mob has taken. You can always avoid hurting the dragged mob by making + them stand up or by buckling them to something or by putting them in a container. + - rscdel: You can no longer empty a mob of its blood entirely with a syringe, once + the mob's blood volume reaches a critically low level you are unable to draw + any more blood from it. + - tweak: A changeling absorbing a human now sucks all their blood. diff --git a/html/changelogs/AutoChangeLog-pr-17934.yml b/html/changelogs/AutoChangeLog-pr-17934.yml deleted file mode 100644 index 4cd736e2ba4..00000000000 --- a/html/changelogs/AutoChangeLog-pr-17934.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: coiax -delete-after: True -changes: - - rscdel: "Bluespace shelter capsules can no longer be used on shuttles." - - rscadd: "Bluespace shelters may have different capsules stored. View what your capsule has inside by examining it." diff --git a/html/changelogs/AutoChangeLog-pr-17968.yml b/html/changelogs/AutoChangeLog-pr-17968.yml deleted file mode 100644 index 2367575fa5b..00000000000 --- a/html/changelogs/AutoChangeLog-pr-17968.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Bobylein -delete-after: True -changes: - - rscadd: "Nanotrasen is finally able to source transparent bottles for chemistry." diff --git a/html/changelogs/AutoChangeLog-pr-18108.yml b/html/changelogs/AutoChangeLog-pr-18108.yml deleted file mode 100644 index 536059097c6..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18108.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: coiax -delete-after: True -changes: - - rscdel: "The Nar'sie rune cannot be scribed on shuttles or off Z-level." - - rscadd: "The Raise Dead rune automatically grabs the ghost of the raised corpse." diff --git a/html/changelogs/AutoChangeLog-pr-18197.yml b/html/changelogs/AutoChangeLog-pr-18197.yml deleted file mode 100644 index c0021f6f875..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18197.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Quiltyquilty -delete-after: True -changes: - - rscadd: "Botany, atmospherics and cargo now all have access to high-capacity watertanks." diff --git a/html/changelogs/AutoChangeLog-pr-18218.yml b/html/changelogs/AutoChangeLog-pr-18218.yml deleted file mode 100644 index 15e624f544f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18218.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: Xhuis -delete-after: True -changes: - - rscdel: "Removed the global message played when Nar-Sie _begins_ to spawn (but not when it actually spawns)." - - tweak: "Drunkenness recovery speed now increases with how drunk the imbiber is and is much quicker when the imbiber is asleep." - - tweak: "Suit storage units now take three seconds to enter (up from one) and have different sounds and messages for UV ray cauterization." - - bugfix: "Fixed some bugs with the suit storage unit, inserting mobs, and contents to seemed to duplicate themselves." - - bugfix: "The Summon Nar-Sie rune can now only be drawn on original station tiles and fails to invoke if scribed on the station then moved elsewhere." diff --git a/html/changelogs/AutoChangeLog-pr-18241.yml b/html/changelogs/AutoChangeLog-pr-18241.yml deleted file mode 100644 index 341f132ab60..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18241.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: phil235 -delete-after: True -changes: - - rscadd: "Monkeys and all other animals that should have blood now has it. Beating them up will make you and your weapon bloody, just like beating a human does. Dragging them when wounded and lying will leave a blood trail. Their blood is still mostly cosmetic, they suffer no effects from low blood level, unlike humans." - - rscadd: "When a mob leaves a blood trail while dragged, it loses blood. You can no longer drag a corpse to make an inifinite amount of blood trails, because once the victim's blood reaches a certain threshold it no longer leaves a blood trail (and no longer lose any more blood). The threshold depends on how much damage the mob has taken. You can always avoid hurting the dragged mob by making them stand up or by buckling them to something or by putting them in a container." - - rscdel: "You can no longer empty a mob of its blood entirely with a syringe, once the mob's blood volume reaches a critically low level you are unable to draw any more blood from it." - - tweak: "A changeling absorbing a human now sucks all their blood." diff --git a/html/changelogs/AutoChangeLog-pr-18259.yml b/html/changelogs/AutoChangeLog-pr-18259.yml deleted file mode 100644 index 7d2db181f7a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18259.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Iamgoofball -delete-after: True -changes: - - experiment: "The Greytide Virus got some teeth." diff --git a/html/changelogs/AutoChangeLog-pr-18263.yml b/html/changelogs/AutoChangeLog-pr-18263.yml deleted file mode 100644 index 620bf0af65c..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18263.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Quiltyquilty -delete-after: True -changes: - - rscadd: "The bar has now been outfitted with custom bar stools." diff --git a/html/changelogs/AutoChangeLog-pr-18264.yml b/html/changelogs/AutoChangeLog-pr-18264.yml deleted file mode 100644 index fda3ad00227..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18264.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: coiax -delete-after: True -changes: - - rscadd: "Deadchat is now notified when a sentient mob dies." diff --git a/html/changelogs/AutoChangeLog-pr-18292.yml b/html/changelogs/AutoChangeLog-pr-18292.yml deleted file mode 100644 index 059ad70ec85..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18292.yml +++ /dev/null @@ -1,22 +0,0 @@ -author: Joan -delete-after: True -changes: - - wip: "This is a bunch of Clockwork Cult changes." - - rscadd: "Added the Clockwork Obelisk, an Application scripture that produces a clockwork obelisk, which can Hierophant Broadcast a large message to all servants or open a Spatial Gateway with 5 uses and a 10 second duration to any conscious servant or clockwork obelisk." - - wip: "Spatial Gateways of any source have doubled uses and duration when the target is a clockwork obelisk." - - rscadd: "Added the Mania Motor, an Application scripture that produces a mania motor, which, while active, causes hallucinations and brain damage in all nearby humans." - - wip: "The Mania Motor will try to convert any non-servant human directly adjacent to it at an additional power cost and will remove brain damage, hallucinations, and the druggy effect from servants." - - rscadd: "Added the Vitality Matrix, an Application scripture that produces a sigil that will slowly drain health from non-servants that remain on it. Servants that remain on the sigil will instead be healed with the vitality drained from non-servants." - - wip: "The Vitality Matrix can revive dead servants for a cost of 25 vitality plus all non-oxygen damage the servant has. If it cannot immediately revive a servant, it will still heal their corpse." - - experiment: "Most clockwork structures, including the Mending Motor, Interdiction Lens, and the newly added Clockwork Obelisk and Mania Motor, now require power to function." - - wip: "Mending Motors can still use alloy for power." - - tweak: "The Sigil of Transmission has been remade into a power battery and will power directly adjecent clockwork structures. Sigils of Transmission start off with 4000 power and can be recharged with Volt Void." - - tweak: "Volt Void drains somewhat more power, but will not damage the invoker unless they drain too much power. Invokers with augmented limbs will instead have those limbs healed unless they drain especially massive amounts of power." - - wip: "Using Volt Void on top of a Sigil of Transmission will transfer most of the power drained to the Sigil of Transmission, effectively making it far less likely to damage the invoker." - - rscdel: "You can no longer stack most sigils and clockwork objects with themself. You can still have multiple different objects or sigils on a tile, however." - - tweak: "The Break Will Script has been renamed to Dementia Doctrine, is slightly faster, and causes slightly more brain damage." - - tweak: "The Judicial Visor now uses an action button instead of alt-click. Cultists of Nar-Sie judged by the visor will be stunned for half duration, but will be set on fire." - - tweak: "Multiple scriptures have had their component requirements changed. The Summon Judicial Visor Script has been reduced from a Script to a Driver." - - rscadd: "Recollection will now show both required and consumed components." - - tweak: "Clockwork Marauders can now emerge from their host if their host is at or below 60% total health(for humans, this is 20 health out of crit)" - - tweak: "Clockwork Marauders will slowly heal if directly adjacent to their host and have a slightly larger threshold for their no-Fatigue bonus damage." From 4ce47d1a6f2055c4e875100b87f2362632b6f761 Mon Sep 17 00:00:00 2001 From: Fox-McCloud Date: Tue, 7 Jun 2016 02:10:44 -0400 Subject: [PATCH 20/50] Experimentor Fixes --- code/game/objects/items/devices/transfer_valve.dm | 1 + code/modules/assembly/bomb.dm | 1 + code/modules/research/experimentor.dm | 8 +++++--- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index a8de11836a8..883f9d57699 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -10,6 +10,7 @@ var/mob/attacher = null var/valve_open = 0 var/toggle = 1 + origin_tech = "materials=1;engineering=1" /obj/item/device/transfer_valve/IsAssemblyHolder() return 1 diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index dbe63bcbd3b..f29fd150717 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -10,6 +10,7 @@ var/status = 0 //0 - not readied //1 - bomb finished with welder var/obj/item/device/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device var/obj/item/weapon/tank/bombtank = null //the second part of the bomb is a plasma tank + origin_tech = "materials=1;engineering=1" /obj/item/device/onetankbomb/examine(mob/user) ..() diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 8422a2c96f1..ea9e34be746 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -191,10 +191,12 @@ if(loaded_item) if(cloneMode && cloneCount > 0) visible_message("A duplicate [loaded_item] pops out!") - new loaded_item(get_turf(pick(oview(1,src)))) + var/type_to_make = loaded_item.type + new type_to_make(get_turf(pick(oview(1,src)))) --cloneCount if(cloneCount == 0) cloneMode = FALSE + return var/turf/dropturf = get_turf(pick(view(1,src))) if(!dropturf) //Failsafe to prevent the object being lost in the void forever. dropturf = get_turf(src) @@ -225,7 +227,7 @@ recentlyExperimented = 1 icon_state = "h_lathe_wloop" var/chosenchem - var/criticalReaction = locate(exp_on) in critical_items ? TRUE : FALSE + var/criticalReaction = (exp_on.type in critical_items) ? TRUE : FALSE //////////////////////////////////////////////////////////////////////////////////////////////// if(exp == SCANTYPE_POKE) visible_message("[src] prods at [exp_on] with mechanical arms.") @@ -379,7 +381,7 @@ visible_message("[src] lowers [exp_on]'s temperature.") if(prob(EFFECT_PROB_LOW) && criticalReaction) visible_message("[src]'s emergency coolant system gives off a small ding!") - var/obj/machinery/vending/coffee/C = new /obj/machinery/vending/coffee(get_turf(pick(oview(1,src)))) + var/obj/item/weapon/reagent_containers/food/drinks/coffee/C = new /obj/item/weapon/reagent_containers/food/drinks/coffee(get_turf(pick(oview(1,src)))) playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) //Ding! Your death coffee is ready! chosenchem = pick("uranium","frostoil","ephedrine") C.reagents.remove_any(25) From 25827d6ccbb9de766dadf56a90d67b86982f6ede Mon Sep 17 00:00:00 2001 From: LatD Date: Tue, 7 Jun 2016 11:18:19 +0300 Subject: [PATCH 21/50] [Ready] Tweaks some R&D levels (#18246) Removes tech levels from some traitor objectives. They had tech levels even before the remake but apparently now that the levels got raised that became a problem. Also some small tweaks to other items to make some early levels easier to get. --- code/game/gamemodes/miniantags/bot_swarm/swarmer.dm | 2 +- code/game/objects/items/weapons/holosign_creator.dm | 4 ++-- code/game/objects/items/weapons/storage/backpack.dm | 2 +- code/modules/clothing/shoes/magboots.dm | 2 +- code/modules/mining/equipment_locker.dm | 4 ++-- code/modules/mob/living/carbon/brain/posibrain.dm | 2 +- code/modules/projectiles/guns/energy/nuclear.dm | 2 +- code/modules/projectiles/guns/syringe_gun.dm | 2 +- code/modules/research/designs.dm | 6 +++--- code/modules/research/designs/weapon_designs.dm | 12 ++++++------ code/modules/telesci/gps.dm | 2 +- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index de4443926b8..caa390984df 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -4,7 +4,7 @@ desc = "A currently unactivated swarmer. Swarmers can self activate at any time, it would be wise to immediately dispose of this." icon = 'icons/mob/swarmer.dmi' icon_state = "swarmer_unactivated" - origin_tech = "bluespace=4;materials=4;programming=6" + origin_tech = "bluespace=4;materials=4;programming=7" materials = list(MAT_METAL=10000, MAT_GLASS=4000) diff --git a/code/game/objects/items/weapons/holosign_creator.dm b/code/game/objects/items/weapons/holosign_creator.dm index 23ad73a62ca..7b5404b760d 100644 --- a/code/game/objects/items/weapons/holosign_creator.dm +++ b/code/game/objects/items/weapons/holosign_creator.dm @@ -9,7 +9,7 @@ throwforce = 0 throw_speed = 3 throw_range = 7 - origin_tech = "magnets=3;programming=3" + origin_tech = "magnets=1;programming=3" flags = NOBLUDGEON var/list/signs = list() var/max_signs = 10 @@ -256,4 +256,4 @@ M.electrocute_act(15,"Energy Barrier", safety=1) shockcd = 1 spawn(10) - shockcd = 0 \ No newline at end of file + shockcd = 0 diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 4577b3bae40..ec8b97b9099 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -33,7 +33,7 @@ /obj/item/weapon/storage/backpack/holding name = "bag of holding" desc = "A backpack that opens into a localized pocket of Blue Space." - origin_tech = "bluespace=5" + origin_tech = "bluespace=5;materials=4;engineering=4;plasmatech=5" icon_state = "holdingpack" max_w_class = 6 max_combined_w_class = 35 diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 85e9ab69c30..6b9b5d1c8c3 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -50,7 +50,7 @@ icon_state = "advmag0" magboot_state = "advmag" slowdown_active = SHOES_SLOWDOWN - origin_tech = "magnets=6;engineering=4" + origin_tech = null /obj/item/clothing/shoes/magboots/syndie desc = "Reverse-engineered magnetic boots that have a heavy magnetic pull. Property of Gorlex Marauders." diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 7c8c9cfb5c7..14555fc484a 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -883,6 +883,7 @@ icon_state = "door_electronics" icon = 'icons/obj/module.dmi' sentience_type = SENTIENCE_MINEBOT + origin_tech = "programming=6" /**********************Lazarus Injector**********************/ @@ -900,7 +901,7 @@ var/loaded = 1 var/malfunctioning = 0 var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it - origin_tech = "biotech=4" + origin_tech = "biotech=4;magnets=6" /obj/item/weapon/lazarus_injector/afterattack(atom/target, mob/user, proximity_flag) if(!loaded) @@ -1172,4 +1173,3 @@ /obj/item/weapon/circuitboard/machine/mining_equipment_vendor/golem name = "circuit board (Golem Ship Equipment Vendor)" build_path = /obj/machinery/mineral/equipment_vendor/golem - diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm index 3dc6ea17a4d..1c0f8ece0ca 100644 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -6,7 +6,7 @@ var/global/posibrain_notif_cooldown = 0 icon = 'icons/obj/assemblies.dmi' icon_state = "posibrain" w_class = 3 - origin_tech = "biotech=4;programming=4;plasmatech=3" + origin_tech = "biotech=3;programming=3;plasmatech=2" var/notified = 0 var/askDelay = 10 * 60 * 1 var/used = 0 //Prevents split personality virus. May be reset if personality deletion code is added. diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 8661313ec86..57918ce5dd4 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -35,7 +35,7 @@ name = "\improper X-01 MultiPhase Energy Gun" desc = "This is a expensive, modern recreation of a antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time." icon_state = "hoslaser" - origin_tech = "combat=5;magnets=4" + origin_tech = null force = 10 ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler) ammo_x_offset = 4 diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index 04b438f82f8..470cf2fd537 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -8,7 +8,7 @@ throw_range = 7 force = 4 materials = list(MAT_METAL=2000) - origin_tech = "combat=3;biotech=3" + origin_tech = "combat=2;biotech=3" clumsy_check = 0 fire_sound = 'sound/items/syringeproj.ogg' var/list/syringes = list() diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 1204ac11d3a..4755a3248a0 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -216,7 +216,7 @@ other types of metals and chemistry for reagents). name = "Bag of Holding" desc = "A backpack that opens into a localized pocket of Blue Space." id = "bag_holding" - req_tech = list("bluespace" = 7, "materials" = 5, "engineering" = 6, "plasmatech" = 5) + req_tech = list("bluespace" = 7, "materials" = 5, "engineering" = 5, "plasmatech" = 6) build_type = PROTOLATHE materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 1500, MAT_URANIUM = 250) build_path = /obj/item/weapon/storage/backpack/holding @@ -236,7 +236,7 @@ other types of metals and chemistry for reagents). name = "GPS Device" desc = "Little thingie that can track its position at all times." id = "telesci_gps" - req_tech = list("materials" = 2, "magnets" = 3, "bluespace" = 3) + req_tech = list("materials" = 2, "bluespace" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 1000) build_path = /obj/item/device/gps @@ -482,7 +482,7 @@ datum/design/diagnostic_hud_night name = "Holographic Sign Projector" desc = "A holograpic projector used to project various warning signs." id = "holosign" - req_tech = list("magnets" = 3, "programming" = 3) + req_tech = list("programming" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) build_path = /obj/item/weapon/holosign_creator diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index e704a8a488d..743f65bcc88 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -77,7 +77,7 @@ name = "Rapid Syringe Gun" desc = "A gun that fires many syringes." id = "rapidsyringe" - req_tech = list("combat" = 3, "biotech" = 3) + req_tech = list("combat" = 2, "biotech" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 1000) build_path = /obj/item/weapon/gun/syringe/rapidsyringe @@ -200,7 +200,7 @@ //WT550 Mags /datum/design/mag_oldsmg - name = "WT-550 Auto Gun Magazine (4.6×30mm)" + name = "WT-550 Auto Gun Magazine (4.6×30mm)" desc = "A 20 round magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg" req_tech = list("combat" = 1, "materials" = 1) @@ -210,22 +210,22 @@ category = list("Ammo") /datum/design/mag_oldsmg/ap_mag - name = "WT-550 Auto Gun Armour Piercing Magazine (4.6×30mm AP)" + name = "WT-550 Auto Gun Armour Piercing Magazine (4.6×30mm AP)" desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_ap" materials = list(MAT_METAL = 6000, MAT_SILVER = 600) build_path = /obj/item/ammo_box/magazine/wt550m9/wtap /datum/design/mag_oldsmg/ic_mag - name = "WT-550 Auto Gun Incendiary Magazine (4.6×30mm IC)" + name = "WT-550 Auto Gun Incendiary Magazine (4.6×30mm IC)" desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_ic" materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_GLASS = 1000) build_path = /obj/item/ammo_box/magazine/wt550m9/wtic /datum/design/mag_oldsmg/tx_mag - name = "WT-550 Auto Gun Urnaium Magazine (4.6×30mm TX)" - desc = "A 20 round urnaium tipped magazine for the out of date security WT-550 Auto Rifle" + name = "WT-550 Auto Gun Uranium Magazine (4.6×30mm TX)" + desc = "A 20 round uranium tipped magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_tx" materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_URANIUM = 2000) build_path = /obj/item/ammo_box/magazine/wt550m9/wttx diff --git a/code/modules/telesci/gps.dm b/code/modules/telesci/gps.dm index f882b4444c7..03fc5baf7bb 100644 --- a/code/modules/telesci/gps.dm +++ b/code/modules/telesci/gps.dm @@ -6,7 +6,7 @@ var/list/GPS_list = list() icon_state = "gps-c" w_class = 2 slot_flags = SLOT_BELT - origin_tech = "materials=2;magnets=3;bluespace=3" + origin_tech = "materials=2;magnets=1;bluespace=2" var/gpstag = "COM0" var/emped = 0 var/turf/locked_location From 922d6166e7bf00e95735aa754a80165ae17d1589 Mon Sep 17 00:00:00 2001 From: GunHog Date: Tue, 7 Jun 2016 03:22:51 -0500 Subject: [PATCH 22/50] Thematic Head of Staff ID Computers (#18297) - Each of the heads' ID computers are now themed for their department! --- code/game/machinery/computer/card.dm | 4 ++++ icons/obj/computer.dmi | Bin 38472 -> 39407 bytes 2 files changed, 4 insertions(+) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 0bbbeda6165..3413b500502 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -504,12 +504,16 @@ var/time_last_changed_position = 0 /obj/machinery/computer/card/minor/hos target_dept = 2 + icon_screen = "idhos" /obj/machinery/computer/card/minor/cmo target_dept = 3 + icon_screen = "idcmo" /obj/machinery/computer/card/minor/rd target_dept = 4 + icon_screen = "idrd" /obj/machinery/computer/card/minor/ce target_dept = 5 + icon_screen = "idce" diff --git a/icons/obj/computer.dmi b/icons/obj/computer.dmi index e359eb9d2f5ca20ad1812ac08e8169c0cda3d13c..2a26590dff36f41cf7891df9c19139d2693e25d8 100644 GIT binary patch delta 17320 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 From a6924931b2304a95b63c456220c5c257bfb5350e Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Tue, 7 Jun 2016 08:22:53 +0000 Subject: [PATCH 23/50] Automatic changelog generation for PR #18297 [ci skip] --- html/changelogs/AutoChangeLog-pr-18297.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18297.yml diff --git a/html/changelogs/AutoChangeLog-pr-18297.yml b/html/changelogs/AutoChangeLog-pr-18297.yml new file mode 100644 index 00000000000..e0a79042fd9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18297.yml @@ -0,0 +1,4 @@ +author: GunHog +delete-after: True +changes: + - tweak: "Each of the heads' ID computers are now themed for their department!" From 51c317ed023fdc9c778d191da03c22218109c768 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Tue, 7 Jun 2016 03:42:35 -0700 Subject: [PATCH 24/50] Remove exception from rule about colon operator (:) This isn't needed because typecasting has a lot less overhead than we thought. --- CONTRIBUTING.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0aeab0904c..27cc7d4835a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -99,9 +99,7 @@ The previous code made compliant: ``` ###No overriding type safety checks. -The use of the : operator to override type safety checks is strongly discouraged. You must cast the variable to the proper type. - -Exceptions are only made when used in loops that require the performance boost from being called ***extremely*** often. (Rule of thumb: If you aren't messing with the master controller or it's subsystems, this exception probably doesn't apply) +The use of the : operator to override type safety checks is not allowed. You must cast the variable to the proper type. ###Type paths must began with a / eg: `/datum/thing` not `datum/thing` From 12825abcdb7404de5a82a29e6721b60cf7d00dc7 Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 09:49:48 -0400 Subject: [PATCH 25/50] formatting --- code/game/gamemodes/clock_cult/clock_cult.dm | 4 ++-- code/game/gamemodes/clock_cult/clock_scripture.dm | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 1dabbfeaad5..87ad2c6e9e8 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -48,7 +48,7 @@ This file's folder contains: if(iscarbon(M)) if(!silent) M << "Your mind is racing! Your body feels incredibly light! Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork \ - Justiciar lies in exile, derelict and forgotten in an unseen realm." + Justiciar, lies in exile, derelict and forgotten in an unseen realm.
" if(!is_eligible_servant(M)) M.visible_message("[M] seems to resist an unseen force!", "And yet, you somehow push it all away.") return 0 @@ -61,7 +61,7 @@ This file's folder contains: "Corrupt data purged. Resetting cortex chip to factory defaults... complete.") return 0 else if(!silent) - M << "Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar lies in exile, derelict and forgotten in an unseen realm." + M << "Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm." if(!is_eligible_servant(M)) M.visible_message("[M] seems to resist an unseen force!", "And yet, you somehow push it all away.") return 0 diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm index 4fff557704e..1c34f1bf0ac 100644 --- a/code/game/gamemodes/clock_cult/clock_scripture.dm +++ b/code/game/gamemodes/clock_cult/clock_scripture.dm @@ -732,6 +732,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed return 0 invoker.notransform = FALSE slab.busy = null + invoker << "The tendril shivers slightly as it selects a marauder..." var/list/marauder_candidates = pollCandidates("Do you want to play as the clockwork marauder of [invoker.real_name]?", ROLE_SERVANT_OF_RATVAR, null, FALSE, 100) if(!marauder_candidates.len) invoker.visible_message("The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!", \ From 3930124eef61f4487f2360e016bb4b7ab795848b Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 12:19:49 -0400 Subject: [PATCH 26/50] fix --- code/game/gamemodes/clock_cult/clock_cult.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 87ad2c6e9e8..1b5ba911440 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -40,10 +40,10 @@ This file's folder contains: return M && istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.servants_of_ratvar) /proc/is_eligible_servant(mob/M) - return M && istype(M) && M.mind && !is_servant_of_ratvar(M) && !iscultist(M) && !isconstruct(M) && !isloyal(M) + return M && istype(M) && M.mind && !iscultist(M) && !isconstruct(M) && !isloyal(M) /proc/add_servant_of_ratvar(mob/M, silent = FALSE) - if(!ticker || !ticker.mode) + if(is_servant_of_ratvar(M) || !ticker || !ticker.mode) return 0 if(iscarbon(M)) if(!silent) From 19eb97ae189a0fdced210f595f7ab0f2588e22ea Mon Sep 17 00:00:00 2001 From: AnturK Date: Sun, 29 May 2016 14:11:48 +0200 Subject: [PATCH 27/50] Moves some list initializations to New Fixes missing ..() calls in New() --- code/game/atoms.dm | 2 +- code/game/atoms_movable.dm | 4 ++-- .../gamemodes/clock_cult/clock_structures.dm | 2 +- .../shadowling/shadowling_abilities.dm | 2 +- code/game/machinery/machinery.dm | 4 ++-- code/game/machinery/washing_machine.dm | 2 +- .../mecha/equipment/tools/medical_tools.dm | 2 +- code/game/mecha/mecha.dm | 4 ++-- code/game/objects/buckling.dm | 19 ++++++++++++++----- .../objects/items/weapons/airlock_painter.dm | 1 + code/game/objects/items/weapons/tools.dm | 1 + .../structures/beds_chairs/alien_nest.dm | 4 ++-- .../objects/structures/beds_chairs/bed.dm | 2 +- .../objects/structures/beds_chairs/chair.dm | 10 +++++----- .../structures/crates_lockers/closets.dm | 4 ++-- code/game/objects/structures/electricchair.dm | 2 +- code/game/objects/structures/kitchen_spike.dm | 4 ++-- code/game/objects/structures/plasticflaps.dm | 2 +- .../structures/transit_tubes/station.dm | 4 ++-- .../machinery/pipes/heat_exchange/he_pipes.dm | 4 ++-- code/modules/clothing/gloves/color.dm | 2 ++ code/modules/events/spacevine.dm | 4 ++-- .../kitchen_machinery/gibber.dm | 4 ++-- .../kitchen_machinery/monkeyrecycler.dm | 2 +- code/modules/mining/ores_coins.dm | 2 ++ code/modules/mob/living/living.dm | 2 +- .../mob/living/simple_animal/bot/mulebot.dm | 2 +- .../mob/living/simple_animal/parrot.dm | 2 +- code/modules/mob/living/ventcrawling.dm | 2 +- code/modules/mob/mob.dm | 1 + code/modules/recycling/disposal-unit.dm | 2 +- code/modules/research/experimentor.dm | 1 + code/modules/research/stock_parts.dm | 1 + code/modules/spells/spell_types/demon.dm | 2 +- .../spells/spell_types/ethereal_jaunt.dm | 2 +- .../spells/spell_types/turf_teleport.dm | 2 +- code/modules/vehicles/atv.dm | 2 +- code/modules/vehicles/pimpin_ride.dm | 2 +- code/modules/vehicles/scooter.dm | 6 +++--- code/modules/vehicles/speedbike.dm | 4 ++-- code/modules/vehicles/vehicle.dm | 4 ++-- 41 files changed, 74 insertions(+), 56 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 44f9b0ba044..ec733786c1a 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -11,7 +11,7 @@ var/datum/reagents/reagents = null //This atom's HUD (med/sec, etc) images. Associative list. - var/list/image/hud_list = list() + var/list/image/hud_list = null //HUD images that this atom can provide. var/list/hud_possible diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 8d6d5705654..8472929b222 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -74,7 +74,7 @@ if(loc == newloc) //Remove this check and people can accelerate. Not opening that can of worms just yet. newtonian_move(last_move) - if(. && buckled_mobs.len && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s) + if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s) . = 0 //Called after a successful Move(). By this point, we've already moved @@ -137,7 +137,7 @@ stop_pulling() if(buckled) buckled.unbuckle_mob(src,force=1) - if(buckled_mobs.len) + if(has_buckled_mobs()) unbuckle_all_mobs(force=1) . = ..() if(client) diff --git a/code/game/gamemodes/clock_cult/clock_structures.dm b/code/game/gamemodes/clock_cult/clock_structures.dm index e6092eae7a2..2b91c1cbb67 100644 --- a/code/game/gamemodes/clock_cult/clock_structures.dm +++ b/code/game/gamemodes/clock_cult/clock_structures.dm @@ -461,7 +461,7 @@ /obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user) if(user.pulling && user.a_intent == "grab" && isliving(user.pulling)) var/mob/living/L = user.pulling - if(L.buckled || L.anchored || L.buckled_mobs.len) + if(L.buckled || L.anchored || L.has_buckled_mobs()) return 0 user.visible_message("[user] shoves [L] into [src]!", "You shove [L] into [src]!") user.stop_pulling() diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 41f37f98540..430cfb3552d 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -136,7 +136,7 @@ if(user.pulledby) user.pulledby.stop_pulling() user.stop_pulling() - if(user.buckled_mobs.len) + if(user.has_buckled_mobs()) user.unbuckle_all_mobs(force=1) sleep(40) //4 seconds if(!qdeleted(user)) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 7207a48eca0..fae51da8c58 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -177,11 +177,11 @@ Class Procs: density = 1 if(!target) for(var/mob/living/carbon/C in loc) - if(C.buckled || C.buckled_mobs.len) + if(C.buckled || C.has_buckled_mobs()) continue else target = C - if(target && !target.buckled && !target.buckled_mobs.len) + if(target && !target.buckled && !target.has_buckled_mobs()) occupant = target target.forceMove(src) updateUsrDialog() diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index f43d5b07698..1acadfa6173 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -226,7 +226,7 @@ if(user.pulling && user.a_intent == "grab" && isliving(user.pulling)) var/mob/living/L = user.pulling - if(L.buckled || L.buckled_mobs.len) + if(L.buckled || L.has_buckled_mobs()) return if(state_open) if(iscorgi(L)) diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index 732fdc85a09..4da9c5feb8e 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -77,7 +77,7 @@ if(target.buckled) occupant_message("[target] will not fit into the sleeper because they are buckled to [target.buckled]!") return - if(target.buckled_mobs.len) + if(target.has_buckled_mobs()) occupant_message("[target] will not fit into the sleeper because of the creatures attached to it!") return if(patient) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 5ab9bfc6618..5952e4bdca2 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -806,7 +806,7 @@ user << "You are currently buckled and cannot move." log_append_to_last("Permission denied.") return - if(user.buckled_mobs.len) //mob attached to us + if(user.has_buckled_mobs()) //mob attached to us user << "You can't enter the exosuit with other creatures attached to you!" return @@ -819,7 +819,7 @@ user << "[occupant] was faster! Try better next time, loser." else if(user.buckled) user << "You can't enter the exosuit while buckled." - else if(user.buckled_mobs.len) + else if(user.has_buckled_mobs()) user << "You can't enter the exosuit with other creatures attached to you!" else moved_inside(user) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 5e16e3f3bc7..46e675245a3 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -4,15 +4,13 @@ var/can_buckle = 0 var/buckle_lying = -1 //bed-like behaviour, forces mob.lying = buckle_lying if != -1 var/buckle_requires_restraints = 0 //require people to be handcuffed before being able to buckle. eg: pipes - var/list/mob/living/buckled_mobs = list() + var/list/mob/living/buckled_mobs = null //list() var/max_buckled_mobs = 1 - - //Interaction /atom/movable/attack_hand(mob/living/user) . = ..() - if(can_buckle && buckled_mobs.len) + if(can_buckle && has_buckled_mobs()) if(buckled_mobs.len > 1) var/unbuckled = input(user, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in buckled_mobs if(user_unbuckle_mob(unbuckled,user)) @@ -27,14 +25,23 @@ if(user_buckle_mob(M, user)) return 1 - //Cleanup /atom/movable/Destroy() . = ..() unbuckle_all_mobs(force=1) +/atom/movable/proc/has_buckled_mobs() + if(!buckled_mobs) + return FALSE + if(buckled_mobs.len) + return TRUE + //procs that handle the actual buckling and unbuckling /atom/movable/proc/buckle_mob(mob/living/M, force = 0) + if(!buckled_mobs) + buckled_mobs = list() + if(!M.buckled_mobs) + M.buckled_mobs = list() if((!can_buckle && !force) || !istype(M) || (M.loc != loc) || M.buckled || (M.buckled_mobs.len >= max_buckled_mobs) || (buckle_requires_restraints && !M.restrained()) || M == src) return 0 if(!M.can_buckle() && !force) @@ -72,6 +79,8 @@ post_buckle_mob(.) /atom/movable/proc/unbuckle_all_mobs(force=0) + if(!has_buckled_mobs()) + return for(var/m in buckled_mobs) unbuckle_mob(m, force) diff --git a/code/game/objects/items/weapons/airlock_painter.dm b/code/game/objects/items/weapons/airlock_painter.dm index b23e2d8ffaf..5d93623fa06 100644 --- a/code/game/objects/items/weapons/airlock_painter.dm +++ b/code/game/objects/items/weapons/airlock_painter.dm @@ -16,6 +16,7 @@ var/obj/item/device/toner/ink = null /obj/item/weapon/airlock_painter/New() + ..() ink = new /obj/item/device/toner(src) //This proc doesn't just check if the painter can be used, but also uses it. diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 899709fffa0..8e371776775 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -104,6 +104,7 @@ return(BRUTELOSS) /obj/item/weapon/screwdriver/New(loc, var/param_color = null) + ..() if(!icon_state) if(!param_color) param_color = pick("red","blue","pink","brown","green","cyan","yellow") diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm index afa7633b420..397db4429ab 100644 --- a/code/game/objects/structures/beds_chairs/alien_nest.dm +++ b/code/game/objects/structures/beds_chairs/alien_nest.dm @@ -18,7 +18,7 @@ return ..() /obj/structure/bed/nest/user_unbuckle_mob(mob/living/buckled_mob, mob/living/user) - if(buckled_mobs.len) + if(has_buckled_mobs()) for(var/buck in buckled_mobs) //breaking a nest releases all the buckled mobs, because the nest isn't holding them down anymore var/mob/living/M = buck @@ -60,7 +60,7 @@ if(!user.getorgan(/obj/item/organ/alien/plasmavessel)) return - if(buckled_mobs.len) + if(has_buckled_mobs()) unbuckle_all_mobs() if(buckle_mob(M)) diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index c9ef9d23e8d..f9e96c10e71 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -134,7 +134,7 @@ return var/obj/structure/bed/roller/R = target - if(R.buckled_mobs.len) + if(R.has_buckled_mobs()) if(R.buckled_mobs.len > 1) R.unbuckle_all_mobs() user.visible_message("[user] unbuckles all creatures from [R].") diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 5e0d0478354..c713a6abfbf 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -71,14 +71,14 @@ return ..() /obj/structure/chair/attack_tk(mob/user) - if(buckled_mobs.len) + if(has_buckled_mobs()) ..() else rotate() return /obj/structure/chair/proc/handle_rotation(direction) - if(buckled_mobs.len) + if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m buckled_mob.buckled = null //Temporary, so Move() succeeds. @@ -99,7 +99,7 @@ /obj/structure/chair/proc/spin() dir = turn(dir, 90) handle_layer() - if(buckled_mobs.len) + if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m buckled_mob.dir = dir @@ -167,7 +167,7 @@ return ..() /obj/structure/chair/comfy/post_buckle_mob(mob/living/M) - if(buckled_mobs.len) + if(has_buckled_mobs()) overlays += armrest else overlays -= armrest @@ -215,7 +215,7 @@ /obj/structure/chair/MouseDrop(over_object, src_location, over_location) . = ..() if(over_object == usr && Adjacent(usr)) - if(!item_chair || !ishuman(usr) || buckled_mobs.len || src.flags & NODECONSTRUCT) + if(!item_chair || !ishuman(usr) || has_buckled_mobs() || src.flags & NODECONSTRUCT) return if(usr.incapacitated()) usr << "You can't do that right now!" diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index ee5705a79d3..f7bad9cee77 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -141,7 +141,7 @@ if(!isliving(AM)) //let's not put ghosts or camera mobs inside closets... return var/mob/living/L = AM - if(L.anchored || L.buckled || L.incorporeal_move || L.buckled_mobs.len) + if(L.anchored || L.buckled || L.incorporeal_move || L.has_buckled_mobs()) return if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items. if(horizontal && L.density) @@ -160,7 +160,7 @@ return if(!allow_dense && AM.density) return - if(AM.anchored || AM.buckled_mobs.len || (AM.flags & NODROP)) + if(AM.anchored || AM.has_buckled_mobs() || (AM.flags & NODROP)) return else return diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index fbb7b66b47f..7d9b35adf16 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -37,7 +37,7 @@ var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(12, 1, src) s.start() - if(buckled_mobs.len) + if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m buckled_mob.electrocute_act(85, src, 1) diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index ddfd102d863..41c23a4748f 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -40,7 +40,7 @@ /obj/structure/kitchenspike/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/crowbar)) - if(!buckled_mobs.len) + if(!has_buckled_mobs()) playsound(loc, 'sound/items/Crowbar.ogg', 100, 1) if(do_after(user, 20/I.toolspeed, target = src)) user << "You pry the spikes out of the frame." @@ -57,7 +57,7 @@ if(user.pulling && isliving(user.pulling) && user.a_intent == "grab" && !buckled_mobs.len) var/mob/living/L = user.pulling if(do_mob(user, src, 120)) - if(buckled_mobs.len) //to prevent spam/queing up attacks + if(has_buckled_mobs()) //to prevent spam/queing up attacks return if(L.buckled) return diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index 69603d9c9ed..2580ac0a3d1 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -23,7 +23,7 @@ return prob(60) var/obj/structure/bed/B = A - if (istype(A, /obj/structure/bed) && (B.buckled_mobs.len || B.density))//if it's a bed/chair and is dense or someone is buckled, it will not pass + if (istype(A, /obj/structure/bed) && (B.has_buckled_mobs() || B.density))//if it's a bed/chair and is dense or someone is buckled, it will not pass return 0 if (istype(A, /obj/structure/closet/cardboard)) diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index 0f4e8e3f431..b6f79c129e2 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -64,13 +64,13 @@ if(icon_state == "open") var/mob/living/GM = user.pulling if(user.grab_state >= GRAB_AGGRESSIVE) - if(GM.buckled || GM.buckled_mobs.len) + if(GM.buckled || GM.has_buckled_mobs()) user << "[GM] is attached to something!" return for(var/obj/structure/transit_tube_pod/pod in loc) pod.visible_message("[user] starts putting [GM] into the [pod]!") if(do_after(user, 15, target = src)) - if(GM && user.grab_state >= GRAB_AGGRESSIVE && user.pulling == GM && !GM.buckled && !GM.buckled_mobs.len) + if(GM && user.grab_state >= GRAB_AGGRESSIVE && user.pulling == GM && !GM.buckled && !GM.has_buckled_mobs()) GM.Weaken(5) src.Bumped(GM) break diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm index 8b3c53864e2..d538c0bad44 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm @@ -46,7 +46,7 @@ //heatup/cooldown any mobs buckled to ourselves based on our temperature - if(buckled_mobs.len) + if(has_buckled_mobs()) var/hc = pipe_air.heat_capacity() var/mob/living/heat_source = buckled_mobs[1] //Best guess-estimate of the total bodytemperature of all the mobs, since they share the same environment it's ~ok~ to guess like this @@ -82,7 +82,7 @@ animate(src, color = rgb(h_r, h_g, h_b), time = 20, easing = SINE_EASING) //burn any mobs buckled based on temperature - if(buckled_mobs.len) + if(has_buckled_mobs()) var/heat_limit = 1000 if(pipe_air.temperature > heat_limit + 1) for(var/m in buckled_mobs) diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 7ffd3afefd5..8a61348e70a 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -19,6 +19,7 @@ burn_state = FIRE_PROOF /obj/item/clothing/gloves/color/fyellow/New() + ..() siemens_coefficient = pick(0,0.5,0.5,0.5,0.5,0.75,1.5) /obj/item/clothing/gloves/color/black @@ -182,6 +183,7 @@ item_color = "mime" /obj/item/clothing/gloves/color/random/New() + ..() var/list/gloves = list( /obj/item/clothing/gloves/color/orange = 1, /obj/item/clothing/gloves/color/red = 1, diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 2b8ae2a3455..3794875dd68 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -363,7 +363,7 @@ KZ.production = (master.spread_cap / initial(master.spread_cap)) * 50 mutations = list() SetOpacity(0) - if(buckled_mobs.len) + if(has_buckled_mobs()) unbuckle_all_mobs(force=1) return ..() @@ -540,7 +540,7 @@ SM.on_grow(src) /obj/effect/spacevine/proc/entangle_mob() - if(!buckled_mobs.len && prob(25)) + if(!has_buckled_mobs() && prob(25)) for(var/mob/living/V in src.loc) entangle(V) if(buckled_mobs.len) diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index 60ce3eda30f..8fe2aebbbde 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -102,7 +102,7 @@ user << "This item is not suitable for the gibber!" return var/mob/living/carbon/C = L - if(C.buckled ||C.buckled_mobs.len) + if(C.buckled ||C.has_buckled_mobs()) user << "[C] is attached to something!" return if(C.abiotic(1) && !ignore_clothing) @@ -112,7 +112,7 @@ user.visible_message("[user] starts to put [C] into the gibber!") src.add_fingerprint(user) if(do_after(user, gibtime, target = src)) - if(C && user.pulling == C && !C.buckled && !C.buckled_mobs.len && !occupant) + if(C && user.pulling == C && !C.buckled && !C.has_buckled_mobs() && !occupant) user.visible_message("[user] stuffs [C] into the gibber!") C.forceMove(src) occupant = C diff --git a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm index 6b2c96d505d..a0e86524ca9 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm @@ -72,7 +72,7 @@ if(target.stat == 0) user << "The monkey is struggling far too much to put it in the recycler." return - if(target.buckled || target.buckled_mobs.len) + if(target.buckled || target.has_buckled_mobs()) user << "The monkey is attached to something." return qdel(target) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index ae534acaf49..72e285a0a13 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -233,6 +233,7 @@ qdel(src) /obj/item/weapon/ore/New() + ..() pixel_x = rand(0,16)-8 pixel_y = rand(0,8)-8 @@ -259,6 +260,7 @@ var/value = 1 /obj/item/weapon/coin/New() + ..() pixel_x = rand(0,16)-8 pixel_y = rand(0,8)-8 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 2b03918b96d..5efb5c2032e 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -121,7 +121,7 @@ Sorry Giacom. Please don't be mad :( if(moving_diagonally)//no mob swap during diagonal moves. return 1 - if(!M.buckled && !M.buckled_mobs.len) + if(!M.buckled && !M.has_buckled_mobs()) var/mob_swap //the puller can always swap with its victim if on grab intent if(M.pulledby == src && a_intent == "grab") diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 857f93b8a63..26ae1fe74d8 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -357,7 +357,7 @@ var/global/mulebot_count = 0 if(isobj(AM)) var/obj/O = AM - if(O.buckled_mobs.len || (locate(/mob) in AM)) //can't load non crates objects with mobs buckled to it or inside it. + if(O.has_buckled_mobs() || (locate(/mob) in AM)) //can't load non crates objects with mobs buckled to it or inside it. buzz(SIGH) return diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 4cde8ce5c32..dc9793ae3ab 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -811,7 +811,7 @@ if(icon_state == "parrot_fly") for(var/mob/living/carbon/human/H in view(src,1)) - if(H.buckled_mobs.len >= H.max_buckled_mobs) //Already has a parrot, or is being eaten by a slime + if(H.has_buckled_mobs() && H.buckled_mobs.len >= H.max_buckled_mobs) //Already has a parrot, or is being eaten by a slime continue perch_on_human(H) return diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index c32a82c7865..d7daf9e2da3 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -15,7 +15,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/components/unary if(restrained()) src << "You can't vent crawl while you're restrained!" return - if(buckled_mobs.len) + if(has_buckled_mobs()) src << "You can't vent crawl with others creatures on you!" return if(buckled) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f9b5b4b161d..626b8b19c78 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -25,6 +25,7 @@ var/next_mob_id = 0 ..() /atom/proc/prepare_huds() + hud_list = list() for(var/hud in hud_possible) var/image/I = image('icons/mob/hud.dmi', src, "") I.appearance_flags = RESET_COLOR diff --git a/code/modules/recycling/disposal-unit.dm b/code/modules/recycling/disposal-unit.dm index df8325fea57..41402531b7c 100644 --- a/code/modules/recycling/disposal-unit.dm +++ b/code/modules/recycling/disposal-unit.dm @@ -120,7 +120,7 @@ return if(!istype(user.loc, /turf/)) //No magically doing it from inside closets return - if(target.buckled || target.buckled_mobs.len) + if(target.buckled || target.has_buckled_mobs()) return if(target.mob_size > MOB_SIZE_HUMAN) user << "[target] doesn't fit inside [src]!" diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 8422a2c96f1..39ad3fba504 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -588,6 +588,7 @@ var/cooldown /obj/item/weapon/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","illegal tech","weapon")]" diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index 9f8e6a580b5..9d79c5f1ced 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -71,6 +71,7 @@ var/rating = 1 /obj/item/weapon/stock_parts/New() + ..() src.pixel_x = rand(-5, 5) src.pixel_y = rand(-5, 5) diff --git a/code/modules/spells/spell_types/demon.dm b/code/modules/spells/spell_types/demon.dm index 12671cfffba..a4a258a9b40 100644 --- a/code/modules/spells/spell_types/demon.dm +++ b/code/modules/spells/spell_types/demon.dm @@ -145,7 +145,7 @@ src.ExtinguishMob() if(buckled) buckled.unbuckle_mob(src,force=1) - if(buckled_mobs.len) + if(has_buckled_mobs()) unbuckle_all_mobs(force=1) if(pulledby) pulledby.stop_pulling() diff --git a/code/modules/spells/spell_types/ethereal_jaunt.dm b/code/modules/spells/spell_types/ethereal_jaunt.dm index 9afa9929390..71b58883ddb 100644 --- a/code/modules/spells/spell_types/ethereal_jaunt.dm +++ b/code/modules/spells/spell_types/ethereal_jaunt.dm @@ -35,7 +35,7 @@ if(target.pulledby) target.pulledby.stop_pulling() target.stop_pulling() - if(target.buckled_mobs.len) + if(target.has_buckled_mobs()) target.unbuckle_all_mobs(force=1) jaunt_disappear(animation, target) target.loc = holder diff --git a/code/modules/spells/spell_types/turf_teleport.dm b/code/modules/spells/spell_types/turf_teleport.dm index d649c488967..0c473f67297 100644 --- a/code/modules/spells/spell_types/turf_teleport.dm +++ b/code/modules/spells/spell_types/turf_teleport.dm @@ -40,7 +40,7 @@ if(!target.Move(picked)) if(target.buckled) target.buckled.unbuckle_mob(target,force=1) - if(target.buckled_mobs.len) + if(target.has_buckled_mobs()) target.unbuckle_all_mobs(force=1) target.loc = picked playsound(get_turf(user), sound2, 50,1) diff --git a/code/modules/vehicles/atv.dm b/code/modules/vehicles/atv.dm index bf77878eae0..fbe44181235 100644 --- a/code/modules/vehicles/atv.dm +++ b/code/modules/vehicles/atv.dm @@ -18,7 +18,7 @@ obj/vehicle/atv/post_buckle_mob(mob/living/M) - if(buckled_mobs.len) + if(has_buckled_mobs()) overlays += atvcover else overlays -= atvcover diff --git a/code/modules/vehicles/pimpin_ride.dm b/code/modules/vehicles/pimpin_ride.dm index e0792514af8..b00bc315680 100644 --- a/code/modules/vehicles/pimpin_ride.dm +++ b/code/modules/vehicles/pimpin_ride.dm @@ -10,7 +10,7 @@ /obj/vehicle/janicart/handle_vehicle_offsets() ..() - if(buckled_mobs.len) + if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m switch(buckled_mob.dir) diff --git a/code/modules/vehicles/scooter.dm b/code/modules/vehicles/scooter.dm index e894e3c1c4a..49a36bf69e0 100644 --- a/code/modules/vehicles/scooter.dm +++ b/code/modules/vehicles/scooter.dm @@ -21,7 +21,7 @@ /obj/vehicle/scooter/handle_vehicle_offsets() ..() - if(buckled_mobs.len) + if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m switch(buckled_mob.dir) @@ -46,14 +46,14 @@ density = 0 /obj/vehicle/scooter/skateboard/post_buckle_mob(mob/living/M)//allows skateboards to be non-dense but still allows 2 skateboarders to collide with each other - if(buckled_mobs.len) + if(has_buckled_mobs()) density = 1 else density = 0 /obj/vehicle/scooter/skateboard/Bump(atom/A) ..() - if(A.density && buckled_mobs.len) + if(A.density && has_buckled_mobs()) var/mob/living/carbon/H = buckled_mobs[1] var/atom/throw_target = get_edge_target_turf(H, pick(cardinal)) unbuckle_mob(H) diff --git a/code/modules/vehicles/speedbike.dm b/code/modules/vehicles/speedbike.dm index 7602f9f4356..e9fa351f398 100644 --- a/code/modules/vehicles/speedbike.dm +++ b/code/modules/vehicles/speedbike.dm @@ -26,7 +26,7 @@ dir = move_dir /obj/vehicle/space/speedbike/Move(newloc,move_dir) - if(buckled_mobs.len) + if(has_buckled_mobs()) PoolOrNew(/obj/effect/overlay/temp/speedbike_trail,list(loc,move_dir)) . = ..() @@ -40,7 +40,7 @@ pixel_y = 0 /obj/vehicle/space/speedbike/handle_vehicle_offsets() - if(buckled_mobs.len) + if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m buckled_mob.dir = dir diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index 96582344dfc..32f0c0f886b 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -36,7 +36,7 @@ //if they differ between directions, otherwise use the //generic variables /obj/vehicle/proc/handle_vehicle_offsets() - if(buckled_mobs.len) + if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m buckled_mob.dir = dir @@ -123,7 +123,7 @@ /obj/vehicle/Bump(atom/movable/M) . = ..() if(auto_door_open) - if(istype(M, /obj/machinery/door) && buckled_mobs.len) + if(istype(M, /obj/machinery/door) && has_buckled_mobs()) for(var/m in buckled_mobs) M.Bumped(m) From 0e691081f853beb00fe7c2f0074233e462682324 Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 15:54:10 -0400 Subject: [PATCH 28/50] stats panel --- code/game/gamemodes/clock_cult/clock_mobs.dm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_mobs.dm b/code/game/gamemodes/clock_cult/clock_mobs.dm index c9caf1f975d..48e460dc319 100644 --- a/code/game/gamemodes/clock_cult/clock_mobs.dm +++ b/code/game/gamemodes/clock_cult/clock_mobs.dm @@ -37,7 +37,7 @@ /mob/living/simple_animal/hostile/anima_fragment/death(gibbed) ..(TRUE) visible_message("[src]'s flame jets cut out as it falls to the floor with a tremendous crash. A cube of metal tumbles out, whirring and sputtering.", \ - "Your gears seize up. Your flame jets flicker. Your soul vessel belches smoke as you helplessly crash down.") + "Your gears seize up. Your flame jets flicker out. Your soul vessel belches smoke as you helplessly crash down.") return 1 /mob/living/simple_animal/hostile/anima_fragment/Process_Spacemove(movement_dir = 0) @@ -176,6 +176,7 @@ resulthealth = round((abs(config.health_threshold_dead - host.health) / abs(config.health_threshold_dead - host.maxHealth)) * 100) stat(null, "Host Health: [resulthealth]%") stat(null, "You are [recovering ? "too weak" : "able"] to deploy!") + stat(null, "You do [melee_damage_upper] on melee attacks.") /mob/living/simple_animal/hostile/clockwork_marauder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) ..() @@ -313,7 +314,10 @@ if(!is_in_host()) return 0 if(recovering) - host << "[true_name] is too weak to come forth!" + if(hostchosen) + host << "[true_name] is too weak to come forth!" + else + host << "[true_name] tries to emerge to protect you, but it's too weak!" src << "You try to come forth, but you're too weak!" return 0 if(hostchosen) //marauder approved From b669940fdac5e7cd1d4a1ef481205794111cd350 Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 17:05:46 -0400 Subject: [PATCH 29/50] fixes a few machine bugs --- code/game/gamemodes/clock_cult/clock_machines.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_machines.dm b/code/game/gamemodes/clock_cult/clock_machines.dm index 36d0f44d123..81f017652de 100644 --- a/code/game/gamemodes/clock_cult/clock_machines.dm +++ b/code/game/gamemodes/clock_cult/clock_machines.dm @@ -95,7 +95,7 @@ while(sigilpower && amount >= 50) for(var/S in sigils_in_range) var/obj/effect/clockwork/sigil/transmission/T = S - if(T.modify_charge(50)) + if(amount >= 50 && T.modify_charge(50)) sigilpower -= 50 amount -= 50 var/apcpower = accessable_apc_power() @@ -448,7 +448,7 @@ /obj/structure/clockwork/powered/clockwork_obelisk/examine(mob/user) ..() if(is_servant_of_ratvar(user) || isobserver(user)) - user << "It requires [hierophant_cost]W to broadcast over the Hierophant Network, and [gateway_cost]W to open a Spatial Gateway." + user << "It requires [hierophant_cost]W to broadcast over the Hierophant Network, and [gateway_cost]W to open a Spatial Gateway." /obj/structure/clockwork/powered/clockwork_obelisk/process() if(locate(/obj/effect/clockwork/spatial_gateway) in loc) From d5667e076ebb995df5a218ee44148af63c90ed48 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Tue, 7 Jun 2016 21:09:41 +0000 Subject: [PATCH 30/50] Automatic changelog generation for PR #18279 [ci skip] --- html/changelogs/AutoChangeLog-pr-18279.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18279.yml diff --git a/html/changelogs/AutoChangeLog-pr-18279.yml b/html/changelogs/AutoChangeLog-pr-18279.yml new file mode 100644 index 00000000000..6f20acefae1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18279.yml @@ -0,0 +1,4 @@ +author: GunHog +delete-after: True +changes: + - rscadd: "Nanotrasen has approved the Hyper-Kenetic Accelerator upgrade for cyborg mining modules." From 6e64c697d7d211f42d02c5a11f1a03dcc293bbef Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 17:47:12 -0400 Subject: [PATCH 31/50] more fixes --- .../gamemodes/clock_cult/clock_machines.dm | 30 +++++++++++-------- .../gamemodes/clock_cult/clock_structures.dm | 2 +- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_machines.dm b/code/game/gamemodes/clock_cult/clock_machines.dm index 81f017652de..0468a0490d9 100644 --- a/code/game/gamemodes/clock_cult/clock_machines.dm +++ b/code/game/gamemodes/clock_cult/clock_machines.dm @@ -440,6 +440,7 @@ debris = list(/obj/item/clockwork/component/hierophant_ansible/obelisk) var/hierophant_cost = 50 //how much it costs to broadcast with large text var/gateway_cost = 2000 //how much it costs to open a gateway + var/gateway_active = FALSE /obj/structure/clockwork/powered/clockwork_obelisk/New() ..() @@ -454,9 +455,11 @@ if(locate(/obj/effect/clockwork/spatial_gateway) in loc) icon_state = active_icon density = 0 + gateway_active = TRUE else icon_state = inactive_icon density = 1 + gateway_active = FALSE /obj/structure/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user) if(!is_servant_of_ratvar(user) || !total_accessable_power() >= hierophant_cost) @@ -466,18 +469,21 @@ switch(choice) if("Hierophant Broadcast") var/input = stripped_input(usr, "Please choose a message to send over the Hierophant Network.", "Hierophant Broadcast", "") - if(user.canUseTopic(src, be_close = 1)) - if(try_use_power(hierophant_cost)) - user.say("Uvrebcunag Oebnqpnfg, npgvingr!") - send_hierophant_message(user, input, 1) - else - user << "The obelisk lacks the power to broadcast!" + if(!input || !user.canUseTopic(src, be_close = 1)) + return + if(!try_use_power(hierophant_cost)) + user << "The obelisk lacks the power to broadcast!" + return + user.say("Uvrebcunag Oebnqpnfg, npgvingr!") + send_hierophant_message(user, input, 1) if("Spatial Gateway") - if(total_accessable_power() >= gateway_cost) - if(procure_gateway(user, 100, 5, 1)) - user.say("Fcnpvny tngrjnl, npgvingr!") - try_use_power(gateway_cost) - else - user << "The obelisk lacks the power to open a gateway!" + if(!try_use_power(gateway_cost)) + user << "The obelisk lacks the power to open a gateway!" + return + if(gateway_active) + user << "The obelisk is already sustaining a gateway!" + return + if(procure_gateway(user, 100, 5, 1)) + user.say("Fcnpvny tngrjnl, npgvingr!") if("Cancel") return diff --git a/code/game/gamemodes/clock_cult/clock_structures.dm b/code/game/gamemodes/clock_cult/clock_structures.dm index e6092eae7a2..46a4324f498 100644 --- a/code/game/gamemodes/clock_cult/clock_structures.dm +++ b/code/game/gamemodes/clock_cult/clock_structures.dm @@ -529,7 +529,7 @@ animate(src, alpha = 0, time = 10) addtimer(src, "selfdel", 10) -/obj/effect/clockwerk/general_marker/proc/selfdel() +/obj/effect/clockwork/general_marker/proc/selfdel() qdel(src) /obj/effect/clockwork/general_marker/nezbere From 698210da020ac0244f686e8fdab4d9dca7fd375a Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 17:48:52 -0400 Subject: [PATCH 32/50] fixathon --- code/game/gamemodes/clock_cult/clock_structures.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/gamemodes/clock_cult/clock_structures.dm b/code/game/gamemodes/clock_cult/clock_structures.dm index 46a4324f498..8aee9dd4bcc 100644 --- a/code/game/gamemodes/clock_cult/clock_structures.dm +++ b/code/game/gamemodes/clock_cult/clock_structures.dm @@ -447,6 +447,7 @@ else sender = TRUE gatewayB.sender = FALSE + gatewayB.density = FALSE lifetime = set_duration gatewayB.lifetime = set_duration uses = set_uses From 55ac3ccb0fcc8c6fd3f3f47ffdf0c2e8f43c499c Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 17:54:42 -0400 Subject: [PATCH 33/50] all of the fixes --- code/game/gamemodes/clock_cult/clock_machines.dm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_machines.dm b/code/game/gamemodes/clock_cult/clock_machines.dm index 0468a0490d9..7d66fa962e9 100644 --- a/code/game/gamemodes/clock_cult/clock_machines.dm +++ b/code/game/gamemodes/clock_cult/clock_machines.dm @@ -468,21 +468,27 @@ var/choice = alert(user,"You place your hand on the obelisk...",,"Hierophant Broadcast","Spatial Gateway","Cancel") switch(choice) if("Hierophant Broadcast") + if(gateway_active) + user << "The obelisk is sustaining a gateway and cannot broadcast!" + return var/input = stripped_input(usr, "Please choose a message to send over the Hierophant Network.", "Hierophant Broadcast", "") if(!input || !user.canUseTopic(src, be_close = 1)) return + if(gateway_active) + user << "The obelisk is sustaining a gateway and cannot broadcast!" + return if(!try_use_power(hierophant_cost)) user << "The obelisk lacks the power to broadcast!" return user.say("Uvrebcunag Oebnqpnfg, npgvingr!") send_hierophant_message(user, input, 1) if("Spatial Gateway") - if(!try_use_power(gateway_cost)) - user << "The obelisk lacks the power to open a gateway!" - return if(gateway_active) user << "The obelisk is already sustaining a gateway!" return + if(!try_use_power(gateway_cost)) + user << "The obelisk lacks the power to open a gateway!" + return if(procure_gateway(user, 100, 5, 1)) user.say("Fcnpvny tngrjnl, npgvingr!") if("Cancel") From dc20a94dd29bebbd1e3f9a52516e4cc41278a20d Mon Sep 17 00:00:00 2001 From: Sawu Date: Wed, 8 Jun 2016 08:32:10 +1000 Subject: [PATCH 34/50] SNPC Updates (#18307) * SNPC Updates * SNPCs now use their custom processing by default, with a few tweaks. This is a temporary fix to ensure they work appropriately until @MrStonedOne's MC is in place. * SNPC custom processing will now watch for a failed loop and restart itself. * Verb added for debugging SNPCs easily, must be enabled. * SNPC customization now has three quick options, as well as the original choices. * Spawns removed from laggier parts of doProcess(), now using waitfor instead * Security SNPCs will target people set to arrest. * Chefs, Botanists and Bartenders should now function more appropriately. * Removes commented code * Fixes an invalid loop * REALLY fixes it this time --- code/modules/mob/interactive.dm | 171 ++++++++++++++++++++------------ 1 file changed, 107 insertions(+), 64 deletions(-) diff --git a/code/modules/mob/interactive.dm b/code/modules/mob/interactive.dm index 8c1c8ea5149..1bd3086e8ce 100644 --- a/code/modules/mob/interactive.dm +++ b/code/modules/mob/interactive.dm @@ -68,9 +68,10 @@ var/list/functions = list("nearbyscan","combat","shitcurity","chatter") var/restrictedJob = 0 var/shouldUseDynamicProc = 0 // switch to make the AI control it's own proccessing - var/alternateProcessing = 0 + var/alternateProcessing = 1 var/forceProcess = 0 - var/processTime = 10 + var/processTime = 8 + var/lastProc = 0 var/list/knownStrings = list() @@ -188,47 +189,82 @@ if(!istype(A,/mob/living/carbon/human/interactive)) return var/mob/living/carbon/human/interactive/T = A - var/cjob = input("Choose Job") as null|anything in SSjob.occupations - if(cjob) - T.myjob = cjob - T.job = T.myjob.title - for(var/obj/item/W in T) - qdel(W) - T.myjob.equip(T) - T.myjob.apply_fingerprints(T) - T.doSetup() - - var/shouldDoppel = input("Do you want the SNPC to disguise themself as a crewmember?") as null|anything in list("Yes","No") - if(shouldDoppel) - if(shouldDoppel == "Yes") - var/list/validchoices = list() - for(var/mob/living/carbon/human/M in mob_list) - validchoices += M - - var/mob/living/carbon/human/chosen = input("Which crewmember?") as null|anything in validchoices - - if(chosen) + var/choice = input("Customization Choices") as null|anything in list("Service NPC","Security NPC","Random","Custom") + if(choice) + if(choice == "Service NPC" || choice == "Security NPC") + var/job = choice == "Service NPC" ? pick("Bartender","Cook","Botanist","Janitor") : pick("Warden","Detective","Security Officer") + for(var/j in SSjob.occupations) + var/datum/job/J = j + if(J.title == job) + T.myjob = J + T.job = T.myjob.title + for(var/obj/item/W in T) + qdel(W) + T.myjob.equip(T) + T.myjob.apply_fingerprints(T) + T.doSetup() + break + if(choice == "Random") + T.myjob = pick(SSjob.occupations) + T.job = T.myjob.title + for(var/obj/item/W in T) + qdel(W) + T.myjob.equip(T) + T.myjob.apply_fingerprints(T) + T.doSetup() + if(prob(25)) + var/list/validchoices = list() + for(var/mob/living/carbon/human/M in mob_list) + validchoices += M + var/mob/living/carbon/human/chosen = pick(validchoices) var/datum/dna/toDoppel = chosen.dna - T.real_name = toDoppel.real_name toDoppel.transfer_identity(T, transfer_SE=1) T.updateappearance(mutcolor_update=1) T.domutcheck() - - var/doTrait = input("Do you want the SNPC to be a traitor?") as null|anything in list("Yes","No") - if(doTrait) - if(doTrait == "Yes") - var/list/tType = list("Brute" = SNPC_BRUTE, "Stealth" = SNPC_STEALTH, "Martyr" = SNPC_MARTYR, "Psycho" = SNPC_PSYCHO) - var/cType = input("Choose the traitor personality.") as null|anything in tType - if(cType) - var/value = tType[cType] - T.makeTraitor(value) - - var/doTele = input("Place the SNPC in their department?") as null|anything in list("Yes","No") - if(doTele) - if(doTele == "Yes") + if(prob(25)) + var/cType = pick(list(SNPC_BRUTE,SNPC_STEALTH,SNPC_MARTYR,SNPC_PSYCHO)) + T.makeTraitor(cType) T.loc = pick(get_area_turfs(T.job2area(T.myjob))) + if(choice == "Custom") + var/cjob = input("Choose Job") as null|anything in SSjob.occupations + if(cjob) + T.myjob = cjob + T.job = T.myjob.title + for(var/obj/item/W in T) + qdel(W) + T.myjob.equip(T) + T.myjob.apply_fingerprints(T) + T.doSetup() + var/shouldDoppel = input("Do you want the SNPC to disguise themself as a crewmember?") as null|anything in list("Yes","No") + if(shouldDoppel) + if(shouldDoppel == "Yes") + var/list/validchoices = list() + for(var/mob/living/carbon/human/M in mob_list) + validchoices += M + + var/mob/living/carbon/human/chosen = input("Which crewmember?") as null|anything in validchoices + + if(chosen) + var/datum/dna/toDoppel = chosen.dna + + T.real_name = toDoppel.real_name + toDoppel.transfer_identity(T, transfer_SE=1) + T.updateappearance(mutcolor_update=1) + T.domutcheck() + var/doTrait = input("Do you want the SNPC to be a traitor?") as null|anything in list("Yes","No") + if(doTrait) + if(doTrait == "Yes") + var/list/tType = list("Brute" = SNPC_BRUTE, "Stealth" = SNPC_STEALTH, "Martyr" = SNPC_MARTYR, "Psycho" = SNPC_PSYCHO) + var/cType = input("Choose the traitor personality.") as null|anything in tType + if(cType) + var/value = tType[cType] + T.makeTraitor(value) + var/doTele = input("Place the SNPC in their department?") as null|anything in list("Yes","No") + if(doTele) + if(doTele == "Yes") + T.loc = pick(get_area_turfs(T.job2area(T.myjob))) /mob/living/carbon/human/interactive/proc/doSetup() Path_ID = new /obj/item/weapon/card/id(src) @@ -500,7 +536,7 @@ ..() if(ticker.current_state == GAME_STATE_FINISHED) saveVoice() - if(!alternateProcessing || forceProcess) + if(!alternateProcessing || forceProcess || world.time > lastProc + processTime) doProcess() /mob/living/carbon/human/interactive/death() @@ -513,7 +549,9 @@ ..() /mob/living/carbon/human/interactive/proc/doProcess() + set waitfor = 0 forceProcess = 0 + lastProc = world.time if(shouldUseDynamicProc) var/isSeen = 0 @@ -540,31 +578,29 @@ //VIEW FUNCTIONS //doorscan is now integrated into life and runs before all other procs - spawn(0) - for(var/dir in alldirs) - var/turf/T = get_step(src,dir) - if(T) - for(var/obj/machinery/door/D in T.contents) - if(!istype(D,/obj/machinery/door/poddoor) && D.density) - spawn(0) - if(istype(D,/obj/machinery/door/airlock)) - var/obj/machinery/door/airlock/AL = D - if(!AL.CanAStarPass(RPID)) // only crack open doors we can't get through - AL.panel_open = 1 - AL.update_icon() - AL.shock(src,(100 - smartness)/2) - sleep(5) - AL.unbolt() - if(!AL.wires.is_cut(WIRE_BOLTS)) - AL.wires.cut(WIRE_BOLTS) - if(!AL.wires.is_cut(WIRE_POWER1)) - AL.wires.cut(WIRE_POWER1) - if(!AL.wires.is_cut(WIRE_POWER2)) - AL.wires.cut(WIRE_POWER2) - sleep(5) - AL.panel_open = 0 - AL.update_icon() - D.open() + for(var/dir in alldirs) + var/turf/T = get_step(src,dir) + if(T) + for(var/obj/machinery/door/D in T.contents) + if(!istype(D,/obj/machinery/door/poddoor) && D.density) + if(istype(D,/obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/AL = D + if(!AL.CanAStarPass(RPID)) // only crack open doors we can't get through + AL.panel_open = 1 + AL.update_icon() + AL.shock(src,(100 - smartness)/2) + sleep(5) + AL.unbolt() + if(!AL.wires.is_cut(WIRE_BOLTS)) + AL.wires.cut(WIRE_BOLTS) + if(!AL.wires.is_cut(WIRE_POWER1)) + AL.wires.cut(WIRE_POWER1) + if(!AL.wires.is_cut(WIRE_POWER2)) + AL.wires.cut(WIRE_POWER2) + sleep(5) + AL.panel_open = 0 + AL.update_icon() + D.open() if(update_hands) if(l_hand || r_hand) @@ -611,7 +647,7 @@ var/obj/machinery/door/D = TARGET if(D.check_access(MYID) && !istype(D,/obj/machinery/door/poddoor)) D.open() - sleep(15) + //sleep(15) var/turf/T = get_step(get_step(D.loc,dir),dir) //recursion yo tryWalk(T) //THIEVING SKILLS @@ -1086,6 +1122,14 @@ /mob/living/carbon/human/interactive/proc/shitcurity(obj) var/list/allContents = getAllContents() + for(var/mob/living/carbon/human/C in nearby) + var/perpname = C.get_face_name(C.get_id_name()) + var/datum/data/record/R = find_record("name", perpname, data_core.security) + if(R && R.fields["criminal"]) + switch(R.fields["criminal"]) + if("*Arrest*") + retalTarget(C) + if(retal && TARGET) for(var/obj/item/I in allContents) if(istype(I,/obj/item/weapon/restraints)) @@ -1411,7 +1455,6 @@ return hasSame /mob/living/carbon/human/interactive/proc/combat(obj) - set background = 1 enforce_hands() if(canmove) if((graytide || (TRAITS & TRAIT_MEAN)) || retal) From b28da9cb97062223ecbd74c008d52361e62e1789 Mon Sep 17 00:00:00 2001 From: PKPenguin321 Date: Tue, 7 Jun 2016 16:09:25 -0700 Subject: [PATCH 35/50] Adds emag functions to chem dispensers (#18153) * adds emag functions to chem dispensers * chemical changes, slight code changes * fixes multiple emagging --- .../chemistry/machinery/chem_dispenser.dm | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 38da68a18ad..70c15075a71 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -43,6 +43,13 @@ "bromine", "stable_plasma" ) + var/list/emagged_reagents = list( + "space_drugs", + "morphine", + "carpotoxin", + "mine_salve", + "toxin" + ) /obj/machinery/chem_dispenser/New() ..() @@ -65,6 +72,14 @@ if(energy != oldenergy) use_power(2500) +/obj/machinery/chem_dispenser/emag_act(mob/user) + if(emagged) + user << "\The [src] has no functional safeties to emag." + return + user << "You short out \the [src]'s safeties." + dispensable_reagents |= emagged_reagents//add the emagged reagents to the dispensable ones + emagged = 1 + /obj/machinery/chem_dispenser/ex_act(severity, target) if(severity < 3) ..() @@ -165,7 +180,7 @@ icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. icon_beaker.pixel_x = rand(-10,5) overlays += icon_beaker - else if(user.a_intent != "harm") + else if(user.a_intent != "harm" && !istype(I, /obj/item/weapon/card/emag)) user << "You can't load \the [I] into the machine!" else return ..() @@ -296,6 +311,13 @@ "tomatojuice", "lemonjuice" ) + emagged_reagents = list( + "thirteenloko", + "whiskeycola", + "mindbreaker", + "tirizene" + ) + /obj/machinery/chem_dispenser/drinks/beer @@ -318,8 +340,16 @@ "ale", "absinthe" ) + emagged_reagents = list( + "ethanol", + "iron", + "minttoxin", + "atomicbomb" + ) + /obj/machinery/chem_dispenser/mutagen name = "mutagen dispenser" desc = "Creates and dispenses mutagen." - dispensable_reagents = list("mutagen") \ No newline at end of file + dispensable_reagents = list("mutagen") + emagged_reagents = list("plasma") From c9b9c81f9b2ea2c1aa761b7683a6f520a418d021 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Tue, 7 Jun 2016 23:09:26 +0000 Subject: [PATCH 36/50] Automatic changelog generation for PR #18153 [ci skip] --- html/changelogs/AutoChangeLog-pr-18153.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18153.yml diff --git a/html/changelogs/AutoChangeLog-pr-18153.yml b/html/changelogs/AutoChangeLog-pr-18153.yml new file mode 100644 index 00000000000..e7fcbfd66bf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18153.yml @@ -0,0 +1,4 @@ +author: PKPenguin321 +delete-after: True +changes: + - rscadd: "You can now emag chemical dispensers, such as the ones in chemistry or the bar, to unlock illegal chemicals." From 5259e73f4dc9eab8dda3301a06a0b6f14ec247bd Mon Sep 17 00:00:00 2001 From: Cruix Date: Tue, 7 Jun 2016 19:17:39 -0400 Subject: [PATCH 37/50] Fixes changelings readapting while in stasis removing the regenerate verb. (#18317) --- code/game/gamemodes/changeling/changeling_power.dm | 1 + code/game/gamemodes/changeling/evolution_menu.dm | 2 +- code/game/gamemodes/changeling/powers/revive.dm | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/changeling/changeling_power.dm b/code/game/gamemodes/changeling/changeling_power.dm index bdd7fc1ac7c..a94b5bb707b 100644 --- a/code/game/gamemodes/changeling/changeling_power.dm +++ b/code/game/gamemodes/changeling/changeling_power.dm @@ -15,6 +15,7 @@ var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD var/genetic_damage = 0 // genetic damage caused by using the sting. Nothing to do with cloneloss. var/max_genetic_damage = 100 // hard counter for spamming abilities. Not used/balanced much yet. + var/always_keep = 0 // important for abilities like regenerate that screw you if you lose them. /obj/effect/proc_holder/changeling/proc/on_purchase(mob/user) diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm index 7aa3a7c0d5c..e3166c231aa 100644 --- a/code/game/gamemodes/changeling/evolution_menu.dm +++ b/code/game/gamemodes/changeling/evolution_menu.dm @@ -392,7 +392,7 @@ var/list/sting_paths mind.changeling.changeling_speak = 0 mind.changeling.reset() for(var/obj/effect/proc_holder/changeling/p in mind.changeling.purchasedpowers) - if(p.dna_cost == 0 && keep_free_powers) + if((p.dna_cost == 0 && keep_free_powers) || p.always_keep) continue mind.changeling.purchasedpowers -= p p.on_refund(src) diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index a68f62a4747..b6a7b4eac30 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -2,6 +2,7 @@ name = "Regenerate" desc = "We regenerate, healing all damage from our form." req_stat = DEAD + always_keep = 1 //Revive from revival stasis /obj/effect/proc_holder/changeling/revive/sting_action(mob/living/carbon/user) From b27d5ea38a82c0ba17c10a6ac687c19a3ca495ea Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Tue, 7 Jun 2016 23:17:40 +0000 Subject: [PATCH 38/50] Automatic changelog generation for PR #18317 [ci skip] --- html/changelogs/AutoChangeLog-pr-18317.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18317.yml diff --git a/html/changelogs/AutoChangeLog-pr-18317.yml b/html/changelogs/AutoChangeLog-pr-18317.yml new file mode 100644 index 00000000000..c04caeffd5d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18317.yml @@ -0,0 +1,4 @@ +author: Cruix +delete-after: True +changes: + - bugfix: "Changelings no longer lose the regenerate ability if they respect while in regenerative stasis." From cf27511dc98c3084e25d5f7d659d9bb781f73ac0 Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 7 Jun 2016 22:29:47 -0300 Subject: [PATCH 39/50] Bar stool FIGHTS (#18325) --- .../objects/structures/beds_chairs/chair.dm | 8 +++++++- icons/mob/inhands/items_lefthand.dmi | Bin 115379 -> 115752 bytes icons/mob/inhands/items_righthand.dmi | Bin 115629 -> 115856 bytes 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 5e0d0478354..85c2246d9e6 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -229,7 +229,7 @@ name = "bar stool" desc = "It has some unsavory stains on it..." icon_state = "bar" - item_chair = null + item_chair = /obj/item/chair/stool/bar /obj/item/chair name = "chair" @@ -310,6 +310,12 @@ origin_type = /obj/structure/chair/stool break_chance = 0 //It's too sturdy. +/obj/item/chair/stool/bar + name = "bar stool" + icon_state = "bar" + item_state = "stool_bar" + origin_type = /obj/structure/chair/stool + /obj/item/chair/stool/narsie_act() return //sturdy enough to ignore a god diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index cd5cd3df688966fa346af28260f485a6e0d2f50d..9b59c86f6de7d4ef77d3b38f793ffe18dbd713fb 100644 GIT binary patch delta 13821 zcmY*<1z1!~+wf8nij;uTp`e6FHw%)264JG(bazP{q(e#+q+6P$I}{Y8o29$EV_Dem z@I3GP{?~u5>&%%sQ+LhG9a9;En;(iB^BCiK>=Q=d)2<^$Bd(EK9BuFWI{~xwgHOMV z&6<|$(p2bGptjEkzi{HjUVIKB!N#YH=!-7=cp84=c{*U-qYXl1E|kk2P}Wt5}F+T47PT^MXli6;fsc8m zHP;_?d~5tSDHMuW%nAeCHBxF7>TI^onHK#&`yEW|Wiy*Ma~(RlSS-KiM){q>6!|f= z0PIrDFK<%r(Z5GBZDNs$E$C>Q{Vee4wvCJ30xSx5nfI8-hDa7peR4$P9(A0V$zrx} z4}T45o0;pCLY}2C=PsC{g5Ic4 zET4lrF7y8T70Q`4+#j7Kb~(HAEI$vEtz3}9UT@9+?IJUgvdJ)3tGKSeAhA3!hbmvEQ}1xRmDovcslt7Dw{6DyOzAT>V~T zz)U)M*S<0KS;j?!%8QzWHq|a~NR7|B&aY7)0)I7gD3jhg?`5Pq&I!MAz&jsmfTL7D zQ$)l{JI77{`jYXKpg7>nSylcH voW#;aAP=z|q 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 delta 13448 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 Date: Tue, 7 Jun 2016 22:10:40 -0400 Subject: [PATCH 40/50] i'm glad i caught that it might have been bad --- code/game/gamemodes/clock_cult/clock_cult.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 1b5ba911440..6f61520ef2a 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -51,7 +51,6 @@ This file's folder contains: Justiciar, lies in exile, derelict and forgotten in an unseen realm." if(!is_eligible_servant(M)) M.visible_message("[M] seems to resist an unseen force!", "And yet, you somehow push it all away.") - return 0 else if(issilicon(M)) if(!silent) M << "You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, lies in \ @@ -59,12 +58,12 @@ This file's folder contains: if(!is_eligible_servant(M)) M.visible_message("[M] whirs as it resists an outside influence!", \ "Corrupt data purged. Resetting cortex chip to factory defaults... complete.") - return 0 else if(!silent) M << "Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm." if(!is_eligible_servant(M)) M.visible_message("[M] seems to resist an unseen force!", "And yet, you somehow push it all away.") - return 0 + if(!is_eligible_servant(M)) + return 0 if(!silent) M.visible_message("[M]'s eyes glow a blazing yellow!", \ "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \ From 2acdf638a7f54164c06746d28370b52c36624ccb Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 22:49:08 -0400 Subject: [PATCH 41/50] a one character fix --- code/game/gamemodes/clock_cult/clock_machines.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/clock_cult/clock_machines.dm b/code/game/gamemodes/clock_cult/clock_machines.dm index 7d66fa962e9..da6b4bd14b1 100644 --- a/code/game/gamemodes/clock_cult/clock_machines.dm +++ b/code/game/gamemodes/clock_cult/clock_machines.dm @@ -490,6 +490,6 @@ user << "The obelisk lacks the power to open a gateway!" return if(procure_gateway(user, 100, 5, 1)) - user.say("Fcnpvny tngrjnl, npgvingr!") + user.say("Fcnpvny Tngrjnl, npgvingr!") if("Cancel") return From 704c89ae0237de7503bd22360769598c84e89958 Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 22:59:20 -0400 Subject: [PATCH 42/50] hellish style choices --- code/game/gamemodes/clock_cult/clock_cult.dm | 10 ++++++---- code/game/gamemodes/clock_cult/clock_structures.dm | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 6f61520ef2a..86340e1dfbb 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -51,6 +51,7 @@ This file's folder contains: Justiciar, lies in exile, derelict and forgotten in an unseen realm." if(!is_eligible_servant(M)) M.visible_message("[M] seems to resist an unseen force!", "And yet, you somehow push it all away.") + return 0 else if(issilicon(M)) if(!silent) M << "You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, lies in \ @@ -58,12 +59,13 @@ This file's folder contains: if(!is_eligible_servant(M)) M.visible_message("[M] whirs as it resists an outside influence!", \ "Corrupt data purged. Resetting cortex chip to factory defaults... complete.") - else if(!silent) - M << "Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm." + return 0 + else + if(!silent) + M << "Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm." if(!is_eligible_servant(M)) M.visible_message("[M] seems to resist an unseen force!", "And yet, you somehow push it all away.") - if(!is_eligible_servant(M)) - return 0 + return 0 if(!silent) M.visible_message("[M]'s eyes glow a blazing yellow!", \ "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \ diff --git a/code/game/gamemodes/clock_cult/clock_structures.dm b/code/game/gamemodes/clock_cult/clock_structures.dm index 8aee9dd4bcc..e24afbecfa3 100644 --- a/code/game/gamemodes/clock_cult/clock_structures.dm +++ b/code/game/gamemodes/clock_cult/clock_structures.dm @@ -481,6 +481,7 @@ qdel(src) return 1 if(user.drop_item()) + user.visible_message("[user] drops [I] into [src]!", "You drop [I] into [src]!" pass_through_gateway(I) ..() From 21945f55096729b72bd0181d92ed46286f320ca2 Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Tue, 7 Jun 2016 23:09:53 -0400 Subject: [PATCH 43/50] ) --- code/game/gamemodes/clock_cult/clock_structures.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/clock_cult/clock_structures.dm b/code/game/gamemodes/clock_cult/clock_structures.dm index e24afbecfa3..6551ae1d498 100644 --- a/code/game/gamemodes/clock_cult/clock_structures.dm +++ b/code/game/gamemodes/clock_cult/clock_structures.dm @@ -481,7 +481,7 @@ qdel(src) return 1 if(user.drop_item()) - user.visible_message("[user] drops [I] into [src]!", "You drop [I] into [src]!" + user.visible_message("[user] drops [I] into [src]!", "You drop [I] into [src]!") pass_through_gateway(I) ..() From 3af3bd29382cdd67484b9e193128632b9232e85e Mon Sep 17 00:00:00 2001 From: Core0verload Date: Wed, 8 Jun 2016 08:18:22 +0300 Subject: [PATCH 44/50] R&D machinery refactor (#18295) * RnD machinery refactor * Small changes * Removed designs selling --- code/__HELPERS/global_lists.dm | 12 +- code/_globalvars/lists/objects.dm | 2 + code/datums/material_container.dm | 77 +-- code/game/machinery/autolathe.dm | 23 +- code/game/machinery/droneDispenser.dm | 2 +- code/game/machinery/machinery.dm | 1 + code/game/machinery/recycler.dm | 2 +- code/game/mecha/mech_fabricator.dm | 253 +++---- code/modules/cargo/exports/research.dm | 24 - code/modules/clothing/shoes/bananashoes.dm | 2 +- code/modules/research/circuitprinter.dm | 90 ++- .../research/designs/AI_module_designs.dm | 73 +-- .../research/designs/comp_board_designs.dm | 156 ++--- .../research/designs/machine_designs.dm | 195 ++---- .../modules/research/designs/mecha_designs.dm | 69 +- .../modules/research/designs/power_designs.dm | 14 +- .../research/designs/telecomms_designs.dm | 28 +- .../research/designs/weapon_designs.dm | 10 +- code/modules/research/protolathe.dm | 26 +- code/modules/research/rdconsole.dm | 615 ++++++++---------- code/modules/research/rdmachines.dm | 11 +- code/modules/research/research.dm | 18 +- 22 files changed, 653 insertions(+), 1050 deletions(-) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index f77e0cf5300..65cef4fbc43 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -38,9 +38,19 @@ species_list[S.id] = S.type //Surgeries - for(var/path in (subtypesof(/datum/surgery))) + for(var/path in subtypesof(/datum/surgery)) surgeries_list += new path() + //Materials + for(var/path in subtypesof(/datum/material)) + var/datum/material/D = new path() + materials_list[D.id] = D + + //Techs + for(var/path in subtypesof(/datum/tech)) + var/datum/tech/D = new path() + tech_list[D.id] = D + init_subtypes(/datum/crafting_recipe, crafting_recipes) /* // Uncomment to debug chemical reaction list. diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index b7bf9169fe3..8f1775261d5 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -13,6 +13,8 @@ var/global/list/nuke_tiles = list() //list of all turfs that turn to animate var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions var/global/list/chemical_reagents_list //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff +var/global/list/materials_list = list() //list of all /datum/material datums indexed by material id. +var/global/list/tech_list = list() //list of all /datum/tech datums indexed by id. var/global/list/surgeries_list = list() //list of all surgeries by name, associated with their path. var/global/list/crafting_recipes = list() //list of all table craft recipes var/global/list/rcd_list = list() //list of Rapid Construction Devices. diff --git a/code/datums/material_container.dm b/code/datums/material_container.dm index 41baa00796e..ed6f375b6f6 100644 --- a/code/datums/material_container.dm +++ b/code/datums/material_container.dm @@ -22,33 +22,26 @@ owner = O max_amount = max(0, max_amt) - if(mat_list[MAT_METAL]) - materials[MAT_METAL] = new /datum/material/metal() - if(mat_list[MAT_GLASS]) - materials[MAT_GLASS] = new /datum/material/glass() - if(mat_list[MAT_SILVER]) - materials[MAT_SILVER] = new /datum/material/silver() - if(mat_list[MAT_GOLD]) - materials[MAT_GOLD] = new /datum/material/gold() - if(mat_list[MAT_DIAMOND]) - materials[MAT_DIAMOND] = new /datum/material/diamond() - if(mat_list[MAT_URANIUM]) - materials[MAT_URANIUM] = new /datum/material/uranium() - if(mat_list[MAT_PLASMA]) - materials[MAT_PLASMA] = new /datum/material/plasma() - if(mat_list[MAT_BANANIUM]) - materials[MAT_BANANIUM] = new /datum/material/bananium() + var/list/possible_mats = list() + for(var/mat_type in subtypesof(/datum/material)) + var/datum/material/MT = mat_type + possible_mats[initial(MT.id)] = mat_type + + for(var/id in mat_list) + if(possible_mats[id]) + var/mat_path = possible_mats[id] + materials[id] = new mat_path() /datum/material_container/Destroy() owner = null return ..() //For inserting an amount of material -/datum/material_container/proc/insert_amount(amt, material_type = null) +/datum/material_container/proc/insert_amount(amt, id = null) if(amt > 0 && has_space(amt)) var/total_amount_saved = total_amount - if(material_type) - var/datum/material/M = materials[material_type] + if(id) + var/datum/material/M = materials[id] if(M) M.amount += amt total_amount += amt @@ -120,8 +113,8 @@ return total_amount_save - total_amount -/datum/material_container/proc/use_amount_type(amt, material_type) - var/datum/material/M = materials[material_type] +/datum/material_container/proc/use_amount_type(amt, id) + var/datum/material/M = materials[id] if(M) if(M.amount >= amt) M.amount -= amt @@ -129,9 +122,9 @@ return amt return 0 -/datum/material_container/proc/can_use_amount(amt, material_type, list/mats) - if(amt && material_type) - var/datum/material/M = materials[material_type] +/datum/material_container/proc/can_use_amount(amt, id, list/mats) + if(amt && id) + var/datum/material/M = materials[id] if(M && M.amount >= amt) return TRUE else if(istype(mats)) @@ -153,23 +146,23 @@ while(sheet_amt > MAX_STACK_SIZE) new M.sheet_type(get_turf(owner), MAX_STACK_SIZE) count += MAX_STACK_SIZE - use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.material_type) + use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id) sheet_amt -= MAX_STACK_SIZE if(round(M.amount / MINERAL_MATERIAL_AMOUNT)) new M.sheet_type(get_turf(owner), sheet_amt) count += sheet_amt - use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.material_type) + use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id) return count return 0 -/datum/material_container/proc/retrieve_sheets(sheet_amt, material_type) - if(materials[material_type]) - return retrieve(sheet_amt, materials[material_type]) +/datum/material_container/proc/retrieve_sheets(sheet_amt, id) + if(materials[id]) + return retrieve(sheet_amt, materials[id]) return 0 -/datum/material_container/proc/retrieve_amount(amt, material_type) - return retrieve_sheets(amount2sheet(amt),material_type) +/datum/material_container/proc/retrieve_amount(amt, id) + return retrieve_sheets(amount2sheet(amt), id) /datum/material_container/proc/retrieve_all() var/result = 0 @@ -203,8 +196,8 @@ return sheet_amt * MINERAL_MATERIAL_AMOUNT return 0 -/datum/material_container/proc/amount(material_type) - var/datum/material/M = materials[material_type] +/datum/material_container/proc/amount(id) + var/datum/material/M = materials[id] return M ? M.amount : 0 //returns the amount of material relevant to this container; @@ -221,45 +214,45 @@ /datum/material var/name var/amount = 0 - var/material_type = null + var/id = null var/sheet_type = null /datum/material/metal name = "Metal" - material_type = MAT_METAL + id = MAT_METAL sheet_type = /obj/item/stack/sheet/metal /datum/material/glass name = "Glass" - material_type = MAT_GLASS + id = MAT_GLASS sheet_type = /obj/item/stack/sheet/glass /datum/material/silver name = "Silver" - material_type = MAT_SILVER + id = MAT_SILVER sheet_type = /obj/item/stack/sheet/mineral/silver /datum/material/gold name = "Gold" - material_type = MAT_GOLD + id = MAT_GOLD sheet_type = /obj/item/stack/sheet/mineral/gold /datum/material/diamond name = "Diamond" - material_type = MAT_DIAMOND + id = MAT_DIAMOND sheet_type = /obj/item/stack/sheet/mineral/diamond /datum/material/uranium name = "Uranium" - material_type = MAT_URANIUM + id = MAT_URANIUM sheet_type = /obj/item/stack/sheet/mineral/uranium /datum/material/plasma name = "Solid Plasma" - material_type = MAT_PLASMA + id = MAT_PLASMA sheet_type = /obj/item/stack/sheet/mineral/plasma /datum/material/bananium name = "Bananium" - material_type = MAT_BANANIUM + id = MAT_BANANIUM sheet_type = /obj/item/stack/sheet/mineral/bananium diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 3aafdb2b324..53e482f751f 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -47,7 +47,7 @@ /obj/machinery/autolathe/New() ..() - materials = new /datum/material_container(src, list(MAT_METAL=1, MAT_GLASS=1)) + materials = new /datum/material_container(src, list(MAT_METAL, MAT_GLASS)) var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/autolathe(null) B.apply_default_parts(src) @@ -244,7 +244,7 @@ return /obj/machinery/autolathe/RefreshParts() - var/T =1.2 + var/T = 0 for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) T += MB.rating*75000 materials.max_amount = T @@ -255,9 +255,7 @@ /obj/machinery/autolathe/proc/main_win(mob/user) var/dat = "Options: " dat += "Deconstruct Item" @@ -831,22 +802,15 @@ proc/CallMaterialName(ID) var/temp_material var/c = 50 var/t - for(var/M in D.materials) + + var/all_materials = D.materials + D.reagents + for(var/M in all_materials) t = linked_lathe.check_mat(D, M) temp_material += " | " if (t < 1) - temp_material += "[D.materials[M]*coeff] [CallMaterialName(M)]" + temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" else - temp_material += " [D.materials[M]*coeff] [CallMaterialName(M)]" - c = min(c,t) - - for(var/R in D.reagents) - t = linked_lathe.check_mat(D, R) - temp_material += " | " - if (t < 1) - temp_material += "[D.reagents[R]*coeff] [CallMaterialName(R)]" - else - temp_material += " [D.reagents[R]*coeff] [CallMaterialName(R)]" + temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" c = min(c,t) if (c >= 1) @@ -898,61 +862,16 @@ proc/CallMaterialName(ID) dat += "Main Menu" dat += "Protolathe Menu
" dat += "

Material Storage:



" - //Metal - var/m_amount = linked_lathe.materials.amount(MAT_METAL) - dat += "* [m_amount] of Metal: " - if(m_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(m_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(m_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Glass - var/g_amount = linked_lathe.materials.amount(MAT_GLASS) - dat += "* [g_amount] of Glass: " - if(g_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(g_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(g_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Gold - var/gold_amount = linked_lathe.materials.amount(MAT_GOLD) - dat += "* [gold_amount] of Gold: " - if(gold_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(gold_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(gold_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Silver - var/silver_amount = linked_lathe.materials.amount(MAT_SILVER) - dat += "* [silver_amount] of Silver: " - if(silver_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(silver_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(silver_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Plasma - var/plasma_amount = linked_lathe.materials.amount(MAT_PLASMA) - dat += "* [plasma_amount] of Solid Plasma: " - if(plasma_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(plasma_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(plasma_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Uranium - var/uranium_amount = linked_lathe.materials.amount(MAT_URANIUM) - dat += "* [uranium_amount] of Uranium: " - if(uranium_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(uranium_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(uranium_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Diamond - var/diamond_amount = linked_lathe.materials.amount(MAT_DIAMOND) - dat += "* [diamond_amount] of Diamond: " - if(diamond_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(diamond_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(diamond_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Bananium - var/bananium_amount = linked_lathe.materials.amount(MAT_BANANIUM) - dat += "* [bananium_amount] of Bananium: " - if(bananium_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(bananium_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(bananium_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" + if(!linked_lathe) + dat += "ERROR: Protolathe connection failed." + else + for(var/mat_id in linked_lathe.materials.materials) + var/datum/material/M = linked_lathe.materials.materials[mat_id] + dat += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" + dat += "
" dat += "
" if(3.3) @@ -974,7 +893,7 @@ proc/CallMaterialName(ID) dat += "Material Storage" dat += "Chemical Storage
" dat += "

Circuit Imprinter Menu:


" - dat += "Material Amount: [linked_imprinter.TotalMaterials()]
" + dat += "Material Amount: [linked_imprinter.materials.total_amount]
" dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" dat += "\ @@ -991,7 +910,7 @@ proc/CallMaterialName(ID) dat += "Main Menu" dat += "Circuit Imprinter Menu" dat += "

Browsing [selected_category]:


" - dat += "Material Amount: [linked_imprinter.TotalMaterials()]
" + dat += "Material Amount: [linked_imprinter.materials.total_amount]
" dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" var/coeff = linked_imprinter.efficiency_coeff @@ -1001,13 +920,16 @@ proc/CallMaterialName(ID) continue var/temp_materials var/check_materials = 1 - for(var/M in D.materials) + + var/all_materials = D.materials + D.reagents + + for(var/M in all_materials) temp_materials += " | " if (!linked_imprinter.check_mat(D, M)) check_materials = 0 - temp_materials += " [D.materials[M]/coeff] [CallMaterialName(M)]" + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" else - temp_materials += " [D.materials[M]/coeff] [CallMaterialName(M)]" + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" if (check_materials) dat += "[D.name][temp_materials]
" else @@ -1018,7 +940,7 @@ proc/CallMaterialName(ID) dat += "Main Menu" dat += "Circuit Imprinter Menu" dat += "

Search results:


" - dat += "Material Amount: [linked_imprinter.TotalMaterials()]
" + dat += "Material Amount: [linked_imprinter.materials.total_amount]
" dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" var/coeff = linked_imprinter.efficiency_coeff @@ -1038,9 +960,9 @@ proc/CallMaterialName(ID) dat += "[D.name][temp_materials]
" dat += "
" - if(4.2) + if(4.2) //Circuit Imprinter Material Storage Sub-menu dat += "Main Menu" - dat += "Imprinter Menu" + dat += "Circuit Imprinter Menu" dat += "Disposal All Chemicals in Storage
" dat += "

Chemical Storage:



" for(var/datum/reagent/R in linked_imprinter.reagents.reagent_list) @@ -1051,23 +973,16 @@ proc/CallMaterialName(ID) dat += "Main Menu" dat += "Circuit Imprinter Menu
" dat += "

Material Storage:



" - //Glass - dat += "* [linked_imprinter.g_amount] glass: " - if(linked_imprinter.g_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(linked_imprinter.g_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(linked_imprinter.g_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Gold - dat += "* [linked_imprinter.gold_amount] gold: " - if(linked_imprinter.gold_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(linked_imprinter.gold_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(linked_imprinter.gold_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Diamond - dat += "* [linked_imprinter.diamond_amount] diamond: " - if(linked_imprinter.diamond_amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " - if(linked_imprinter.diamond_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(linked_imprinter.diamond_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" + if(!linked_imprinter) + dat += "ERROR: Protolathe connection failed." + else + for(var/mat_id in linked_imprinter.materials.materials) + var/datum/material/M = linked_imprinter.materials.materials[mat_id] + dat += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" + dat += "
" dat += "
" var/datum/browser/popup = new(user, "rndconsole", name, 460, 550) diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index 3778e2c1c73..e90dcb20412 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -81,9 +81,14 @@ return if (disabled) return - if (!linked_console) - user << "The [name] must be linked to an R&D console first!" - return + if (!linked_console) // Try to auto-connect to new RnD consoles nearby. + for(var/obj/machinery/computer/rdconsole/console in oview(3, src)) + if(console.first_use) + console.SyncRDevices() + + if(!linked_console) + user << "The [name] must be linked to an R&D console first!" + return if (busy) user << "The [src.name] is busy right now." return diff --git a/code/modules/research/research.dm b/code/modules/research/research.dm index 130fce1f03f..503b35891d5 100644 --- a/code/modules/research/research.dm +++ b/code/modules/research/research.dm @@ -172,12 +172,12 @@ research holder datum. /datum/tech/engineering name = "Engineering Research" - desc = "Development of new and improved engineering parts and." + desc = "Development of new and improved engineering parts and tools." id = "engineering" /datum/tech/plasmatech name = "Plasma Research" - desc = "Research into the mysterious substance colloqually known as 'plasma'." + desc = "Research into the mysterious substance colloqually known as \"plasma\"." id = "plasmatech" rare = 3 @@ -187,8 +187,8 @@ research holder datum. id = "powerstorage" /datum/tech/bluespace - name = "'Blue-space' Research" - desc = "Research into the sub-reality known as 'blue-space'" + name = "\"Blue-space\" Research" + desc = "Research into the sub-reality known as \"blue-space\"." id = "bluespace" rare = 2 @@ -218,6 +218,9 @@ research holder datum. id = "syndicate" rare = 4 + +//Secret Technologies (hidden by default, require rare items to reveal) + /datum/tech/abductor name = "Alien Technologies Research" desc = "The study of technologies used by the advanced alien race known as Abductors." @@ -225,13 +228,14 @@ research holder datum. rare = 5 level = 0 -/* /datum/tech/arcane name = "Arcane Research" - desc = "Research into the occult and arcane field for use in practical science" + desc = "When sufficiently analyzed, any magic becomes indistinguishable from technology." id = "arcane" - level = 0 //It didn't become "secret" as advertised. + rare = 5 + level = 0 +/* //Branch Techs /datum/tech/explosives name = "Explosives Research" From 331618f950beb10d39431da47b553dd0d83c2ce8 Mon Sep 17 00:00:00 2001 From: sybil-tgstation13 Date: Wed, 8 Jun 2016 05:29:43 +0000 Subject: [PATCH 45/50] Automatic changelog compile, [ci skip] --- html/changelog.html | 37 +++++++++------------- html/changelogs/.all_changelog.yml | 11 +++++++ html/changelogs/AutoChangeLog-pr-18153.yml | 4 --- html/changelogs/AutoChangeLog-pr-18279.yml | 4 --- html/changelogs/AutoChangeLog-pr-18297.yml | 4 --- html/changelogs/AutoChangeLog-pr-18317.yml | 4 --- 6 files changed, 26 insertions(+), 38 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-18153.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18279.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18297.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18317.yml diff --git a/html/changelog.html b/html/changelog.html index ba19896e817..4d6caa7741d 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,21 @@ -->
+

08 June 2016

+

Cruix updated:

+
    +
  • Changelings no longer lose the regenerate ability if they respect while in regenerative stasis.
  • +
+

GunHog updated:

+
    +
  • Nanotrasen has approved the Hyper-Kenetic Accelerator upgrade for cyborg mining modules.
  • +
  • Each of the heads' ID computers are now themed for their department!
  • +
+

PKPenguin321 updated:

+
    +
  • You can now emag chemical dispensers, such as the ones in chemistry or the bar, to unlock illegal chemicals.
  • +
+

07 June 2016

Bobylein updated:

    @@ -1184,28 +1199,6 @@
  • Due to budget cuts, Nanotrasen is no longer utilizing copy-protected paper for its classified documents. Fortunately, our world-class security team has always prevented any thefts or photocopies from being made!
  • Secret documents can be photocopied. If you have an objective to steal any set of documents, a photocopy will be accepted. If you must steal red or blue documents, a photocopy will NOT be accepted. Enterprising traitors can forge the red/blue seal with a crayon to take advantage of this.
- -

06 April 2016

-

CoreOverload updated:

-
    -
  • You can now put slimes in stasis by exposing them to room temp CO2. Useful for both fighting the slimes and safely storing them.
  • -
-

Erwgd updated:

-
    -
  • The autolathe can now make hydroponics tools! Access the design routines in the Misc. category of the machine.
  • -
-

LanCartwright updated:

-
    -
  • Custom viruses with stealth values of 3 or above are now invisible on the PANDEMIC and no longer visible on health huds.
  • -
-

MrStonedOne updated:

-
    -
  • Centcom is happy to report that our single sided windows and our windoors should once again create an airtight seal.
  • -
-

bgobandit updated:

-
    -
  • Honk! Nanotrasen's clowning and development department has invented the clown megaphone, standard in all clowning loadouts! Honk honk!
  • -
GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 4ba647bd0fd..6d37ab056db 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -5451,3 +5451,14 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. the mob's blood volume reaches a critically low level you are unable to draw any more blood from it. - tweak: A changeling absorbing a human now sucks all their blood. +2016-06-08: + Cruix: + - bugfix: Changelings no longer lose the regenerate ability if they respect while + in regenerative stasis. + GunHog: + - rscadd: Nanotrasen has approved the Hyper-Kenetic Accelerator upgrade for cyborg + mining modules. + - tweak: Each of the heads' ID computers are now themed for their department! + PKPenguin321: + - rscadd: You can now emag chemical dispensers, such as the ones in chemistry or + the bar, to unlock illegal chemicals. diff --git a/html/changelogs/AutoChangeLog-pr-18153.yml b/html/changelogs/AutoChangeLog-pr-18153.yml deleted file mode 100644 index e7fcbfd66bf..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18153.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: PKPenguin321 -delete-after: True -changes: - - rscadd: "You can now emag chemical dispensers, such as the ones in chemistry or the bar, to unlock illegal chemicals." diff --git a/html/changelogs/AutoChangeLog-pr-18279.yml b/html/changelogs/AutoChangeLog-pr-18279.yml deleted file mode 100644 index 6f20acefae1..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18279.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: GunHog -delete-after: True -changes: - - rscadd: "Nanotrasen has approved the Hyper-Kenetic Accelerator upgrade for cyborg mining modules." diff --git a/html/changelogs/AutoChangeLog-pr-18297.yml b/html/changelogs/AutoChangeLog-pr-18297.yml deleted file mode 100644 index e0a79042fd9..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18297.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: GunHog -delete-after: True -changes: - - tweak: "Each of the heads' ID computers are now themed for their department!" diff --git a/html/changelogs/AutoChangeLog-pr-18317.yml b/html/changelogs/AutoChangeLog-pr-18317.yml deleted file mode 100644 index c04caeffd5d..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18317.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Cruix -delete-after: True -changes: - - bugfix: "Changelings no longer lose the regenerate ability if they respect while in regenerative stasis." From f3545d8d3b8af278575a3c29d27a2093a8652bfc Mon Sep 17 00:00:00 2001 From: LatD Date: Wed, 8 Jun 2016 10:23:10 +0300 Subject: [PATCH 46/50] Balances pyro anomaly (#18310) * End damage buff * Nerfs constant damage --- code/game/objects/effects/anomalies.dm | 2 +- code/modules/events/anomaly_pyro.dm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 458633001ca..843bf4411b8 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -172,7 +172,7 @@ ..() var/turf/open/T = get_turf(src) if(istype(T)) - T.atmos_spawn_air("o2=15;plasma=15;TEMP=1000") + T.atmos_spawn_air("o2=5;plasma=5;TEMP=1000") ///////////////////// diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm index 1f1b63c9fa3..751089d434d 100644 --- a/code/modules/events/anomaly_pyro.dm +++ b/code/modules/events/anomaly_pyro.dm @@ -30,10 +30,10 @@ if(newAnomaly.loc) var/turf/open/T = get_turf(newAnomaly) if(istype(T)) - T.atmos_spawn_air("o2=200;plasma=200;TEMP=1000") //Make it hot and burny for the new slime + T.atmos_spawn_air("o2=500;plasma=500;TEMP=1000") //Make it hot and burny for the new slime var/mob/living/simple_animal/slime/S = new/mob/living/simple_animal/slime(T) S.colour = pick("red", "orange") S.rabid = 1 - qdel(newAnomaly) \ No newline at end of file + qdel(newAnomaly) From eebfcaf82a591447e29af90b899b0c7d0cb438e8 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Wed, 8 Jun 2016 08:47:58 +0000 Subject: [PATCH 47/50] Automatic changelog generation for PR #18323 [ci skip] --- html/changelogs/AutoChangeLog-pr-18323.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18323.yml diff --git a/html/changelogs/AutoChangeLog-pr-18323.yml b/html/changelogs/AutoChangeLog-pr-18323.yml new file mode 100644 index 00000000000..8265d22cfa8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18323.yml @@ -0,0 +1,4 @@ +author: Kor +delete-after: True +changes: + - rscadd: "The clown will play a sad trombone noise upon death." From 8afd2ae8f21f5bbd6ab7a5c7a0ed0b32f745fd74 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Wed, 8 Jun 2016 11:14:58 +0000 Subject: [PATCH 48/50] Automatic changelog generation for PR #18335 [ci skip] --- html/changelogs/AutoChangeLog-pr-18335.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18335.yml diff --git a/html/changelogs/AutoChangeLog-pr-18335.yml b/html/changelogs/AutoChangeLog-pr-18335.yml new file mode 100644 index 00000000000..fd3081cb824 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18335.yml @@ -0,0 +1,7 @@ +author: Fox McCloud +delete-after: True +changes: + - bugfix: "Fixes Experimentor critical reactions not working" + - bugfix: "Fixes Experimentor item cloning not working" + - bugfix: "Fixes Experimentor producing coffee vending machines instead of coffe cups" + - tweak: "Experimentor can only clone critical reaction items instead of anything with an origin tech" From 33b9d7c8c2d7301769e30652c996d158947ac692 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Wed, 8 Jun 2016 11:16:31 +0000 Subject: [PATCH 49/50] Automatic changelog generation for PR #18327 [ci skip] --- html/changelogs/AutoChangeLog-pr-18327.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18327.yml diff --git a/html/changelogs/AutoChangeLog-pr-18327.yml b/html/changelogs/AutoChangeLog-pr-18327.yml new file mode 100644 index 00000000000..1af8a6544ca --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18327.yml @@ -0,0 +1,4 @@ +author: Joan +delete-after: True +changes: + - tweak: "Anima Fragments have slightly more health and move faster, but slow down temporarily when taking damage. Also they can move in space now." From eab3839b302835aeab3d860ebd17f7555d70bd1f Mon Sep 17 00:00:00 2001 From: sybil-tgstation13 Date: Wed, 8 Jun 2016 11:24:25 +0000 Subject: [PATCH 50/50] Automatic changelog compile, [ci skip] --- html/changelog.html | 15 +++++++++++++++ html/changelogs/.all_changelog.yml | 12 ++++++++++++ html/changelogs/AutoChangeLog-pr-18323.yml | 4 ---- html/changelogs/AutoChangeLog-pr-18327.yml | 4 ---- html/changelogs/AutoChangeLog-pr-18335.yml | 7 ------- 5 files changed, 27 insertions(+), 15 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-18323.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18327.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-18335.yml diff --git a/html/changelog.html b/html/changelog.html index 4d6caa7741d..fc7a43aa6e3 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -60,11 +60,26 @@
  • Changelings no longer lose the regenerate ability if they respect while in regenerative stasis.
+

Fox McCloud updated:

+
    +
  • Fixes Experimentor critical reactions not working
  • +
  • Fixes Experimentor item cloning not working
  • +
  • Fixes Experimentor producing coffee vending machines instead of coffe cups
  • +
  • Experimentor can only clone critical reaction items instead of anything with an origin tech
  • +

GunHog updated:

  • Nanotrasen has approved the Hyper-Kenetic Accelerator upgrade for cyborg mining modules.
  • Each of the heads' ID computers are now themed for their department!
+

Joan updated:

+
    +
  • Anima Fragments have slightly more health and move faster, but slow down temporarily when taking damage. Also they can move in space now.
  • +
+

Kor updated:

+
    +
  • The clown will play a sad trombone noise upon death.
  • +

PKPenguin321 updated:

  • You can now emag chemical dispensers, such as the ones in chemistry or the bar, to unlock illegal chemicals.
  • diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 6d37ab056db..944c4906364 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -5455,10 +5455,22 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Cruix: - bugfix: Changelings no longer lose the regenerate ability if they respect while in regenerative stasis. + Fox McCloud: + - bugfix: Fixes Experimentor critical reactions not working + - bugfix: Fixes Experimentor item cloning not working + - bugfix: Fixes Experimentor producing coffee vending machines instead of coffe + cups + - tweak: Experimentor can only clone critical reaction items instead of anything + with an origin tech GunHog: - rscadd: Nanotrasen has approved the Hyper-Kenetic Accelerator upgrade for cyborg mining modules. - tweak: Each of the heads' ID computers are now themed for their department! + Joan: + - tweak: Anima Fragments have slightly more health and move faster, but slow down + temporarily when taking damage. Also they can move in space now. + Kor: + - rscadd: The clown will play a sad trombone noise upon death. PKPenguin321: - rscadd: You can now emag chemical dispensers, such as the ones in chemistry or the bar, to unlock illegal chemicals. diff --git a/html/changelogs/AutoChangeLog-pr-18323.yml b/html/changelogs/AutoChangeLog-pr-18323.yml deleted file mode 100644 index 8265d22cfa8..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18323.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Kor -delete-after: True -changes: - - rscadd: "The clown will play a sad trombone noise upon death." diff --git a/html/changelogs/AutoChangeLog-pr-18327.yml b/html/changelogs/AutoChangeLog-pr-18327.yml deleted file mode 100644 index 1af8a6544ca..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18327.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Joan -delete-after: True -changes: - - tweak: "Anima Fragments have slightly more health and move faster, but slow down temporarily when taking damage. Also they can move in space now." diff --git a/html/changelogs/AutoChangeLog-pr-18335.yml b/html/changelogs/AutoChangeLog-pr-18335.yml deleted file mode 100644 index fd3081cb824..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18335.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: Fox McCloud -delete-after: True -changes: - - bugfix: "Fixes Experimentor critical reactions not working" - - bugfix: "Fixes Experimentor item cloning not working" - - bugfix: "Fixes Experimentor producing coffee vending machines instead of coffe cups" - - tweak: "Experimentor can only clone critical reaction items instead of anything with an origin tech"

Autolathe Menu:


" - dat += "Total amount: [materials.total_amount] / [materials.max_amount] cm3
" - dat += "Metal amount: [materials.amount(MAT_METAL)] cm3
" - dat += "Glass amount: [materials.amount(MAT_GLASS)] cm3
" + dat += materials_printout() dat += "
\ \ @@ -284,9 +282,7 @@ /obj/machinery/autolathe/proc/category_win(mob/user,selected_category) var/dat = "Return to main menu" dat += "

Browsing [selected_category]:


" - dat += "Total amount: [materials.total_amount] / [materials.max_amount] cm3
" - dat += "Metal amount: [materials.amount(MAT_METAL)] cm3
" - dat += "Glass amount: [materials.amount(MAT_GLASS)] cm3
" + dat += materials_printout() for(var/v in files.known_designs) var/datum/design/D = files.known_designs[v] @@ -315,9 +311,7 @@ /obj/machinery/autolathe/proc/search_win(mob/user) var/dat = "Return to main menu" dat += "

Search results:


" - dat += "Total amount: [materials.total_amount] / [materials.max_amount] cm3
" - dat += "Metal amount: [materials.amount(MAT_METAL)] cm3
" - dat += "Glass amount: [materials.amount(MAT_GLASS)] cm3
" + dat += materials_printout() for(var/v in matching_designs) var/datum/design/D = v @@ -340,6 +334,13 @@ dat += "
" return dat +/obj/machinery/autolathe/proc/materials_printout() + var/dat = "Total amount: [materials.total_amount] / [materials.max_amount] cm3
" + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + dat += "[M.name] amount: [M.amount] cm3
" + return dat + /obj/machinery/autolathe/proc/can_build(datum/design/D) var/coeff = (ispath(D.build_path,/obj/item/stack) ? 1 : prod_coeff) diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm index 07e44ffe1be..a3663f95612 100644 --- a/code/game/machinery/droneDispenser.dm +++ b/code/game/machinery/droneDispenser.dm @@ -55,7 +55,7 @@ /obj/machinery/droneDispenser/New() ..() health = max_health - materials = new(src, list(MAT_METAL=1, MAT_GLASS=1), + materials = new(src, list(MAT_METAL, MAT_GLASS), MINERAL_MATERIAL_AMOUNT*MAX_STACK_SIZE*2) using_materials = list(MAT_METAL=metal_cost, MAT_GLASS=glass_cost) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 7207a48eca0..e45c6c26e80 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -96,6 +96,7 @@ Class Procs: /obj/machinery name = "machinery" icon = 'icons/obj/stationobjs.dmi' + verb_say = "beeps" verb_yell = "blares" pressure_resistance = 10 var/stat = 0 diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 1725f6e06d7..4bc0a4a5418 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -20,7 +20,7 @@ var/const/SAFETY_COOLDOWN = 100 /obj/machinery/recycler/New() ..() - materials = new /datum/material_container(src, list(MAT_METAL=1, MAT_GLASS=1, MAT_PLASMA=1, MAT_SILVER=1, MAT_GOLD=1, MAT_DIAMOND=1, MAT_URANIUM=1, MAT_BANANIUM=1)) + materials = new /datum/material_container(src, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM)) var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/recycler(null) B.apply_default_parts(src) update_icon() diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 429460f0d67..c564e924fab 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -11,19 +11,8 @@ req_access = list(access_robotics) var/time_coeff = 1 var/component_coeff = 1 - var/list/resources = list( - MAT_METAL=0, - MAT_GLASS=0, - MAT_BANANIUM=0, - MAT_DIAMOND=0, - MAT_GOLD=0, - MAT_PLASMA=0, - MAT_SILVER=0, - MAT_URANIUM=0 - ) - var/res_max_amount = 200000 + var/datum/material_container/materials var/datum/research/files - var/id var/sync = 0 var/part_set var/datum/design/being_built @@ -47,9 +36,10 @@ /obj/machinery/mecha_part_fabricator/New() ..() + files = new /datum/research(src) //Setup the research data holder. + materials = new(src, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM)) var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/mechfab(null) B.apply_default_parts(src) - files = new /datum/research(src) //Setup the research data holder. /obj/item/weapon/circuitboard/machine/mechfab name = "circuit board (Exosuit Fabricator)" @@ -64,10 +54,10 @@ /obj/machinery/mecha_part_fabricator/RefreshParts() var/T = 0 - //maximum stocking amount (max 412000) + //maximum stocking amount (default 300000, 600000 at T4) for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) T += M.rating - res_max_amount = (187000+(T * 37500)) + materials.max_amount = (200000 + (T*50000)) //resources adjustment coefficient (1 -> 0.85 -> 0.7 -> 0.55) T = 1.15 @@ -93,24 +83,20 @@ return 0 return 1 -/obj/machinery/mecha_part_fabricator/proc/emag() - switch(emagged) - if(0) - emagged = 0.5 - visible_message("\icon[src] \The [src] beeps: \"DB error \[Code 0x00F1\]\"") - sleep(10) - visible_message("\icon[src] \The [src] beeps: \"Attempting auto-repair\"") - sleep(15) - visible_message("\icon[src] \The [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"") - sleep(30) - visible_message("\icon[src] \The [src] beeps: \"User DB truncated. Please contact your Nanotrasen system operator for future assistance.\"") - req_access = null - emagged = 1 - if(0.5) - visible_message("\icon[src] \The [src] beeps: \"DB not responding \[Code 0x0003\]...\"") - if(1) - visible_message("\icon[src] \The [src] beeps: \"No records in User DB\"") - return +/obj/machinery/mecha_part_fabricator/emag_act() + if(emagged) + return + + emagged = 0.5 + say("DB error \[Code 0x00F1\]") + sleep(10) + say("Attempting auto-repair...") + sleep(15) + say("User DB corrupted \[Code 0x00FA\]. Truncating data structure...") + sleep(30) + say("User DB truncated. Please contact your Nanotrasen system operator for future assistance.") + req_access = null + emagged = 1 /obj/machinery/mecha_part_fabricator/proc/output_parts_list(set_name) var/output = "" @@ -119,8 +105,10 @@ if(D.build_type & MECHFAB) if(!(set_name in D.category)) continue - var/resources_available = check_resources(D) - output += "
[output_part_info(D)]
\[[resources_available?"Build | ":null]Add to queue\]\[?\]
" + output += "
[output_part_info(D)]
\[" + if(check_resources(D)) + output += "Build | " + output += "Add to queue\]\[?\]
" return output /obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D) @@ -131,39 +119,42 @@ var/i = 0 var/output for(var/c in D.materials) - if(c in resources) - output += "[i?" | ":null][get_resource_cost_w_coeff(D,c)] [material2name(c)]" - i++ + output += "[i?" | ":null][get_resource_cost_w_coeff(D, c)] [material2name(c)]" + i++ return output /obj/machinery/mecha_part_fabricator/proc/output_available_resources() var/output - for(var/resource in resources) - var/amount = min(res_max_amount, resources[resource]) - output += "[material2name(resource)]: [amount] cm³" - if(amount>0) - output += "- Remove \[1\] | \[10\] | \[All\]" + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + output += "[M.name]: [M.amount] cm³" + if(M.amount >= MINERAL_MATERIAL_AMOUNT) + output += "- Remove \[1\]" + if(M.amount >= (MINERAL_MATERIAL_AMOUNT * 10)) + output += " | \[10\]" + output += " | \[All\]" output += "
" return output -/obj/machinery/mecha_part_fabricator/proc/remove_resources(datum/design/D) - for(var/resource in D.materials) - if(resource in resources) - resources[resource] -= get_resource_cost_w_coeff(D,resource) +/obj/machinery/mecha_part_fabricator/proc/get_resources_w_coeff(datum/design/D) + var/list/resources = list() + for(var/R in D.materials) + resources[R] = get_resource_cost_w_coeff(D, R) + return resources /obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D) - for(var/R in D.materials) - if(R in resources) - if(resources[R] < get_resource_cost_w_coeff(D, R)) - return 0 - else - return 0 - return 1 + if(D.reagents.len) // No reagents storage - no reagent designs. + return 0 + if(materials.has_materials(get_resources_w_coeff(D))) + return 1 + return 0 /obj/machinery/mecha_part_fabricator/proc/build_part(datum/design/D) being_built = D desc = "It's building \a [initial(D.name)]." - remove_resources(D) + var/list/res_coef = get_resources_w_coeff(D) + + materials.use_amount(res_coef) overlays += "fab-active" use_power = 2 updateUsrDialog() @@ -174,9 +165,8 @@ var/location = get_step(src,(dir)) var/obj/item/I = new D.build_path(location) - I.materials[MAT_METAL] = get_resource_cost_w_coeff(D,MAT_METAL) - I.materials[MAT_GLASS] = get_resource_cost_w_coeff(D,MAT_GLASS) - visible_message("\icon[src] \The [src] beeps, \"\The [I] is complete.\"") + I.materials = res_coef + say("\The [I] is complete.") being_built = null updateUsrDialog() @@ -220,14 +210,14 @@ if(stat&(NOPOWER|BROKEN)) return 0 if(!check_resources(D)) - visible_message("\icon[src] \The [src] beeps, \"Not enough resources. Queue processing stopped.\"") + say("Not enough resources. Queue processing stopped.") temp = {"Not enough resources to build next part.
Try again | Return"} return 0 remove_from_queue(1) build_part(D) D = listgetindex(queue, 1) - visible_message("\icon[src] \The [src] beeps, \"Queue processing finished successfully.\"") + say("Queue processing finished successfully.") /obj/machinery/mecha_part_fabricator/proc/list_queue() var/output = "Queue contains:" @@ -239,7 +229,11 @@ for(var/datum/design/D in queue) i++ var/obj/part = D.build_path - output += "[initial(part.name)] - [i>1?"":null] [i↓":null] Remove" + output += "" + output += initial(part.name) + " - " + output += "[i>1?"":null] " + output += "[i↓":null] " + output += "Remove" output += "" output += "\[Process queue | Clear queue\]" @@ -265,7 +259,7 @@ temp += "Return" updateUsrDialog() - visible_message("\icon[src] \The [src] beeps, \"Successfully synchronized with R&D server.\"") + say("Successfully synchronized with R&D server.") return temp = "Unable to connect to local R&D Database.
Please check your connections and try again.
Return" @@ -289,7 +283,7 @@ user.set_machine(src) var/turf/exit = get_step(src,(dir)) if(exit.density) - visible_message("\icon[src] \The [src] beeps, \"Error! Part outlet is obstructed.\"") + say("Error! Part outlet is obstructed.") return if(temp) left_part = temp @@ -303,7 +297,7 @@ left_part = output_available_resources()+"
" left_part += "Sync with R&D servers
" for(var/part_set in part_sets) - left_part += "[part_set] - \[Add all parts to queue\]
" + left_part += "
[part_set] - \[Add all parts to queue
\]" if("parts") left_part += output_parts_list(part_set) left_part += "
Return" @@ -416,124 +410,57 @@ break if(href_list["remove_mat"] && href_list["material"]) - var/amount = text2num(href_list["remove_mat"]) - var/material = href_list["material"] - if(amount < 0 || amount > resources[material]) //href protection - return - - var/removed = remove_material(material,amount) - if(removed == -1) - temp = "Not enough [material2name(material)] to produce a sheet." - else - temp = "Ejected [removed] of [material2name(material)]" - temp += "
Return" + materials.retrieve_sheets(text2num(href_list["remove_mat"]), href_list["material"]) updateUsrDialog() return -/obj/machinery/mecha_part_fabricator/proc/remove_material(mat_string, amount) - if(resources[mat_string] < MINERAL_MATERIAL_AMOUNT) //not enough mineral for a sheet - return -1 - var/type - switch(mat_string) - if(MAT_METAL) - type = /obj/item/stack/sheet/metal - if(MAT_GLASS) - type = /obj/item/stack/sheet/glass - if(MAT_GOLD) - type = /obj/item/stack/sheet/mineral/gold - if(MAT_SILVER) - type = /obj/item/stack/sheet/mineral/silver - if(MAT_DIAMOND) - type = /obj/item/stack/sheet/mineral/diamond - if(MAT_PLASMA) - type = /obj/item/stack/sheet/mineral/plasma - if(MAT_URANIUM) - type = /obj/item/stack/sheet/mineral/uranium - if(MAT_BANANIUM) - type = /obj/item/stack/sheet/mineral/bananium - else - return 0 - var/result = 0 - - while(amount > 50) - new type(get_turf(src),50) - amount -= 50 - result += 50 - resources[mat_string] -= 50 * MINERAL_MATERIAL_AMOUNT - - var/total_amount = round(resources[mat_string]/MINERAL_MATERIAL_AMOUNT) - if(total_amount)//if there's still enough material for sheets - var/obj/item/stack/sheet/res = new type(get_turf(src),min(amount,total_amount)) - resources[mat_string] -= res.amount*MINERAL_MATERIAL_AMOUNT - result += res.amount - - return result - /obj/machinery/mecha_part_fabricator/deconstruction() - for(var/material in resources) - remove_material(material, resources[material]/MINERAL_MATERIAL_AMOUNT) + materials.retrieve_all() + ..() -/obj/machinery/mecha_part_fabricator/attackby(obj/W, mob/user, params) +/obj/machinery/mecha_part_fabricator/attackby(obj/item/W, mob/user, params) if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W)) - return + return 1 if(exchange_parts(user, W)) - return + return 1 if(default_deconstruction_crowbar(W)) return 1 - if(istype(W, /obj/item/stack)) + if(istype(W, /obj/item/stack/sheet)) if(panel_open) - user << "You can't load \the [name] while it's opened!" + user << "You can't load [src] while it's opened!" return 1 - var/material - switch(W.type) - if(/obj/item/stack/sheet/mineral/gold) - material = MAT_GOLD - if(/obj/item/stack/sheet/mineral/silver) - material = MAT_SILVER - if(/obj/item/stack/sheet/mineral/diamond) - material = MAT_DIAMOND - if(/obj/item/stack/sheet/mineral/plasma) - material = MAT_PLASMA - if(/obj/item/stack/sheet/metal) - material = MAT_METAL - if(/obj/item/stack/sheet/glass) - material = MAT_GLASS - if(/obj/item/stack/sheet/mineral/bananium) - material = MAT_BANANIUM - if(/obj/item/stack/sheet/mineral/uranium) - material = MAT_URANIUM - else - return ..() - if(being_built) user << "\The [src] is currently processing! Please wait until completion." - return - if(res_max_amount - resources[material] < MINERAL_MATERIAL_AMOUNT) //overstuffing the fabricator - user << "\The [src] [material2name(material)] storage is full!" - return - var/obj/item/stack/sheet/stack = W - var/sname = "[stack.name]" - if(resources[material] < res_max_amount) - overlays += "fab-load-[material2name(material)]"//loading animation is now an overlay based on material type. No more spontaneous conversion of all ores to metal. -vey + return 1 + + var/material_amount = materials.get_item_material_amount(W) + if(!material_amount) + user << "This object does not contain sufficient amounts of materials to be accepted by [src]." + return 1 + if(!materials.has_space(material_amount)) + user << "\The [src] is full. Please remove some materials from [src] in order to insert more." + return 1 + if(!user.unEquip(W)) + user << "\The [W] is stuck to you and cannot be placed into [src]." + return 1 + + var/inserted = materials.insert_item(W) + if(inserted) + user << "You insert [inserted] sheet\s into [src]." + if(W && W.materials.len) + var/mat_overlay = "fab-load-[material2name(W.materials[1])]" + overlays += mat_overlay + sleep(10) + overlays -= mat_overlay //No matter what the overlay shall still be deleted + + updateUsrDialog() - var/transfer_amount = min(stack.amount, round((res_max_amount - resources[material])/MINERAL_MATERIAL_AMOUNT,1)) - resources[material] += transfer_amount * MINERAL_MATERIAL_AMOUNT - stack.use(transfer_amount) - user << "You insert [transfer_amount] [sname] sheet\s into \the [src]." - sleep(10) - updateUsrDialog() - overlays -= "fab-load-[material2name(material)]" //No matter what the overlay shall still be deleted - else - user << "\The [src] cannot hold any more [sname] sheet\s!" else return ..() /obj/machinery/mecha_part_fabricator/proc/material2name(ID) - return copytext(ID,2) - -/obj/machinery/mecha_part_fabricator/emag_act() - emag() + return copytext(ID,2) \ No newline at end of file diff --git a/code/modules/cargo/exports/research.dm b/code/modules/cargo/exports/research.dm index 004eded9101..2862b6c1f93 100644 --- a/code/modules/cargo/exports/research.dm +++ b/code/modules/cargo/exports/research.dm @@ -17,27 +17,3 @@ var/obj/item/weapon/disk/tech_disk/D = O var/datum/tech/tech = D.stored techLevels[tech.id] = tech.level - - - -// Sell designs -/datum/export/design - cost = 2500 - unit_name = "design data disk" - export_types = list(/obj/item/weapon/disk/design_disk) - var/list/researchDesigns = list() - -/datum/export/design/get_cost(obj/O) - var/obj/item/weapon/disk/design_disk/disk = O - if(!disk.blueprint) - return 0 - var/datum/design/design = disk.blueprint - if(design.id in researchDesigns) - return 0 - return ..() - -/datum/export/design/sell_object(obj/O) - ..() - var/obj/item/weapon/disk/design_disk/disk = O - var/datum/design/design = disk.blueprint - researchDesigns += design.id \ No newline at end of file diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm index da3698024d0..0167f9f8347 100644 --- a/code/modules/clothing/shoes/bananashoes.dm +++ b/code/modules/clothing/shoes/bananashoes.dm @@ -10,7 +10,7 @@ /obj/item/clothing/shoes/clown_shoes/banana_shoes/New() ..() - bananium = new/datum/material_container(src,list(MAT_BANANIUM=1),200000) + bananium = new/datum/material_container(src,list(MAT_BANANIUM),200000) /obj/item/clothing/shoes/clown_shoes/banana_shoes/step_action() if(on) diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index 0da4c5e927e..7ee80b4e266 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -10,12 +10,8 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). icon_state = "circuit_imprinter" flags = OPENCONTAINER - var/g_amount = 0 - var/gold_amount = 0 - var/diamond_amount = 0 - var/max_material_amount = 75000 + var/datum/material_container/materials var/efficiency_coeff - reagents = new(0) var/list/categories = list( "AI Modules", @@ -32,9 +28,14 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). /obj/machinery/r_n_d/circuit_imprinter/New() ..() + materials = new(src, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND)) + create_reagents(0) var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/circuit_imprinter(null) B.apply_default_parts(src) - reagents.my_atom = src + +/obj/machinery/r_n_d/circuit_imprinter/Destroy() + qdel(materials) + return ..() /obj/item/weapon/circuitboard/machine/circuit_imprinter name = "circuit board (Circuit Imprinter)" @@ -52,7 +53,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). G.reagents.trans_to(src, G.reagents.total_volume) for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) T += M.rating - max_material_amount = T * 75000 + materials.max_amount = T * 75000 T = 0 for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) T += M.rating @@ -62,72 +63,55 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). if (prob(50)) qdel(src) +/obj/machinery/r_n_d/circuit_imprinter/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material + var/list/all_materials = being_built.reagents + being_built.materials -/obj/machinery/r_n_d/circuit_imprinter/proc/check_mat(datum/design/being_built, M) - switch(M) - if(MAT_GLASS) - return (g_amount - (being_built.materials[M]/efficiency_coeff) >= 0) - if(MAT_GOLD) - return (gold_amount - (being_built.materials[M]/efficiency_coeff) >= 0) - if(MAT_DIAMOND) - return (diamond_amount - (being_built.materials[M]/efficiency_coeff) >= 0) - else - return (reagents.has_reagent(M, (being_built.materials[M]/efficiency_coeff)) != 0) + var/A = materials.amount(M) + if(!A) + A = reagents.get_reagent_amount(M) + return round(A / max(1, (all_materials[M]/efficiency_coeff))) -/obj/machinery/r_n_d/circuit_imprinter/proc/TotalMaterials() - return g_amount + gold_amount + diamond_amount - -//we drop the minerals in the machine onto the ground when deconstructed. +//we eject the materials upon deconstruction. /obj/machinery/r_n_d/circuit_imprinter/deconstruction() for(var/obj/item/weapon/reagent_containers/glass/G in component_parts) reagents.trans_to(G, G.reagents.maximum_volume) - if(g_amount >= MINERAL_MATERIAL_AMOUNT) - var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc) - G.amount = round(g_amount / MINERAL_MATERIAL_AMOUNT) - if(gold_amount >= MINERAL_MATERIAL_AMOUNT) - var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(src.loc) - G.amount = round(gold_amount / MINERAL_MATERIAL_AMOUNT) - if(diamond_amount >= MINERAL_MATERIAL_AMOUNT) - var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(src.loc) - G.amount = round(diamond_amount / MINERAL_MATERIAL_AMOUNT) + materials.retrieve_all() ..() + /obj/machinery/r_n_d/circuit_imprinter/disconnect_console() linked_console.linked_imprinter = null ..() /obj/machinery/r_n_d/circuit_imprinter/Insert_Item(obj/item/O, mob/user) - if (istype(O, /obj/item/stack/sheet/glass) || istype(O, /obj/item/stack/sheet/mineral/gold) || istype(O, /obj/item/stack/sheet/mineral/diamond)) + if(istype(O,/obj/item/stack/sheet)) . = 1 if(!is_insertion_ready(user)) return + var/sheet_material = materials.get_item_material_amount(O) + if(!sheet_material) + return + + if(!materials.has_space(sheet_material)) + user << "The [src.name]'s material bin is full! Please remove material before adding more." + return 1 + var/obj/item/stack/sheet/stack = O - if ((TotalMaterials() + stack.perunit) > max_material_amount) - user << "The [name] is full! Please remove glass from the protolathe in order to insert more." + var/amount = round(input("How many sheets do you want to add?") as num)//No decimals + if(!in_range(src, stack) || !user.Adjacent(src)) return - - var/amount = round(input("How many sheets do you want to add?") as num) - if(amount <= 0 || stack.amount <= 0) - return - if(amount > stack.amount) - amount = min(stack.amount, round((max_material_amount-TotalMaterials())/stack.perunit)) - - busy = 1 - use_power(max(1000, (MINERAL_MATERIAL_AMOUNT*amount/10))) - user << "You add [amount] sheets to the [src.name]." - if(istype(stack, /obj/item/stack/sheet/glass)) - g_amount += amount * MINERAL_MATERIAL_AMOUNT - else if(istype(stack, /obj/item/stack/sheet/mineral/gold)) - gold_amount += amount * MINERAL_MATERIAL_AMOUNT - else if(istype(stack, /obj/item/stack/sheet/mineral/diamond)) - diamond_amount += amount * MINERAL_MATERIAL_AMOUNT - stack.use(amount) - busy = 0 - src.updateUsrDialog() + var/amount_inserted = materials.insert_stack(O,amount) + if(!amount_inserted) + return 1 + else + use_power(max(1000, (MINERAL_MATERIAL_AMOUNT*amount_inserted/10))) + user << "You add [amount_inserted] sheets to the [src.name]." + updateUsrDialog() else if(user.a_intent != "harm") user << "You cannot insert this item into the [name]!" + return 1 else - return 0 + return 0 \ No newline at end of file diff --git a/code/modules/research/designs/AI_module_designs.dm b/code/modules/research/designs/AI_module_designs.dm index 569a36607ef..7f39ffbce51 100644 --- a/code/modules/research/designs/AI_module_designs.dm +++ b/code/modules/research/designs/AI_module_designs.dm @@ -2,154 +2,139 @@ //////////AI Module Disks////////// /////////////////////////////////// -/datum/design/aicore +/datum/design/board/aicore name = "AI Design (AI Core)" desc = "Allows for the construction of circuit boards used to build new AI cores." id = "aicore" req_tech = list("programming" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/aicore category = list("AI Modules") -/datum/design/safeguard_module +/datum/design/board/safeguard_module name = "Module Design (Safeguard)" desc = "Allows for the construction of a Safeguard AI Module." id = "safeguard_module" req_tech = list("programming" = 3, "materials" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_GOLD = 100) + materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/weapon/aiModule/supplied/safeguard category = list("AI Modules") -/datum/design/onehuman_module +/datum/design/board/onehuman_module name = "Module Design (OneHuman)" desc = "Allows for the construction of a OneHuman AI Module." id = "onehuman_module" req_tech = list("programming" = 6, "materials" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_DIAMOND = 100) + materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/weapon/aiModule/zeroth/oneHuman category = list("AI Modules") -/datum/design/protectstation_module +/datum/design/board/protectstation_module name = "Module Design (ProtectStation)" desc = "Allows for the construction of a ProtectStation AI Module." id = "protectstation_module" req_tech = list("programming" = 5, "materials" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_GOLD = 100) + materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/weapon/aiModule/supplied/protectStation category = list("AI Modules") -/datum/design/quarantine_module +/datum/design/board/quarantine_module name = "Module Design (Quarantine)" desc = "Allows for the construction of a Quarantine AI Module." id = "quarantine_module" req_tech = list("programming" = 3, "biotech" = 2, "materials" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_GOLD = 100) + materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/weapon/aiModule/supplied/quarantine category = list("AI Modules") -/datum/design/oxygen_module +/datum/design/board/oxygen_module name = "Module Design (OxygenIsToxicToHumans)" desc = "Allows for the construction of a Safeguard AI Module." id = "oxygen_module" req_tech = list("programming" = 4, "biotech" = 2, "materials" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_GOLD = 100) + materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/weapon/aiModule/supplied/oxygen category = list("AI Modules") -/datum/design/freeform_module +/datum/design/board/freeform_module name = "Module Design (Freeform)" desc = "Allows for the construction of a Freeform AI Module." id = "freeform_module" req_tech = list("programming" = 5, "materials" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_GOLD = 100) + materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/weapon/aiModule/supplied/freeform category = list("AI Modules") -/datum/design/reset_module +/datum/design/board/reset_module name = "Module Design (Reset)" desc = "Allows for the construction of a Reset AI Module." id = "reset_module" req_tech = list("programming" = 4, "materials" = 6) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_GOLD = 100) + materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/weapon/aiModule/reset category = list("AI Modules") -/datum/design/purge_module +/datum/design/board/purge_module name = "Module Design (Purge)" desc = "Allows for the construction of a Purge AI Module." id = "purge_module" req_tech = list("programming" = 5, "materials" = 6) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_DIAMOND = 100) + materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/weapon/aiModule/reset/purge category = list("AI Modules") -/datum/design/freeformcore_module +/datum/design/board/freeformcore_module name = "AI Core Module (Freeform)" desc = "Allows for the construction of a Freeform AI Core Module." id = "freeformcore_module" req_tech = list("programming" = 6, "materials" = 6) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_DIAMOND = 100) + materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/weapon/aiModule/core/freeformcore category = list("AI Modules") -/datum/design/asimov +/datum/design/board/asimov name = "Core Module Design (Asimov)" desc = "Allows for the construction of a Asimov AI Core Module." id = "asimov_module" req_tech = list("programming" = 3, "materials" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_DIAMOND = 100) + materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/weapon/aiModule/core/full/asimov category = list("AI Modules") -/datum/design/paladin_module +/datum/design/board/paladin_module name = "Core Module Design (P.A.L.A.D.I.N.)" desc = "Allows for the construction of a P.A.L.A.D.I.N. AI Core Module." id = "paladin_module" req_tech = list("programming" = 5, "materials" = 5) build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_DIAMOND = 100) + materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/weapon/aiModule/core/full/paladin category = list("AI Modules") -/datum/design/tyrant_module +/datum/design/board/tyrant_module name = "Core Module Design (T.Y.R.A.N.T.)" desc = "Allows for the construction of a T.Y.R.A.N.T. AI Module." id = "tyrant_module" req_tech = list("programming" = 5, "syndicate" = 2, "materials" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_DIAMOND = 100) + materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/weapon/aiModule/core/full/tyrant category = list("AI Modules") -/datum/design/corporate_module +/datum/design/board/corporate_module name = "Core Module Design (Corporate)" desc = "Allows for the construction of a Corporate AI Core Module." id = "corporate_module" req_tech = list("programming" = 5, "materials" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_DIAMOND = 100) + materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/weapon/aiModule/core/full/corp category = list("AI Modules") -/datum/design/custom_module +/datum/design/board/custom_module name = "Core Module Design (Custom)" desc = "Allows for the construction of a Custom AI Core Module." id = "custom_module" req_tech = list("programming" = 5, "materials" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_DIAMOND = 100) + materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/weapon/aiModule/core/full/custom category = list("AI Modules") diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm index 453c04d05e6..60b921056de 100644 --- a/code/modules/research/designs/comp_board_designs.dm +++ b/code/modules/research/designs/comp_board_designs.dm @@ -1,311 +1,253 @@ ///////////////////Computer Boards/////////////////////////////////// -/datum/design/seccamera +/datum/design/board + name = "Computer Design (Battle Arcade Machine)" + desc = "Allows for the construction of circuit boards used to build a new arcade machine." + id = "arcade_battle" + req_tech = list("programming" = 1) + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000) + reagents = list("sacid" = 20) + build_path = /obj/item/weapon/circuitboard/computer/arcade/battle + category = list("Computer Boards") + +/datum/design/board/orion_trail + name = "Computer Design (Orion Trail Arcade Machine)" + desc = "Allows for the construction of circuit boards used to build a new Orion Trail machine." + id = "arcade_orion" + req_tech = list("programming" = 1) + build_path = /obj/item/weapon/circuitboard/computer/arcade/orion_trail + category = list("Computer Boards") + + +/datum/design/board/seccamera name = "Computer Design (Security)" desc = "Allows for the construction of circuit boards used to build security camera computers." id = "seccamera" req_tech = list("programming" = 2, "combat" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/security category = list("Computer Boards") -/datum/design/aiupload +/datum/design/board/aiupload name = "Computer Design (AI Upload)" desc = "Allows for the construction of circuit boards used to build an AI Upload Console." id = "aiupload" req_tech = list("programming" = 5, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/aiupload category = list("Computer Boards") -/datum/design/borgupload +/datum/design/board/borgupload name = "Computer Design (Cyborg Upload)" desc = "Allows for the construction of circuit boards used to build a Cyborg Upload Console." id = "borgupload" req_tech = list("programming" = 5, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/borgupload category = list("Computer Boards") -/datum/design/med_data +/datum/design/board/med_data name = "Computer Design (Medical Records)" desc = "Allows for the construction of circuit boards used to build a medical records console." id = "med_data" req_tech = list("programming" = 2, "biotech" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/med_data category = list("Computer Boards") -/datum/design/operating +/datum/design/board/operating name = "Computer Design (Operating Computer)" desc = "Allows for the construction of circuit boards used to build an operating computer console." id = "operating" req_tech = list("programming" = 2, "biotech" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/operating category = list("Computer Boards") -/datum/design/pandemic +/datum/design/board/pandemic name = "Computer Design (PanD.E.M.I.C. 2200)" desc = "Allows for the construction of circuit boards used to build a PanD.E.M.I.C. 2200 console." id = "pandemic" req_tech = list("programming" = 3, "biotech" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/pandemic category = list("Computer Boards") -/datum/design/scan_console +/datum/design/board/scan_console name = "Computer Design (DNA Machine)" desc = "Allows for the construction of circuit boards used to build a new DNA scanning console." id = "scan_console" req_tech = list("programming" = 2, "biotech" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/scan_consolenew category = list("Computer Boards") -/datum/design/comconsole +/datum/design/board/comconsole name = "Computer Design (Communications)" desc = "Allows for the construction of circuit boards used to build a communications console." id = "comconsole" req_tech = list("programming" = 3, "magnets" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/communications category = list("Computer Boards") -/datum/design/idcardconsole +/datum/design/board/idcardconsole name = "Computer Design (ID Console)" desc = "Allows for the construction of circuit boards used to build an ID computer." id = "idcardconsole" req_tech = list("programming" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/card category = list("Computer Boards") -/datum/design/crewconsole +/datum/design/board/crewconsole name = "Computer Design (Crew monitoring computer)" desc = "Allows for the construction of circuit boards used to build a Crew monitoring computer." id = "crewconsole" req_tech = list("programming" = 3, "magnets" = 2, "biotech" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/crew category = list("Computer Boards") -/datum/design/secdata +/datum/design/board/secdata name = "Computer Design (Security Records Console)" desc = "Allows for the construction of circuit boards used to build a security records console." id = "secdata" req_tech = list("programming" = 2, "combat" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/secure_data category = list("Computer Boards") -/datum/design/atmosalerts +/datum/design/board/atmosalerts name = "Computer Design (Atmosphere Alert)" desc = "Allows for the construction of circuit boards used to build an atmosphere alert console." id = "atmosalerts" req_tech = list("programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/atmos_alert category = list("Computer Boards") -/datum/design/atmos_control +/datum/design/board/atmos_control name = "Computer Design (Atmospheric Monitor)" desc = "Allows for the construction of circuit boards used to build an Atmospheric Monitor." id = "atmos_control" req_tech = list("programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/atmos_control category = list("Computer Boards") -/datum/design/robocontrol +/datum/design/board/robocontrol name = "Computer Design (Robotics Control Console)" desc = "Allows for the construction of circuit boards used to build a Robotics Control console." id = "robocontrol" req_tech = list("programming" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/robotics category = list("Computer Boards") -/datum/design/arcadebattle - name = "Computer Design (Battle Arcade Machine)" - desc = "Allows for the construction of circuit boards used to build a new arcade machine." - id = "arcademachine" - req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) - build_path = /obj/item/weapon/circuitboard/computer/arcade/battle - category = list("Computer Boards") - -/datum/design/orion_trail - name = "Computer Design (Orion Trail Arcade Machine)" - desc = "Allows for the construction of circuit boards used to build a new Orion Trail machine." - id = "arcademachine" - req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) - build_path = /obj/item/weapon/circuitboard/computer/arcade/orion_trail - category = list("Computer Boards") - -/datum/design/slot_machine +/datum/design/board/slot_machine name = "Computer Design (Slot Machine)" desc = "Allows for the construction of circuit boards used to build a new slot machine." id = "slotmachine" req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/slot_machine category = list("Computer Boards") -/datum/design/powermonitor +/datum/design/board/powermonitor name = "Computer Design (Power Monitor)" desc = "Allows for the construction of circuit boards used to build a new power monitor." id = "powermonitor" req_tech = list("programming" = 2, "powerstorage" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/powermonitor category = list("Computer Boards") -/datum/design/solarcontrol +/datum/design/board/solarcontrol name = "Computer Design (Solar Control)" desc = "Allows for the construction of circuit boards used to build a solar control console." id = "solarcontrol" req_tech = list("programming" = 2, "powerstorage" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/solar_control category = list("Computer Boards") -/datum/design/prisonmanage +/datum/design/board/prisonmanage name = "Computer Design (Prisoner Management Console)" desc = "Allows for the construction of circuit boards used to build a prisoner management console." id = "prisonmanage" req_tech = list("programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/prisoner category = list("Computer Boards") -/datum/design/mechacontrol +/datum/design/board/mechacontrol name = "Computer Design (Exosuit Control Console)" desc = "Allows for the construction of circuit boards used to build an exosuit control console." id = "mechacontrol" req_tech = list("programming" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/mecha_control category = list("Computer Boards") -/datum/design/mechapower +/datum/design/board/mechapower name = "Computer Design (Mech Bay Power Control Console)" desc = "Allows for the construction of circuit boards used to build a mech bay power control console." id = "mechapower" req_tech = list("programming" = 3, "powerstorage" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/mech_bay_power_console category = list("Computer Boards") -/datum/design/rdconsole +/datum/design/board/rdconsole name = "Computer Design (R&D Console)" desc = "Allows for the construction of circuit boards used to build a new R&D console." id = "rdconsole" req_tech = list("programming" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/rdconsole category = list("Computer Boards") -/datum/design/cargo +/datum/design/board/cargo name = "Computer Design (Supply Console)" desc = "Allows for the construction of circuit boards used to build a Supply Console." id = "cargo" req_tech = list("programming" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/cargo category = list("Computer Boards") -/datum/design/cargorequest +/datum/design/board/cargorequest name = "Computer Design (Supply Request Console)" desc = "Allows for the construction of circuit boards used to build a Supply Request Console." id = "cargorequest" req_tech = list("programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/cargo/request category = list("Computer Boards") -/datum/design/mining +/datum/design/board/mining name = "Computer Design (Outpost Status Display)" desc = "Allows for the construction of circuit boards used to build an outpost status display console." id = "mining" req_tech = list("programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/mining category = list("Computer Boards") -/datum/design/comm_monitor +/datum/design/board/comm_monitor name = "Computer Design (Telecommunications Monitoring Console)" desc = "Allows for the construction of circuit boards used to build a telecommunications monitor." id = "comm_monitor" req_tech = list("programming" = 3, "magnets" = 3, "bluespace" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/comm_monitor category = list("Computer Boards") -/datum/design/comm_server +/datum/design/board/comm_server name = "Computer Design (Telecommunications Server Monitoring Console)" desc = "Allows for the construction of circuit boards used to build a telecommunication server browser and monitor." id = "comm_server" req_tech = list("programming" = 3, "magnets" = 3, "bluespace" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/comm_server category = list("Computer Boards") -/datum/design/message_monitor +/datum/design/board/message_monitor name = "Computer Design (Messaging Monitor Console)" desc = "Allows for the construction of circuit boards used to build a messaging monitor console." id = "message_monitor" req_tech = list("programming" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/message_monitor category = list("Computer Boards") -/datum/design/aifixer +/datum/design/board/aifixer name = "Computer Design (AI Integrity Restorer)" desc = "Allows for the construction of circuit boards used to build an AI Integrity Restorer." id = "aifixer" req_tech = list("programming" = 4, "magnets" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/aifixer category = list("Computer Boards") -/datum/design/libraryconsole +/datum/design/board/libraryconsole name = "Computer Design (Library Console)" desc = "Allows for the construction of circuit boards used to build a new library console." id = "libraryconsole" req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/libraryconsole category = list("Computer Boards") diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 6a0bf146ea3..3ed57ca5fea 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -2,482 +2,387 @@ //////////////MISC Boards/////////////// //////////////////////////////////////// -/datum/design/smes +/datum/design/board/smes name = "Machine Design (SMES Board)" desc = "The circuit board for a SMES." id = "smes" req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/smes category = list ("Engineering Machinery") -/datum/design/announcement_system +/datum/design/board/announcement_system name = "Machine Design (Automated Announcement System Board)" desc = "The circuit board for an automated announcement system." id = "automated_announcement" req_tech = list("programming" = 3, "bluespace" = 3, "magnets" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/announcement_system category = list("Subspace Telecomms") -/datum/design/turbine_computer +/datum/design/board/turbine_computer name = "Computer Design (Power Turbine Console Board)" desc = "The circuit board for a power turbine console." id = "power_turbine_console" req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/turbine_computer category = list ("Engineering Machinery") -/datum/design/emitter +/datum/design/board/emitter name = "Machine Design (Emitter Board)" desc = "The circuit board for an emitter." id = "emitter" req_tech = list("programming" = 3, "powerstorage" = 5, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/emitter category = list ("Engineering Machinery") -/datum/design/power_compressor +/datum/design/board/power_compressor name = "Machine Design (Power Compressor Board)" desc = "The circuit board for a power compressor." id = "power_compressor" req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/power_compressor category = list ("Engineering Machinery") -/datum/design/power_turbine +/datum/design/board/power_turbine name = "Machine Design (Power Turbine Board)" desc = "The circuit board for a power turbine." id = "power_turbine" req_tech = list("programming" = 4, "powerstorage" = 4, "engineering" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/power_turbine category = list ("Engineering Machinery") -/datum/design/thermomachine +/datum/design/board/thermomachine name = "Machine Design (Freezer/Heater Board)" desc = "The circuit board for a freezer/heater." id = "thermomachine" req_tech = list("programming" = 3, "plasmatech" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/thermomachine category = list ("Engineering Machinery") -/datum/design/space_heater +/datum/design/board/space_heater name = "Machine Design (Space Heater Board)" desc = "The circuit board for a space heater." id = "space_heater" req_tech = list("programming" = 2, "engineering" = 2, "plasmatech" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/space_heater category = list ("Engineering Machinery") -/datum/design/teleport_station +/datum/design/board/teleport_station name = "Machine Design (Teleportation Station Board)" desc = "The circuit board for a teleportation station." id = "tele_station" req_tech = list("programming" = 5, "bluespace" = 4, "engineering" = 4, "plasmatech" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/teleporter_station category = list ("Teleportation Machinery") -/datum/design/teleport_hub +/datum/design/board/teleport_hub name = "Machine Design (Teleportation Hub Board)" desc = "The circuit board for a teleportation hub." id = "tele_hub" req_tech = list("programming" = 3, "bluespace" = 5, "materials" = 4, "engineering" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/teleporter_hub category = list ("Teleportation Machinery") -/datum/design/telepad +/datum/design/board/telepad name = "Machine Design (Telepad Board)" desc = "The circuit board for a telescience telepad." id = "telepad" req_tech = list("programming" = 4, "bluespace" = 5, "plasmatech" = 4, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/telesci_pad category = list ("Teleportation Machinery") -/datum/design/teleconsole +/datum/design/board/teleconsole name = "Computer Design (Teleporter Console)" desc = "Allows for the construction of circuit boards used to build a teleporter control console." id = "teleconsole" req_tech = list("programming" = 3, "bluespace" = 3, "plasmatech" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/teleporter category = list("Teleportation Machinery") -/datum/design/telesci_console +/datum/design/board/telesci_console name = "Computer Design (Telepad Control Console Board)" desc = "Allows for the construction of circuit boards used to build a telescience console." id = "telesci_console" req_tech = list("programming" = 3, "bluespace" = 3, "plasmatech" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/telesci_console category = list("Teleportation Machinery") -/datum/design/sleeper +/datum/design/board/sleeper name = "Machine Design (Sleeper Board)" desc = "The circuit board for a sleeper." id = "sleeper" req_tech = list("programming" = 3, "biotech" = 2, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/sleeper category = list ("Medical Machinery") -/datum/design/cryotube +/datum/design/board/cryotube name = "Machine Design (Cryotube Board)" desc = "The circuit board for a cryotube." id = "cryotube" req_tech = list("programming" = 5, "biotech" = 3, "engineering" = 4, "plasmatech" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/cryo_tube category = list ("Medical Machinery") -/datum/design/chem_dispenser +/datum/design/board/chem_dispenser name = "Machine Design (Portable Chem Dispenser Board)" desc = "The circuit board for a portable chem dispenser." id = "chem_dispenser" req_tech = list("programming" = 5, "biotech" = 3, "materials" = 4, "plasmatech" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/chem_dispenser category = list ("Medical Machinery") -/datum/design/chem_master +/datum/design/board/chem_master name = "Machine Design (Chem Master Board)" - desc = "The circuit board for a Chem Master 2999." + desc = "The circuit board for a Chem Master 3000." id = "chem_master" req_tech = list("biotech" = 3, "materials" = 3, "programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/chem_master category = list ("Medical Machinery") -/datum/design/chem_heater +/datum/design/board/chem_heater name = "Machine Design (Chemical Heater Board)" desc = "The circuit board for a chemical heater." id = "chem_heater" req_tech = list("engineering" = 2, "biotech" = 2, "programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/chem_heater category = list ("Medical Machinery") -/datum/design/clonecontrol +/datum/design/board/clonecontrol name = "Computer Design (Cloning Machine Console)" desc = "Allows for the construction of circuit boards used to build a new Cloning Machine console." id = "clonecontrol" req_tech = list("programming" = 4, "biotech" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/cloning category = list("Medical Machinery") -/datum/design/clonepod +/datum/design/board/clonepod name = "Machine Design (Clone Pod)" desc = "Allows for the construction of circuit boards used to build a Cloning Pod." id = "clonepod" req_tech = list("programming" = 4, "biotech" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/clonepod category = list("Medical Machinery") -/datum/design/clonescanner +/datum/design/board/clonescanner name = "Machine Design (Cloning Scanner)" desc = "Allows for the construction of circuit boards used to build a Cloning Scanner." id = "clonescanner" req_tech = list("programming" = 4, "biotech" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/clonescanner category = list("Medical Machinery") -/datum/design/biogenerator +/datum/design/board/biogenerator name = "Machine Design (Biogenerator Board)" desc = "The circuit board for a biogenerator." id = "biogenerator" req_tech = list("programming" = 2, "biotech" = 3, "materials" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/biogenerator category = list ("Hydroponics Machinery") -/datum/design/hydroponics +/datum/design/board/hydroponics name = "Machine Design (Hydroponics Tray Board)" desc = "The circuit board for a hydroponics tray." id = "hydro_tray" req_tech = list("biotech" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/hydroponics category = list ("Hydroponics Machinery") -/datum/design/destructive_analyzer +/datum/design/board/destructive_analyzer name = "Machine Design (Destructive Analyzer Board)" desc = "The circuit board for a destructive analyzer." id = "destructive_analyzer" req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/destructive_analyzer category = list("Research Machinery") -/datum/design/experimentor +/datum/design/board/experimentor name = "Machine Design (E.X.P.E.R.I-MENTOR Board)" desc = "The circuit board for an E.X.P.E.R.I-MENTOR." id = "experimentor" req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2, "bluespace" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/experimentor category = list("Research Machinery") -/datum/design/protolathe +/datum/design/board/protolathe name = "Machine Design (Protolathe Board)" desc = "The circuit board for a protolathe." id = "protolathe" req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/protolathe category = list("Research Machinery") -/datum/design/circuit_imprinter +/datum/design/board/circuit_imprinter name = "Machine Design (Circuit Imprinter Board)" desc = "The circuit board for a circuit imprinter." id = "circuit_imprinter" req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/circuit_imprinter category = list("Research Machinery") -/datum/design/rdservercontrol +/datum/design/board/rdservercontrol name = "Computer Design (R&D Server Control Console Board)" desc = "The circuit board for an R&D Server Control Console." id = "rdservercontrol" req_tech = list("programming" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/computer/rdservercontrol category = list("Research Machinery") -/datum/design/rdserver +/datum/design/board/rdserver name = "Machine Design (R&D Server Board)" desc = "The circuit board for an R&D Server." id = "rdserver" req_tech = list("programming" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/rdserver category = list("Research Machinery") -/datum/design/mechfab +/datum/design/board/mechfab name = "Machine Design (Exosuit Fabricator Board)" desc = "The circuit board for an Exosuit Fabricator." id = "mechfab" req_tech = list("programming" = 3, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/mechfab category = list("Research Machinery") -/datum/design/cyborgrecharger +/datum/design/board/cyborgrecharger name = "Machine Design (Cyborg Recharger Board)" desc = "The circuit board for a Cyborg Recharger." id = "cyborgrecharger" req_tech = list("powerstorage" = 3, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/cyborgrecharger category = list("Research Machinery") -/datum/design/mech_recharger +/datum/design/board/mech_recharger name = "Machine Design (Mechbay Recharger Board)" desc = "The circuit board for a Mechbay Recharger." id = "mech_recharger" req_tech = list("programming" = 3, "powerstorage" = 4, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/mech_recharger category = list("Research Machinery") -/datum/design/microwave +/datum/design/board/microwave name = "Machine Design (Microwave Board)" desc = "The circuit board for a microwave." id = "microwave" req_tech = list("programming" = 2, "magnets" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/microwave category = list ("Misc. Machinery") -/datum/design/gibber +/datum/design/board/gibber name = "Machine Design (Gibber Board)" desc = "The circuit board for a gibber." id = "gibber" req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/gibber category = list ("Misc. Machinery") -/datum/design/smartfridge +/datum/design/board/smartfridge name = "Machine Design (Smartfridge Board)" desc = "The circuit board for a smartfridge." id = "smartfridge" req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/smartfridge category = list ("Misc. Machinery") -/datum/design/monkey_recycler +/datum/design/board/monkey_recycler name = "Machine Design (Monkey Recycler Board)" desc = "The circuit board for a monkey recycler." id = "smartfridge" req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/monkey_recycler category = list ("Misc. Machinery") -/datum/design/seed_extractor +/datum/design/board/seed_extractor name = "Machine Design (Seed Extractor Board)" desc = "The circuit board for a seed extractor." id = "seed_extractor" req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/seed_extractor category = list ("Misc. Machinery") -/datum/design/processor +/datum/design/board/processor name = "Machine Design (Processor Board)" desc = "The circuit board for a processor." id = "processor" req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/processor category = list ("Misc. Machinery") -/datum/design/recycler +/datum/design/board/recycler name = "Machine Design (Recycler Board)" desc = "The circuit board for a recycler." id = "recycler" req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/recycler category = list ("Misc. Machinery") -/datum/design/holopad +/datum/design/board/holopad name = "Machine Design (AI Holopad Board)" desc = "The circuit board for a holopad." id = "holopad" req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/holopad category = list ("Misc. Machinery") -/datum/design/autolathe +/datum/design/board/autolathe name = "Machine Design (Autolathe Board)" desc = "The circuit board for an autolathe." id = "autolathe" req_tech = list("programming" = 3, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/autolathe category = list ("Misc. Machinery") -/datum/design/recharger +/datum/design/board/recharger name = "Machine Design (Weapon Recharger Board)" desc = "The circuit board for a Weapon Recharger." id = "recharger" req_tech = list("powerstorage" = 4, "engineering" = 3, "materials" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20, MAT_GOLD = 100) + materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/weapon/circuitboard/machine/recharger category = list("Misc. Machinery") -/datum/design/vendor +/datum/design/board/vendor name = "Machine Design (Vendor Board)" desc = "The circuit board for a Vendor." id = "vendor" req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/vendor category = list ("Misc. Machinery") -/datum/design/ore_redemption +/datum/design/board/ore_redemption name = "Machine Design (Ore Redemption Board)" desc = "The circuit board for an Ore Redemption machine." id = "ore_redemption" req_tech = list("programming" = 2, "engineering" = 2, "plasmatech" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/ore_redemption category = list ("Misc. Machinery") -/datum/design/mining_equipment_vendor +/datum/design/board/mining_equipment_vendor name = "Machine Design (Mining Rewards Vender Board)" desc = "The circuit board for a Mining Rewards Vender." id = "mining_equipment_vendor" req_tech = list("engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/mining_equipment_vendor category = list ("Misc. Machinery") -/datum/design/tesla_coil +/datum/design/board/tesla_coil name = "Machine Design (Tesla Coil Board)" desc = "The circuit board for a tesla coil." id = "tesla_coil" req_tech = list("programming" = 3, "powerstorage" = 3, "magnets" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/tesla_coil category = list ("Misc. Machinery") -/datum/design/grounding_rod +/datum/design/board/grounding_rod name = "Machine Design (Grounding Rod Board)" desc = "The circuit board for a grounding rod." id = "grounding_rod" req_tech = list("programming" = 3, "powerstorage" = 3, "magnets" = 3, "plasmatech" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/grounding_rod category = list ("Misc. Machinery") -/datum/design/plantgenes +/datum/design/board/plantgenes name = "Machine Design (Plant DNA Manipulator Board)" desc = "The circuit board for a plant DNA manipulator." id = "plantgenes" req_tech = list("programming" = 4, "biotech" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/plantgenes category = list ("Misc. Machinery") diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm index 6805fac443e..ebfece1ddbc 100644 --- a/code/modules/research/designs/mecha_designs.dm +++ b/code/modules/research/designs/mecha_designs.dm @@ -2,163 +2,136 @@ //////////Mecha Module Disks/////// /////////////////////////////////// -/datum/design/ripley_main +/datum/design/board/ripley_main name = "APLU \"Ripley\" Central Control module" desc = "Allows for the construction of a \"Ripley\" Central Control module." id = "ripley_main" req_tech = list("programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/ripley/main category = list("Exosuit Modules") -/datum/design/ripley_peri +/datum/design/board/ripley_peri name = "APLU \"Ripley\" Peripherals Control module" desc = "Allows for the construction of a \"Ripley\" Peripheral Control module." id = "ripley_peri" req_tech = list("programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/ripley/peripherals category = list("Exosuit Modules") -/datum/design/odysseus_main + +/datum/design/board/odysseus_main name = "\"Odysseus\" Central Control module" desc = "Allows for the construction of a \"Odysseus\" Central Control module." id = "odysseus_main" req_tech = list("programming" = 3,"biotech" = 3, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/odysseus/main category = list("Exosuit Modules") -/datum/design/odysseus_peri +/datum/design/board/odysseus_peri name = "\"Odysseus\" Peripherals Control module" desc = "Allows for the construction of a \"Odysseus\" Peripheral Control module." id = "odysseus_peri" req_tech = list("programming" = 3,"biotech" = 3, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/odysseus/peripherals category = list("Exosuit Modules") -/datum/design/gygax_main + +/datum/design/board/gygax_main name = "\"Gygax\" Central Control module" desc = "Allows for the construction of a \"Gygax\" Central Control module." id = "gygax_main" req_tech = list("programming" = 4, "combat" = 3, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/gygax/main category = list("Exosuit Modules") -/datum/design/gygax_peri +/datum/design/board/gygax_peri name = "\"Gygax\" Peripherals Control module" desc = "Allows for the construction of a \"Gygax\" Peripheral Control module." id = "gygax_peri" req_tech = list("programming" = 4, "combat" = 3, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/gygax/peripherals category = list("Exosuit Modules") -/datum/design/gygax_targ +/datum/design/board/gygax_targ name = "\"Gygax\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Gygax\" Weapons & Targeting Control module." id = "gygax_targ" req_tech = list("programming" = 4, "combat" = 4, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/gygax/targeting category = list("Exosuit Modules") -/datum/design/durand_main + +/datum/design/board/durand_main name = "\"Durand\" Central Control module" desc = "Allows for the construction of a \"Durand\" Central Control module." id = "durand_main" req_tech = list("programming" = 4, "combat" = 4, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/main category = list("Exosuit Modules") -/datum/design/durand_peri +/datum/design/board/durand_peri name = "\"Durand\" Peripherals Control module" desc = "Allows for the construction of a \"Durand\" Peripheral Control module." id = "durand_peri" req_tech = list("programming" = 4, "combat" = 4, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/peripherals category = list("Exosuit Modules") -/datum/design/durand_targ +/datum/design/board/durand_targ name = "\"Durand\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Durand\" Weapons & Targeting Control module." id = "durand_targ" req_tech = list("programming" = 5, "combat" = 4, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/targeting category = list("Exosuit Modules") -/datum/design/honker_main + +/datum/design/board/honker_main name = "\"H.O.N.K\" Central Control module" desc = "Allows for the construction of a \"H.O.N.K\" Central Control module." id = "honker_main" req_tech = list("programming" = 3, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/honker/main category = list("Exosuit Modules") -/datum/design/honker_peri +/datum/design/board/honker_peri name = "\"H.O.N.K\" Peripherals Control module" desc = "Allows for the construction of a \"H.O.N.K\" Peripheral Control module." id = "honker_peri" req_tech = list("programming" = 3, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/honker/peripherals category = list("Exosuit Modules") -/datum/design/honker_targ +/datum/design/board/honker_targ name = "\"H.O.N.K\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"H.O.N.K\" Weapons & Targeting Control module." id = "honker_targ" req_tech = list("programming" = 3, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/honker/targeting category = list("Exosuit Modules") -/datum/design/phazon_main + +/datum/design/board/phazon_main name = "\"Phazon\" Central Control module" desc = "Allows for the construction of a \"Phazon\" Central Control module." id = "phazon_main" req_tech = list("programming" = 6, "materials" = 6, "plasmatech" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/phazon/main category = list("Exosuit Modules") -/datum/design/phazon_peri +/datum/design/board/phazon_peri name = "\"Phazon\" Peripherals Control module" desc = "Allows for the construction of a \"Phazon\" Peripheral Control module." id = "phazon_peri" req_tech = list("programming" = 6, "bluespace" = 5, "plasmatech" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/phazon/peripherals category = list("Exosuit Modules") -/datum/design/phazon_targ +/datum/design/board/phazon_targ name = "\"Phazon\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Phazon\" Weapons & Targeting Control module." id = "phazon_targ" req_tech = list("programming" = 6, "magnets" = 5, "plasmatech" = 5) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/phazon/targeting category = list("Exosuit Modules") diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm index ba9f113e2e4..c474db4f2fb 100644 --- a/code/modules/research/designs/power_designs.dm +++ b/code/modules/research/designs/power_designs.dm @@ -68,32 +68,24 @@ build_path = /obj/item/device/lightreplacer category = list("Power Designs") -/datum/design/pacman +/datum/design/board/pacman name = "Machine Design (PACMAN-type Generator Board)" desc = "The circuit board that for a PACMAN-type portable generator." id = "pacman" req_tech = list("programming" = 2, "plasmatech" = 3, "powerstorage" = 3, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/pacman category = list("Engineering Machinery") -/datum/design/superpacman +/datum/design/board/pacman/super name = "Machine Design (SUPERPACMAN-type Generator Board)" desc = "The circuit board that for a SUPERPACMAN-type portable generator." id = "superpacman" req_tech = list("programming" = 3, "powerstorage" = 4, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/pacman/super - category = list("Engineering Machinery") -/datum/design/mrspacman +/datum/design/board/pacman/mrs name = "Machine Design (MRSPACMAN-type Generator Board)" desc = "The circuit board that for a MRSPACMAN-type portable generator." id = "mrspacman" req_tech = list("programming" = 3, "powerstorage" = 5, "engineering" = 5, "plasmatech" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/pacman/mrs - category = list("Engineering Machinery") diff --git a/code/modules/research/designs/telecomms_designs.dm b/code/modules/research/designs/telecomms_designs.dm index f63ee2fe2d5..a9bfa208893 100644 --- a/code/modules/research/designs/telecomms_designs.dm +++ b/code/modules/research/designs/telecomms_designs.dm @@ -2,72 +2,58 @@ /////Subspace Telecomms//////////// /////////////////////////////////// -/datum/design/subspace_receiver +/datum/design/board/subspace_receiver name = "Machine Design (Subspace Receiver)" desc = "Allows for the construction of Subspace Receiver equipment." id = "s-receiver" req_tech = list("programming" = 2, "engineering" = 2, "bluespace" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/telecomms/receiver category = list("Subspace Telecomms") -/datum/design/telecomms_bus +/datum/design/board/telecomms_bus name = "Machine Design (Bus Mainframe)" desc = "Allows for the construction of Telecommunications Bus Mainframes." id = "s-bus" req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/telecomms/bus category = list("Subspace Telecomms") -/datum/design/telecomms_hub +/datum/design/board/telecomms_hub name = "Machine Design (Hub Mainframe)" desc = "Allows for the construction of Telecommunications Hub Mainframes." id = "s-hub" req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/telecomms/hub category = list("Subspace Telecomms") -/datum/design/telecomms_relay +/datum/design/board/telecomms_relay name = "Machine Design (Relay Mainframe)" desc = "Allows for the construction of Telecommunications Relay Mainframes." id = "s-relay" req_tech = list("programming" = 2, "engineering" = 2, "bluespace" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/telecomms/relay category = list("Subspace Telecomms") -/datum/design/telecomms_processor +/datum/design/board/telecomms_processor name = "Machine Design (Processor Unit)" desc = "Allows for the construction of Telecommunications Processor equipment." id = "s-processor" req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/telecomms/processor category = list("Subspace Telecomms") -/datum/design/telecomms_server +/datum/design/board/telecomms_server name = "Machine Design (Server Mainframe)" desc = "Allows for the construction of Telecommunications Servers." id = "s-server" req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/telecomms/server category = list("Subspace Telecomms") -/datum/design/subspace_broadcaster +/datum/design/board/subspace_broadcaster name = "Machine Design (Subspace Broadcaster)" desc = "Allows for the construction of Subspace Broadcasting equipment." id = "s-broadcaster" req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/machine/telecomms/broadcaster category = list("Subspace Telecomms") diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 743f65bcc88..3aef80ce616 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -200,7 +200,7 @@ //WT550 Mags /datum/design/mag_oldsmg - name = "WT-550 Auto Gun Magazine (4.6×30mm)" + name = "WT-550 Auto Gun Magazine (4.6x30mm)" desc = "A 20 round magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg" req_tech = list("combat" = 1, "materials" = 1) @@ -210,21 +210,21 @@ category = list("Ammo") /datum/design/mag_oldsmg/ap_mag - name = "WT-550 Auto Gun Armour Piercing Magazine (4.6×30mm AP)" + name = "WT-550 Auto Gun Armour Piercing Magazine (4.6x30mm AP)" desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_ap" materials = list(MAT_METAL = 6000, MAT_SILVER = 600) build_path = /obj/item/ammo_box/magazine/wt550m9/wtap /datum/design/mag_oldsmg/ic_mag - name = "WT-550 Auto Gun Incendiary Magazine (4.6×30mm IC)" + name = "WT-550 Auto Gun Incendiary Magazine (4.6x30mm IC)" desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_ic" materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_GLASS = 1000) build_path = /obj/item/ammo_box/magazine/wt550m9/wtic /datum/design/mag_oldsmg/tx_mag - name = "WT-550 Auto Gun Uranium Magazine (4.6×30mm TX)" + name = "WT-550 Auto Gun Uranium Magazine (4.6x30mm TX)" desc = "A 20 round uranium tipped magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_tx" materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_URANIUM = 2000) @@ -268,4 +268,4 @@ build_type = PROTOLATHE materials = list(MAT_SILVER = 7000, MAT_GOLD = 7000, MAT_URANIUM = 6000, MAT_GLASS = 6000, MAT_METAL = 6000, MAT_DIAMOND = 3000) build_path = /obj/item/weapon/gun/energy/gravity_gun - category = list("Weapons") \ No newline at end of file + category = list("Weapons") diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index ff1e2ef9c75..9af5ba770e9 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -29,17 +29,14 @@ Note: Must be placed west/left of and R&D console to function. "Firing Pins" ) - reagents = new() - /obj/machinery/r_n_d/protolathe/New() ..() - materials = new(src, list(MAT_METAL=1, MAT_GLASS=1, MAT_SILVER=1, MAT_GOLD=1, MAT_DIAMOND=1, MAT_PLASMA=1, MAT_URANIUM=1, MAT_BANANIUM=1)) + create_reagents(0) + materials = new(src, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM)) var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/protolathe(null) B.apply_default_parts(src) - reagents.my_atom = src - /obj/item/weapon/circuitboard/machine/protolathe name = "circuit board (Protolathe)" build_path = /obj/machinery/r_n_d/protolathe @@ -66,13 +63,13 @@ Note: Must be placed west/left of and R&D console to function. efficiency_coeff = min(max(0, T), 1) /obj/machinery/r_n_d/protolathe/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material + var/list/all_materials = being_built.reagents + being_built.materials + var/A = materials.amount(M) if(!A) A = reagents.get_reagent_amount(M) - A = A / max(1, (being_built.reagents[M])) - else - A = A / max(1, (being_built.materials[M])) - return A + + return round(A / max(1, (all_materials[M]*efficiency_coeff))) //we eject the materials upon deconstruction. /obj/machinery/r_n_d/protolathe/deconstruction() @@ -88,11 +85,15 @@ Note: Must be placed west/left of and R&D console to function. /obj/machinery/r_n_d/protolathe/Insert_Item(obj/item/O, mob/user) - if(istype(O,/obj/item/stack/sheet)) + if(istype(O, /obj/item/stack/sheet)) . = 1 - if(!is_insertion_ready(user) || busy) + if(!is_insertion_ready(user)) return - if(!materials.has_space( materials.get_item_material_amount(O) )) + var/sheet_material = materials.get_item_material_amount(O) + if(!sheet_material) + return + + if(!materials.has_space(sheet_material)) user << "The [src.name]'s material bin is full! Please remove material before adding more." return 1 @@ -116,5 +117,6 @@ Note: Must be placed west/left of and R&D console to function. else if(user.a_intent != "harm") user << "You cannot insert this item into the [name]!" + return 1 else return 0 diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 9f31eff821b..dfd361a885b 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -45,6 +45,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/screen = 1.0 //Which screen is currently showing. var/id = 0 //ID of the computer (for server restrictions). var/sync = 1 //If sync = 0, it doesn't show up on Server Control Console + var/first_use = 1 //If first_use = 1, it will try to auto-connect with nearby devices req_access = list(access_tox) //Data and setting manipulation requires scientist access. @@ -53,37 +54,20 @@ won't update every console in existence) but it's more of a hassle to do. Also, /proc/CallTechName(ID) //A simple helper proc to find the name of a tech with a given ID. - for(var/T in subtypesof(/datum/tech)) - var/datum/tech/tt = T - if(initial(tt.id) == ID) - return initial(tt.name) + if(tech_list[ID]) + var/datum/tech/tech = tech_list[ID] + return tech.name + return "ERROR: Report This" -proc/CallMaterialName(ID) - if (copytext(ID, 1, 2) == "$") - var/return_name = copytext(ID, 2) - switch(return_name) - if("metal") - return_name = "Metal" - if("glass") - return_name = "Glass" - if("gold") - return_name = "Gold" - if("silver") - return_name = "Silver" - if("plasma") - return_name = "Solid Plasma" - if("uranium") - return_name = "Uranium" - if("diamond") - return_name = "Diamond" - if("clown") - return_name = "Bananium" - return return_name - else - for(var/R in subtypesof(/datum/reagent)) - var/datum/reagent/rr = R - if(initial(rr.id) == ID) - return initial(rr.name) +/proc/CallMaterialName(ID) + if (copytext(ID, 1, 2) == "$" && materials_list[ID]) + var/datum/material/material = materials_list[ID] + return material.name + + else if(chemical_reagents_list[ID]) + var/datum/reagent/reagent = chemical_reagents_list[ID] + return reagent.name + return "ERROR: Report This" /obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any). for(var/obj/machinery/r_n_d/D in oview(3,src)) @@ -101,7 +85,7 @@ proc/CallMaterialName(ID) if(linked_imprinter == null) linked_imprinter = D D.linked_console = src - return + first_use = 0 //Have it automatically push research to the centcom server so wild griffins can't fuck up R&D's work --NEO /obj/machinery/computer/rdconsole/proc/griefProtection() @@ -124,9 +108,6 @@ proc/CallMaterialName(ID) S.initialize() break -/obj/machinery/computer/rdconsole/initialize() - SyncRDevices() - /* Instead of calling this every tick, it is only being called when needed /obj/machinery/computer/rdconsole/process() griefProtection() @@ -231,10 +212,15 @@ proc/CallMaterialName(ID) var/datum/design/D = files.known_designs[href_list["copy_design_ID"]] if(D) var/autolathe_friendly = 1 - for(var/x in D.materials) - if( !(x in list(MAT_METAL, MAT_GLASS))) - autolathe_friendly = 0 - D.category -= "Imported" + if(D.reagents.len) + autolathe_friendly = 0 + D.category -= "Imported" + else + for(var/x in D.materials) + if( !(x in list(MAT_METAL, MAT_GLASS))) + autolathe_friendly = 0 + D.category -= "Imported" + if(D.build_type & (AUTOLATHE|PROTOLATHE|CRAFTLATHE)) // Specifically excludes circuit imprinter and mechfab D.build_type = autolathe_friendly ? (D.build_type | AUTOLATHE) : D.build_type D.category |= "Imported" @@ -253,60 +239,59 @@ proc/CallMaterialName(ID) screen = 1.0 else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder. - if(linked_destroy) - if(linked_destroy.busy) - usr << "The destructive analyzer is busy at the moment." - return - var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) - var/cancontinue = FALSE - for(var/T in temp_tech) - if(files.IsTechHigher(T, temp_tech[T])) - cancontinue = TRUE - break - if(!cancontinue) - var/choice = input("This item does not raise tech levels. Proceed destroying loaded item anyway?") in list("Proceed", "Cancel") - if(choice == "Cancel" || !linked_destroy) return - linked_destroy.busy = 1 - screen = 0.1 + if(!linked_destroy || linked_destroy.busy || !linked_destroy.loaded_item) updateUsrDialog() - flick("d_analyzer_process", linked_destroy) - spawn(24) - if(linked_destroy) - linked_destroy.busy = 0 - if(!linked_destroy.loaded_item) - usr <<"The destructive analyzer appears to be empty." - screen = 1.0 - return + return - for(var/T in temp_tech) - var/datum/tech/KT = files.known_tech[T] //For stat logging of high levels - if(files.IsTechHigher(T, temp_tech[T]) && KT.level >= 5) //For stat logging of high levels - feedback_add_details("high_research_level","[KT][KT.level + 1]") //+1 to show the level which we're about to get - files.UpdateTech(T, temp_tech[T]) + var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) + var/cancontinue = FALSE + for(var/T in temp_tech) + if(files.IsTechHigher(T, temp_tech[T])) + cancontinue = TRUE + break + if(!cancontinue) + var/choice = input("This item does not raise tech levels. Proceed destroying loaded item anyway?") in list("Proceed", "Cancel") + if(choice == "Cancel" || !linked_destroy || !linked_destroy.loaded_item) return + linked_destroy.busy = 1 + screen = 0.1 + updateUsrDialog() + flick("d_analyzer_process", linked_destroy) + spawn(24) + if(linked_destroy) + linked_destroy.busy = 0 + if(!linked_destroy.loaded_item) + screen = 1.0 + return - if(linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. - for(var/material in linked_destroy.loaded_item.materials) - linked_lathe.materials.insert_amount(min((linked_lathe.materials.max_amount - linked_lathe.materials.total_amount), (linked_destroy.loaded_item.materials[material]*(linked_destroy.decon_mod/10))), material) - feedback_add_details("item_deconstructed","[linked_destroy.loaded_item.type]") - linked_destroy.loaded_item = null - for(var/obj/I in linked_destroy.contents) - for(var/mob/M in I.contents) - M.death() - if(istype(I,/obj/item/stack/sheet))//Only deconsturcts one sheet at a time instead of the entire stack - var/obj/item/stack/sheet/S = I - if(S.amount > 1) - S.amount-- - linked_destroy.loaded_item = S - else - qdel(S) - linked_destroy.icon_state = "d_analyzer" + for(var/T in temp_tech) + var/datum/tech/KT = files.known_tech[T] //For stat logging of high levels + if(files.IsTechHigher(T, temp_tech[T]) && KT.level >= 5) //For stat logging of high levels + feedback_add_details("high_research_level","[KT][KT.level + 1]") //+1 to show the level which we're about to get + files.UpdateTech(T, temp_tech[T]) + + if(linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. + for(var/material in linked_destroy.loaded_item.materials) + linked_lathe.materials.insert_amount(min((linked_lathe.materials.max_amount - linked_lathe.materials.total_amount), (linked_destroy.loaded_item.materials[material]*(linked_destroy.decon_mod/10))), material) + feedback_add_details("item_deconstructed","[linked_destroy.loaded_item.type]") + linked_destroy.loaded_item = null + for(var/obj/I in linked_destroy.contents) + for(var/mob/M in I.contents) + M.death() + if(istype(I,/obj/item/stack/sheet))//Only deconsturcts one sheet at a time instead of the entire stack + var/obj/item/stack/sheet/S = I + if(S.amount > 1) + S.amount-- + linked_destroy.loaded_item = S else - if(!(I in linked_destroy.component_parts)) - qdel(I) - linked_destroy.icon_state = "d_analyzer" - screen = 1.0 - use_power(250) - updateUsrDialog() + qdel(S) + linked_destroy.icon_state = "d_analyzer" + else + if(!(I in linked_destroy.component_parts)) + qdel(I) + linked_destroy.icon_state = "d_analyzer" + screen = 1.0 + use_power(250) + updateUsrDialog() else if(href_list["lock"]) //Lock the console from use by anyone without tox access. if(src.allowed(usr)) @@ -353,183 +338,166 @@ proc/CallMaterialName(ID) sync = !sync else if(href_list["build"]) //Causes the Protolathe to build something. - if(linked_lathe) - if(linked_lathe.busy) - usr << "Protolathe is busy at the moment." - return - var/coeff = linked_lathe.efficiency_coeff - var/g2g = 1 - var/datum/design/being_built = files.known_designs[href_list["build"]] - if(being_built) - var/power = 2000 - var/amount=text2num(href_list["amount"]) - var/old_screen = screen - amount = max(1, min(10, amount)) - for(var/M in being_built.materials) - power += round(being_built.materials[M] * amount / 5) - power = max(2000, power) - screen = 0.3 - var/key = usr.key //so we don't lose the info during the spawn delay - if (!(being_built.build_type & PROTOLATHE)) + var/datum/design/being_built = files.known_designs[href_list["build"]] + var/amount = text2num(href_list["amount"]) + + if(!linked_lathe || !being_built || !amount) + updateUsrDialog() + return + + if(linked_lathe.busy) + usr << "Protolathe is busy at the moment." + return + + var/coeff = linked_lathe.efficiency_coeff + var/power = 1000 + var/old_screen = screen + + amount = max(1, min(10, amount)) + for(var/M in being_built.materials) + power += round(being_built.materials[M] * amount / 5) + power = max(3000, power) + screen = 0.3 + var/key = usr.key //so we don't lose the info during the spawn delay + if (!(being_built.build_type & PROTOLATHE)) + message_admins("Protolathe exploit attempted by [key_name(usr, usr.client)]!") + updateUsrDialog() + return + + var/g2g = 1 + var/enough_materials = 1 + linked_lathe.busy = 1 + flick("protolathe_n",linked_lathe) + use_power(power) + + var/list/efficient_mats = list() + for(var/MAT in being_built.materials) + efficient_mats[MAT] = being_built.materials[MAT]*coeff + + if(!linked_lathe.materials.has_materials(efficient_mats, amount)) + linked_lathe.say("Not enough materials to complete prototype.") + enough_materials = 0 + g2g = 0 + else + for(var/R in being_built.reagents) + if(!linked_lathe.reagents.has_reagent(R, being_built.reagents[R]*coeff)) + linked_lathe.say("Not enough reagents to complete prototype.") + enough_materials = 0 g2g = 0 - message_admins("Protolathe exploit attempted by [key_name(usr, usr.client)]!") - if (g2g) //If input is incorrect, nothing happens - var/enough_materials = 1 - linked_lathe.busy = 1 - flick("protolathe_n",linked_lathe) - use_power(power) + if(enough_materials) + linked_lathe.materials.use_amount(efficient_mats, amount) + for(var/R in being_built.reagents) + linked_lathe.reagents.remove_reagent(R, being_built.reagents[R]*coeff) - var/list/efficient_mats = list() - for(var/MAT in being_built.materials) - efficient_mats[MAT] = being_built.materials[MAT]*coeff - - if(!linked_lathe.materials.has_materials(efficient_mats, amount)) - src.visible_message("The [src.name] beeps, \"Not enough materials to complete prototype.\"") - enough_materials = 0 - g2g = 0 - else - for(var/R in being_built.reagents) - if(!linked_lathe.reagents.has_reagent(R, being_built.reagents[R])*coeff) - src.visible_message("The [src.name] beeps, \"Not enough reagents to complete prototype.\"") - enough_materials = 0 - g2g = 0 - - if(enough_materials) - linked_lathe.materials.use_amount(efficient_mats, amount) - for(var/R in being_built.reagents) - linked_lathe.reagents.remove_reagent(R, being_built.reagents[R]*coeff) - - var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. - spawn(32*coeff*amount**0.8) - if(linked_lathe) - if(g2g) //And if we only fail the material requirements, we still spend time and power - var/already_logged = 0 - for(var/i = 0, iThe [src.name] beeps, \"Something went wrong, production halted!\"") - screen = 1.0 - updateUsrDialog() + var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. + spawn(32*coeff*amount**0.8) + if(linked_lathe) + if(g2g) //And if we only fail the material requirements, we still spend time and power + var/already_logged = 0 + for(var/i = 0, iCircuit Imprinter is busy at the moment." + updateUsrDialog() + return + var/coeff = linked_imprinter.efficiency_coeff + + var/power = 1000 + var/old_screen = screen + for(var/M in being_built.materials) + power += round(being_built.materials[M] / 5) + power = max(4000, power) + screen = 0.4 + if (!(being_built.build_type & IMPRINTER)) + message_admins("Circuit imprinter exploit attempted by [key_name(usr, usr.client)]!") + updateUsrDialog() + return + var/g2g = 1 - if(linked_imprinter) - if(linked_imprinter.busy) - usr << "Circuit Imprinter is busy at the moment." - return - var/datum/design/being_built = files.known_designs[href_list["imprint"]] - if(being_built) - var/power = 2000 - var/old_screen = screen - for(var/M in being_built.materials) - power += round(being_built.materials[M] / 5) - power = max(2000, power) - screen = 0.4 - if (!(being_built.build_type & IMPRINTER)) + var/enough_materials = 1 + linked_imprinter.busy = 1 + flick("circuit_imprinter_ani", linked_imprinter) + use_power(power) + + var/list/efficient_mats = list() + for(var/MAT in being_built.materials) + efficient_mats[MAT] = being_built.materials[MAT]/coeff + + if(!linked_imprinter.materials.has_materials(efficient_mats)) + linked_imprinter.say("Not enough materials to complete prototype.") + enough_materials = 0 + g2g = 0 + else + for(var/R in being_built.reagents) + if(!linked_imprinter.reagents.has_reagent(R, being_built.reagents[R]/coeff)) + linked_imprinter.say("Not enough reagents to complete prototype.") + enough_materials = 0 g2g = 0 - message_admins("Circuit imprinter exploit attempted by [key_name(usr, usr.client)]!") - if (g2g) //Again, if input is wrong, do nothing - linked_imprinter.busy = 1 - flick("circuit_imprinter_ani",linked_imprinter) - use_power(power) + if(enough_materials) + linked_imprinter.materials.use_amount(efficient_mats) + for(var/R in being_built.reagents) + linked_imprinter.reagents.remove_reagent(R, being_built.reagents[R]/coeff) - for(var/M in being_built.materials) - if(!linked_imprinter.check_mat(being_built, M)) - src.visible_message("The [src.name] beeps, \"Not enough materials to complete prototype.\"") - g2g = 0 - break - switch(M) - if(MAT_GLASS) - linked_imprinter.g_amount = max(0, (linked_imprinter.g_amount-being_built.materials[M]/coeff)) - if(MAT_GOLD) - linked_imprinter.gold_amount = max(0, (linked_imprinter.gold_amount-being_built.materials[M]/coeff)) - if(MAT_DIAMOND) - linked_imprinter.diamond_amount = max(0, (linked_imprinter.diamond_amount-being_built.materials[M]/coeff)) - else - linked_imprinter.reagents.remove_reagent(M, being_built.materials[M]/coeff) - - var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. - spawn(16) - if(linked_imprinter) - if(g2g) - var/obj/item/new_item = new P(src) - new_item.loc = linked_imprinter.loc - feedback_add_details("circuit_printed","[new_item.type]") - screen = old_screen - linked_imprinter.busy = 0 - else - src.visible_message("The [src.name] beeps, \"Something went wrong, production halted!\"") - screen = 1.0 - updateUsrDialog() - - else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) - linked_imprinter.reagents.del_reagent(href_list["disposeI"]) - - else if(href_list["disposeallI"] && linked_imprinter) //Causes the circuit imprinter to dispose of all it's reagents. - linked_imprinter.reagents.clear_reagents() + var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. + spawn(16) + if(linked_imprinter) + if(g2g) + var/obj/item/new_item = new P(src) + new_item.loc = linked_imprinter.loc + new_item.materials = efficient_mats.Copy() + feedback_add_details("circuit_printed","[new_item.type]") + screen = old_screen + linked_imprinter.busy = 0 + else + say("Circuit Imprinter connection failed. Production halted.") + screen = 1.0 + updateUsrDialog() + //Protolathe Materials else if(href_list["disposeP"] && linked_lathe) //Causes the protolathe to dispose of a single reagent (all of it) linked_lathe.reagents.del_reagent(href_list["disposeP"]) else if(href_list["disposeallP"] && linked_lathe) //Causes the protolathe to dispose of all it's reagents. linked_lathe.reagents.clear_reagents() - else if(href_list["lathe_ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material - var/desired_num_sheets = text2num(href_list["lathe_ejectsheet_amt"]) - var/MAT - switch(href_list["lathe_ejectsheet"]) - if("metal") - MAT = MAT_METAL - if("glass") - MAT = MAT_GLASS - if("gold") - MAT = MAT_GOLD - if("silver") - MAT = MAT_SILVER - if("plasma") - MAT = MAT_PLASMA - if("uranium") - MAT = MAT_URANIUM - if("diamond") - MAT = MAT_DIAMOND - if("clown") - MAT = MAT_BANANIUM - linked_lathe.materials.retrieve_sheets(desired_num_sheets, MAT) + else if(href_list["ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material + linked_lathe.materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["ejectsheet"]) + + //Circuit Imprinter Materials + else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) + linked_imprinter.reagents.del_reagent(href_list["disposeI"]) + + else if(href_list["disposeallI"] && linked_imprinter) //Causes the circuit imprinter to dispose of all it's reagents. + linked_imprinter.reagents.clear_reagents() + + else if(href_list["imprinter_ejectsheet"] && linked_imprinter) //Causes the imprinter to eject a sheet of material + linked_imprinter.materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["imprinter_ejectsheet"]) - else if(href_list["imprinter_ejectsheet"] && linked_imprinter) //Causes the protolathe to eject a sheet of material - var/desired_num_sheets = text2num(href_list["imprinter_ejectsheet_amt"]) - var/res_amount, type - switch(href_list["imprinter_ejectsheet"]) - if("glass") - type = /obj/item/stack/sheet/glass - res_amount = "g_amount" - if("gold") - type = /obj/item/stack/sheet/mineral/gold - res_amount = "gold_amount" - if("diamond") - type = /obj/item/stack/sheet/mineral/diamond - res_amount = "diamond_amount" - if(ispath(type) && hasvar(linked_imprinter, res_amount)) - var/obj/item/stack/sheet/sheet = new type(linked_imprinter.loc) - var/available_num_sheets = round(linked_imprinter.vars[res_amount]/sheet.perunit) - if(available_num_sheets>0) - sheet.amount = min(available_num_sheets, desired_num_sheets) - linked_imprinter.vars[res_amount] = max(0, (linked_imprinter.vars[res_amount]-sheet.amount * sheet.perunit)) - else - qdel(sheet) else if(href_list["find_device"]) //The R&D console looks for devices nearby to link up with. screen = 0.0 @@ -591,6 +559,10 @@ proc/CallMaterialName(ID) /obj/machinery/computer/rdconsole/interact(mob/user) user.set_machine(src) + + if(first_use) + SyncRDevices() + var/dat = "" files.RefreshResearch() switch(screen) //A quick check to make sure you get the right screen when a device is disconnected. @@ -705,13 +677,13 @@ proc/CallMaterialName(ID) if(b_type) dat += "Lathe Types:
" if(b_type & IMPRINTER) dat += "Circuit Imprinter
" - if(b_type & PROTOLATHE) dat += "Proto-lathe
" - if(b_type & AUTOLATHE) dat += "Auto-lathe
" - if(b_type & MECHFAB) dat += "Mech Fabricator
" + if(b_type & PROTOLATHE) dat += "Protolathe
" + if(b_type & AUTOLATHE) dat += "Autolathe
" + if(b_type & MECHFAB) dat += "Exosuit Fabricator
" dat += "Required Materials:
" - for(var/M in d_disk.blueprint.materials) - if(copytext(M, 1, 2) == "$") dat += "* [copytext(M, 2)] x [d_disk.blueprint.materials[M]]
" - else dat += "* [M] x [d_disk.blueprint.materials[M]]
" + var/all_mats = d_disk.blueprint.materials + d_disk.blueprint.reagents + for(var/M in all_mats) + dat += "* [CallMaterialName(M)] x [all_mats[M]]
" dat += "
Operations: " dat += "Upload to Database" dat += "Clear Disk" @@ -779,11 +751,10 @@ proc/CallMaterialName(ID) var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) for(var/T in temp_tech) dat += "* [CallTechName(T)] [temp_tech[T]]" - for(var/v in files.known_tech) - var/datum/tech/F = files.known_tech[v] - if(F.name == CallTechName(T)) - dat += " (Current: [F.level])" - break + var/datum/tech/F = files.known_tech[T] + if(F) + dat += " (Current: [F.level])" + dat += "
" dat += "