From f8d51270789ded9eff9286c0ed079c087470d08b Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 21 Jun 2015 01:20:39 -0400 Subject: [PATCH 01/10] Adds SLOT_EARS to various items --- code/game/objects/items/devices/flashlight.dm | 1 + code/game/objects/items/devices/radio/encryptionkey.dm | 1 + code/game/objects/items/devices/spy_bug.dm | 1 + code/game/objects/items/toys.dm | 3 +++ code/game/objects/items/weapons/cigs_lighters.dm | 3 +++ code/game/objects/items/weapons/cosmetics.dm | 2 ++ code/game/objects/items/weapons/dna_injector.dm | 1 + code/game/objects/items/weapons/surgery_tools.dm | 1 + code/game/objects/items/weapons/tools.dm | 2 +- code/modules/detectivework/evidence.dm | 1 + code/modules/mining/coins.dm | 1 + .../living/carbon/human/species/xenomorphs/alien_facehugger.dm | 2 +- code/modules/mob/living/simple_animal/constructs/soulstone.dm | 2 +- code/modules/paperwork/paper_bundle.dm | 2 +- code/modules/projectiles/ammunition.dm | 2 +- code/modules/projectiles/guns/launcher/syringe_gun.dm | 2 +- code/modules/reagents/reagent_containers/dropper.dm | 1 + code/modules/reagents/reagent_containers/pill.dm | 1 + code/modules/reagents/reagent_containers/syringes.dm | 1 + code/modules/spells/spellbook.dm | 2 +- 20 files changed, 25 insertions(+), 7 deletions(-) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 29bcbc4332..2b0f5920ce 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -87,6 +87,7 @@ icon_state = "penlight" item_state = "" flags = CONDUCT + slot_flags = SLOT_EARS brightness_on = 2 w_class = 1 diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index 823940a53c..3056ce5275 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -6,6 +6,7 @@ icon_state = "cypherkey" item_state = "" w_class = 1 + slot_flags = SLOT_EARS var/translate_binary = 0 var/translate_hive = 0 var/syndie = 0 diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm index 2ad3df7ae5..b283ed889c 100644 --- a/code/game/objects/items/devices/spy_bug.dm +++ b/code/game/objects/items/devices/spy_bug.dm @@ -9,6 +9,7 @@ flags = CONDUCT force = 5.0 w_class = 1.0 + slot_flags = SLOT_EARS throwforce = 5.0 throw_range = 15 throw_speed = 3 diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index dcb12f2a5d..9632e66564 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -314,6 +314,7 @@ icon = 'icons/obj/toy.dmi' icon_state = "foamdart" w_class = 1.0 + slot_flags = SLOT_EARS /obj/effect/foam_dart_dummy name = "" @@ -486,6 +487,8 @@ icon = 'icons/obj/toy.dmi' icon_state = "bosunwhistle" var/cooldown = 0 + w_class = 1 + slot_flags = SLOT_EARS /obj/item/toy/bosunwhistle/attack_self(mob/user as mob) if(cooldown < world.time - 35) diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index da22352a72..2cd16fd561 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -38,6 +38,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/burnt = 0 var/smoketime = 5 w_class = 1.0 + slot_flags = SLOT_EARS origin_tech = "materials=1" attack_verb = list("burnt", "singed") @@ -210,6 +211,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM throw_speed = 0.5 item_state = "cigoff" w_class = 1 + slot_flags = SLOT_EARS attack_verb = list("burnt", "singed") icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi icon_off = "cigoff" @@ -294,6 +296,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon = 'icons/obj/clothing/masks.dmi' icon_state = "cigbutt" w_class = 1 + slot_flags = SLOT_EARS throwforce = 1 /obj/item/weapon/cigbutt/New() diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 437daa86bb..0f0f850ca0 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -5,6 +5,7 @@ icon = 'icons/obj/items.dmi' icon_state = "lipstick" w_class = 1.0 + slot_flags = SLOT_EARS var/colour = "red" var/open = 0 @@ -71,6 +72,7 @@ name = "purple comb" desc = "A pristine purple comb made from flexible plastic." w_class = 1.0 + slot_flags = SLOT_EARS icon = 'icons/obj/items.dmi' icon_state = "purplecomb" item_state = "purplecomb" diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index b94fd2d360..7c685a9e1d 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -9,6 +9,7 @@ throw_speed = 1 throw_range = 5 w_class = 1.0 + slot_flags = SLOT_EARS var/uses = 1 var/nofail var/is_bullet = 0 diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index d15441b032..786b90329a 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -83,6 +83,7 @@ sharp = 1 edge = 1 w_class = 1 + slot_flags = SLOT_EARS throwforce = 5.0 throw_speed = 3 throw_range = 5 diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index fad3035563..5f83f32581 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -38,7 +38,7 @@ icon = 'icons/obj/items.dmi' icon_state = "screwdriver" flags = CONDUCT - slot_flags = SLOT_BELT + slot_flags = SLOT_BELT | SLOT_EARS force = 5.0 w_class = 1.0 throwforce = 5.0 diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm index f115d9f9a9..898dbbaf1d 100644 --- a/code/modules/detectivework/evidence.dm +++ b/code/modules/detectivework/evidence.dm @@ -119,6 +119,7 @@ item_state = "paper" throwforce = 1 w_class = 1.0 + slot_flags = SLOT_EARS throw_speed = 3 throw_range = 5 diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm index 6ddf02609a..7491bf668d 100644 --- a/code/modules/mining/coins.dm +++ b/code/modules/mining/coins.dm @@ -8,6 +8,7 @@ force = 0.0 throwforce = 0.0 w_class = 1.0 + slot_flags = SLOT_EARS var/string_attached var/sides = 2 diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm index 68e106ee1d..d6767fbbc4 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm @@ -14,7 +14,7 @@ var/const/MAX_ACTIVE_TIME = 400 icon = 'icons/mob/alien.dmi' icon_state = "facehugger" item_state = "facehugger" - w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4 + w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4 flags = MASKCOVERSMOUTH | MASKCOVERSEYES | AIRTIGHT body_parts_covered = FACE|EYES throw_range = 5 diff --git a/code/modules/mob/living/simple_animal/constructs/soulstone.dm b/code/modules/mob/living/simple_animal/constructs/soulstone.dm index 2fa81f08c8..5859969d03 100644 --- a/code/modules/mob/living/simple_animal/constructs/soulstone.dm +++ b/code/modules/mob/living/simple_animal/constructs/soulstone.dm @@ -7,7 +7,7 @@ icon_state = "soulstone" item_state = "electronic" desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefacts power." - w_class = 1.0 + w_class = 2 slot_flags = SLOT_BELT origin_tech = "bluespace=4;materials=4" var/imprinted = "empty" diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index 409dd3e5f0..c99edc57b9 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -5,7 +5,7 @@ icon_state = "paper" item_state = "paper" throwforce = 0 - w_class = 1.0 + w_class = 2 throw_range = 2 throw_speed = 1 layer = 4 diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 52ca04e655..bb23b9c3ee 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/ammo.dmi' icon_state = "s-casing" flags = CONDUCT - slot_flags = SLOT_BELT + slot_flags = SLOT_BELT | SLOT_EARS throwforce = 1 w_class = 1 var/caliber = "" //Which kind of guns it can be loaded into diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm index 8acbcce8b2..07cb48d784 100644 --- a/code/modules/projectiles/guns/launcher/syringe_gun.dm +++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm @@ -6,7 +6,7 @@ var/icon_flight = "syringe-cartridge-flight" //so it doesn't look so weird when shot matter = list(DEFAULT_WALL_MATERIAL = 125, "glass" = 375) flags = CONDUCT - slot_flags = SLOT_BELT + slot_flags = SLOT_BELT | SLOT_EARS throwforce = 3 force = 3 w_class = 1 diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 44fd6b1a49..e6e6f3ac29 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -9,6 +9,7 @@ amount_per_transfer_from_this = 5 possible_transfer_amounts = list(1,2,3,4,5) w_class = 1 + slot_flags = SLOT_EARS volume = 5 afterattack(var/obj/target, var/mob/user, var/flag) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index bb405828ee..bab7fc5be6 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -9,6 +9,7 @@ item_state = "pill" possible_transfer_amounts = null w_class = 1 + slot_flags = SLOT_EARS volume = 60 New() diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index a221c31b10..0f3076fdb6 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -16,6 +16,7 @@ possible_transfer_amounts = null volume = 15 w_class = 1 + slot_flags = SLOT_EARS sharp = 1 var/mode = SYRINGE_DRAW var/image/filling //holds a reference to the current filling overlay diff --git a/code/modules/spells/spellbook.dm b/code/modules/spells/spellbook.dm index 169d750944..70d92f0183 100644 --- a/code/modules/spells/spellbook.dm +++ b/code/modules/spells/spellbook.dm @@ -5,7 +5,7 @@ icon_state ="spellbook" throw_speed = 1 throw_range = 5 - w_class = 1.0 + w_class = 2 var/uses = 5 var/temp = null var/max_uses = 5 From 2f1a6eaf83bbd13844ff5c237aed7b1873295782 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 21 Jun 2015 01:21:43 -0400 Subject: [PATCH 02/10] Adjusts w_class of beach ball and scroll --- code/defines/obj.dm | 2 +- code/game/objects/items/weapons/scrolls.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/defines/obj.dm b/code/defines/obj.dm index a70822942f..65f34ed580 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -310,7 +310,7 @@ var/global/ManifestJSON item_state = "beachball" density = 0 anchored = 0 - w_class = 2.0 + w_class = 4 force = 0.0 throwforce = 0.0 throw_speed = 1 diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm index 92ba323a6a..19a99c7f93 100644 --- a/code/game/objects/items/weapons/scrolls.dm +++ b/code/game/objects/items/weapons/scrolls.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/wizard.dmi' icon_state = "scroll" var/uses = 4.0 - w_class = 2.0 + w_class = 1 item_state = "paper" throw_speed = 4 throw_range = 20 From 4605d19b7900d52181e6f485f95e7f4ffc1ee864 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 20 Jun 2015 12:17:24 -0400 Subject: [PATCH 03/10] Fixes #9280 --- code/game/machinery/alarm.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index b5bd66f4cf..ebc3e5e6db 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -518,8 +518,8 @@ data["total_danger"] = max(oxygen_danger, data["total_danger"]) current_settings = TLV["carbon dioxide"] - var/carbon_dioxide_danger = get_danger_level(environment.gas["carbon dioxide"]*partial_pressure, current_settings) - environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon dioxide"] / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger) + var/carbon_dioxide_danger = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, current_settings) + environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon_dioxide"] / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger) data["total_danger"] = max(carbon_dioxide_danger, data["total_danger"]) current_settings = TLV["phoron"] From 712dc391859de3fb244c233ad1f15a4f753a35a5 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 20 Jun 2015 14:23:58 -0400 Subject: [PATCH 04/10] Fixes #9729 --- code/game/objects/items/weapons/storage/backpack.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 541b41f74d..f9a236e20c 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -241,8 +241,10 @@ name = "captain's satchel" desc = "An exclusive satchel for Nanotrasen officers." icon_state = "satchel-cap" - item_state = "captainpack" - item_state_slots = null + item_state_slots = list( + slot_l_hand_str = "satchel-cap", + slot_r_hand_str = "satchel-cap", + ) //ERT backpacks. /obj/item/weapon/storage/backpack/ert From 1678cc5b96970ecdb8ae17e312b0af172ea0619d Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 20 Jun 2015 15:52:48 -0400 Subject: [PATCH 05/10] Removes CRASH() --- code/game/atoms_movable.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 95bf4aa94d..38431627eb 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -22,7 +22,6 @@ /atom/movable/Del() if(isnull(gcDestroyed) && loc) testing("GC: -- [type] was deleted via del() rather than qdel() --") - CRASH() // Debug until I can get a clean server start. // else if(isnull(gcDestroyed)) // testing("GC: [type] was deleted via GC without qdel()") //Not really a huge issue but from now on, please qdel() // else From 80c80abe3abf4a8d6f1461870aa0d59e9f1bc229 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 21 Jun 2015 02:39:25 -0400 Subject: [PATCH 06/10] Fixes #9511 --- code/modules/shuttles/shuttle_specops.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/shuttles/shuttle_specops.dm b/code/modules/shuttles/shuttle_specops.dm index 078d1e9a5a..b4e791670e 100644 --- a/code/modules/shuttles/shuttle_specops.dm +++ b/code/modules/shuttles/shuttle_specops.dm @@ -23,6 +23,10 @@ docking_controller_offsite = locate(docking_controller_tag_offsite) if(!istype(docking_controller_offsite)) world << "warning: shuttle with docking tag [docking_controller_offsite] could not find it's controller!" + if (!location) + docking_controller = docking_controller_station + else + docking_controller = docking_controller_offsite /datum/shuttle/ferry/multidock/move(var/area/origin,var/area/destination) ..(origin, destination) From ec5e05b9f1835fc65a9d773c1aff2badb6ab0629 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Sun, 21 Jun 2015 14:35:33 +0930 Subject: [PATCH 07/10] Antagonist system refactor. Fixes #9495, #9290, #9521, #8800 and #9465. --- baystation12.dme | 11 +- code/controllers/voting.dm | 2 +- code/datums/mind.dm | 2 +- code/game/antagonist/_antagonist_setup.dm | 72 ++++++ code/game/antagonist/alien/xenomorph.dm | 4 +- code/game/antagonist/antagonist.dm | 223 +++--------------- code/game/antagonist/antagonist_add.dm | 22 ++ ...tagonist_build.dm => antagonist_create.dm} | 151 ++++++------ code/game/antagonist/antagonist_equip.dm | 17 ++ code/game/antagonist/antagonist_globals.dm | 41 ---- code/game/antagonist/antagonist_helpers.dm | 14 +- code/game/antagonist/antagonist_objectives.dm | 13 +- code/game/antagonist/antagonist_panel.dm | 61 +++++ code/game/antagonist/antagonist_place.dm | 29 +++ code/game/antagonist/antagonist_print.dm | 88 +++++++ code/game/antagonist/antagonist_spawn.dm | 85 ------- code/game/antagonist/antagonist_update.dm | 76 ++++++ code/game/antagonist/outsider/deathsquad.dm | 14 +- code/game/antagonist/outsider/ert.dm | 7 +- code/game/antagonist/outsider/mercenary.dm | 8 +- code/game/antagonist/outsider/ninja.dm | 4 +- code/game/antagonist/outsider/raider.dm | 7 +- code/game/antagonist/outsider/wizard.dm | 3 +- code/game/antagonist/station/changeling.dm | 2 +- code/game/antagonist/station/cultist.dm | 2 - code/game/antagonist/station/revolutionary.dm | 34 ++- code/game/gamemodes/game_mode.dm | 6 +- code/game/mecha/mecha.dm | 3 +- code/game/response_team.dm | 40 +--- code/modules/admin/player_panel.dm | 40 +--- code/modules/admin/topic.dm | 8 +- code/modules/events/random_antagonist.dm | 2 +- .../mob/living/silicon/robot/drone/drone.dm | 15 +- code/setup.dm | 12 - 34 files changed, 598 insertions(+), 520 deletions(-) create mode 100644 code/game/antagonist/_antagonist_setup.dm create mode 100644 code/game/antagonist/antagonist_add.dm rename code/game/antagonist/{antagonist_build.dm => antagonist_create.dm} (50%) create mode 100644 code/game/antagonist/antagonist_equip.dm delete mode 100644 code/game/antagonist/antagonist_globals.dm create mode 100644 code/game/antagonist/antagonist_panel.dm create mode 100644 code/game/antagonist/antagonist_place.dm create mode 100644 code/game/antagonist/antagonist_print.dm delete mode 100644 code/game/antagonist/antagonist_spawn.dm create mode 100644 code/game/antagonist/antagonist_update.dm diff --git a/baystation12.dme b/baystation12.dme index edec632f08..88966c957f 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -212,12 +212,17 @@ #include "code\game\skincmd.dm" #include "code\game\sound.dm" #include "code\game\supplyshuttle.dm" +#include "code\game\antagonist\_antagonist_setup.dm" #include "code\game\antagonist\antagonist.dm" -#include "code\game\antagonist\antagonist_build.dm" -#include "code\game\antagonist\antagonist_globals.dm" +#include "code\game\antagonist\antagonist_add.dm" +#include "code\game\antagonist\antagonist_create.dm" +#include "code\game\antagonist\antagonist_equip.dm" #include "code\game\antagonist\antagonist_helpers.dm" #include "code\game\antagonist\antagonist_objectives.dm" -#include "code\game\antagonist\antagonist_spawn.dm" +#include "code\game\antagonist\antagonist_panel.dm" +#include "code\game\antagonist\antagonist_place.dm" +#include "code\game\antagonist\antagonist_print.dm" +#include "code\game\antagonist\antagonist_update.dm" #include "code\game\antagonist\alien\borer.dm" #include "code\game\antagonist\alien\xenomorph.dm" #include "code\game\antagonist\outsider\commando.dm" diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index f4b88f8850..939dd34e7e 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -237,7 +237,7 @@ datum/controller/vote return 0 for(var/antag_type in all_antag_types) var/datum/antagonist/antag = all_antag_types[antag_type] - if(!(antag.id in additional_antag_types) && (antag.flags & ANTAG_VOTABLE)) + if(!(antag.id in additional_antag_types) && antag.is_votable()) choices.Add(antag.role_text) choices.Add("None") if("custom") diff --git a/code/datums/mind.dm b/code/datums/mind.dm index fac5c75fc3..0e7e42d152 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -143,7 +143,7 @@ if(href_list["add_antagonist"]) var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]] - if(antag) antag.add_antagonist(src) + if(antag) antag.add_antagonist(src, 1, 1, 0, 1, 1) // Ignore equipment and role type for this. else if(href_list["remove_antagonist"]) var/datum/antagonist/antag = all_antag_types[href_list["remove_antagonist"]] diff --git a/code/game/antagonist/_antagonist_setup.dm b/code/game/antagonist/_antagonist_setup.dm new file mode 100644 index 0000000000..ebf22a21c9 --- /dev/null +++ b/code/game/antagonist/_antagonist_setup.dm @@ -0,0 +1,72 @@ +/* + MODULAR ANTAGONIST SYSTEM + + Attempts to move all the bullshit snowflake antag tracking code into its own system, which + has the added bonus of making the display procs consistent. Still needs work/adjustment/cleanup + but should be fairly self-explanatory with a review of the procs. Will supply a few examples + of common tasks that the system will be expected to perform below. ~Z + + To use: + - Get the appropriate datum via get_antag_data("antagonist id") + using the id var of the desired /datum/antagonist ie. var/datum/antagonist/A = get_antag_data("traitor") + - Call add_antagonist() on the desired target mind ie. A.add_antagonist(mob.mind) + - To ignore protected roles, supply a positive second argument. + - To skip equipping with appropriate gear, supply a positive third argument. +*/ + +// Antagonist datum flags. +#define ANTAG_OVERRIDE_JOB 1 // Assigned job is set to MODE when spawning. +#define ANTAG_OVERRIDE_MOB 2 // Mob is recreated from datum mob_type var when spawning. +#define ANTAG_CLEAR_EQUIPMENT 4 // All preexisting equipment is purged. +#define ANTAG_CHOOSE_NAME 8 // Antagonists are prompted to enter a name. +#define ANTAG_IMPLANT_IMMUNE 16 // Cannot be loyalty implanted. +#define ANTAG_SUSPICIOUS 32 // Shows up on roundstart report. +#define ANTAG_HAS_LEADER 64 // Generates a leader antagonist. +#define ANTAG_HAS_NUKE 128 // Will spawn a nuke at supplied location. +#define ANTAG_RANDSPAWN 256 // Potentially randomly spawns due to events. +#define ANTAG_VOTABLE 512 // Can be voted as an additional antagonist before roundstart. +#define ANTAG_SET_APPEARANCE 1024 // Causes antagonists to use an appearance modifier on spawn. + +// Globals. +var/global/list/all_antag_types = list() +var/global/list/all_antag_spawnpoints = list() +var/global/list/antag_names_to_ids = list() + +// Global procs. +/proc/get_antag_data(var/antag_type) + if(all_antag_types[antag_type]) + return all_antag_types[antag_type] + else + for(var/cur_antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[cur_antag_type] + if(antag && antag.is_type(antag_type)) + return antag + +/proc/clear_antag_roles(var/datum/mind/player, var/implanted) + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(!implanted || !(antag.flags & ANTAG_IMPLANT_IMMUNE)) + antag.remove_antagonist(player, 1, implanted) + +/proc/update_antag_icons(var/datum/mind/player) + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(player) + antag.update_icons_removed(player) + if(antag.is_antagonist(player)) + antag.update_icons_added(player) + else + antag.update_all_icons() + +/proc/populate_antag_type_list() + for(var/antag_type in typesof(/datum/antagonist)-/datum/antagonist) + var/datum/antagonist/A = new antag_type + all_antag_types[A.id] = A + all_antag_spawnpoints[A.landmark_id] = list() + antag_names_to_ids[A.role_text] = A.id + +/proc/get_antags(var/atype) + var/datum/antagonist/antag = all_antag_types[atype] + if(antag && islist(antag.current_antagonists)) + return antag.current_antagonists + return list() \ No newline at end of file diff --git a/code/game/antagonist/alien/xenomorph.dm b/code/game/antagonist/alien/xenomorph.dm index 1ab79f26b5..f93409a820 100644 --- a/code/game/antagonist/alien/xenomorph.dm +++ b/code/game/antagonist/alien/xenomorph.dm @@ -26,12 +26,12 @@ var/datum/antagonist/xenos/xenomorphs /datum/antagonist/xenos/Topic(href, href_list) if (..()) return - if(href_list["move_to_spawn"]) place_mob(href_list["move_to_spawn"]) + if(href_list["move_to_spawn"]) place_mob(locate(href_list["move_to_spawn"])) /datum/antagonist/xenos/get_extra_panel_options(var/datum/mind/player) return "\[move to vent\]" -/datum/antagonist/xenos/random_spawn() +/datum/antagonist/xenos/attempt_random_spawn() if(config.aliens_allowed) ..() /datum/antagonist/xenos/proc/get_vents() diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index aad02b1c6c..c7cbde15ab 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -42,209 +42,64 @@ var/default_access = list() var/id_type = /obj/item/weapon/card/id + var/announced /datum/antagonist/New() ..() cur_max = max_antags get_starting_locations() + if(!role_text_plural) + role_text_plural = role_text if(config.protect_roles_from_antagonist) restricted_jobs |= protected_jobs /datum/antagonist/proc/tick() return 1 -/datum/antagonist/proc/get_panel_entry(var/datum/mind/player) +/datum/antagonist/proc/get_candidates(var/ghosts_only) - var/dat = "[role_text]:" - var/extra = get_extra_panel_options(player) - if(is_antagonist(player)) - dat += "\[-\]" - dat += "\[equip\]" - if(starting_locations && starting_locations.len) - dat += "\[move to spawn\]" - if(extra) dat += "[extra]" - else - dat += "\[+\]" - dat += "" + candidates = list() // Clear. + candidates = ticker.mode.get_players_for_role(role_type, id) + // Prune restricted jobs and status. + for(var/datum/mind/player in candidates) + if((ghosts_only && !istype(player.current, /mob/dead)) || player.special_role || (player.assigned_role in restricted_jobs)) + candidates -= player + return candidates - return dat +/datum/antagonist/proc/attempt_random_spawn() + attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB)) -/datum/antagonist/proc/get_extra_panel_options() - return +/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player, var/move_to_spawn) -/datum/antagonist/proc/get_starting_locations() - if(landmark_id) - starting_locations = list() - for(var/obj/effect/landmark/L in landmarks_list) - if(L.name == landmark_id) - starting_locations |= get_turf(L) - -/datum/antagonist/proc/place_all_mobs() - if(!starting_locations || !starting_locations.len || !current_antagonists || !current_antagonists.len) - return - for(var/datum/mind/player in current_antagonists) - player.current.loc = pick(starting_locations) - -/datum/antagonist/proc/finalize(var/datum/mind/target) - - // This will fail if objectives have already been generated. - create_global_objectives() - - if(leader && flags & ANTAG_HAS_NUKE && !spawned_nuke) - make_nuke(leader) - - if(target) - apply(target) - create_objectives(target) - update_icons_added(target) - greet(target) - return - - for(var/datum/mind/player in current_antagonists) - apply(player) - equip(player.current) - create_objectives(player) - update_icons_added(player) - greet(player) - - place_all_mobs() - - spawn(1) - if(spawn_announcement) - if(spawn_announcement_delay) - sleep(spawn_announcement_delay) - if(spawn_announcement_sound) - command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound) - else - command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]") - - -/datum/antagonist/proc/print_player_summary() - - if(!current_antagonists.len) + update_current_antag_max() + if(get_antag_count() >= cur_max) return 0 - var/text = "
The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:" - for(var/datum/mind/P in current_antagonists) - text += print_player_full(P) - text += get_special_objective_text(P) - var/failed - if(!global_objectives.len && P.objectives && P.objectives.len) - var/num = 1 - for(var/datum/objective/O in P.objectives) - text += print_objective(O, num) - if(O.completed) // This is set actively in check_victory() - text += "Success!" - feedback_add_details(feedback_tag,"[O.type]|SUCCESS") - else - text += "Fail." - feedback_add_details(feedback_tag,"[O.type]|FAIL") - failed = 1 - num++ + player.current << "You have been selected this round as an antagonist!" + if(move_to_spawn) + place_mob(player.current) + add_antagonist(player) + equip(player.current) + return - if(!config.objectives_disabled) - if(failed) - text += "
The [role_text] has failed." - else - text += "
The [role_text] was successful!" +/datum/antagonist/proc/attempt_spawn(var/ghosts_only) - if(global_objectives && global_objectives.len) - text += "
Their objectives were:" - var/num = 1 - for(var/datum/objective/O in global_objectives) - text += print_objective(O, num, 1) - num++ + // Get the raw list of potential players. + update_current_antag_max() + candidates = get_candidates(ghosts_only) - // Display the results. - world << text - -/datum/antagonist/proc/print_objective(var/datum/objective/O, var/num, var/append_success) - var/text = "
Objective [num]: [O.explanation_text] " - if(append_success) - if(O.check_completion()) - text += "Success!" - else - text += "Fail." - return text - -/datum/antagonist/proc/print_player_lite(var/datum/mind/ply) - var/role = ply.assigned_role == "MODE" ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]" - var/text = "
[ply.name] ([ply.key]) as \a [role] (" - if(ply.current) - if(ply.current.stat == DEAD) - text += "died" - else if(isNotStationLevel(ply.current.z)) - text += "fled the station" - else - text += "survived" - if(ply.current.real_name != ply.name) - text += " as [ply.current.real_name]" - else - text += "body destroyed" - text += ")" - - return text - -/datum/antagonist/proc/print_player_full(var/datum/mind/ply) - var/text = print_player_lite(ply) - - var/TC_uses = 0 - var/uplink_true = 0 - var/purchases = "" - for(var/obj/item/device/uplink/H in world_uplinks) - if(H && H.uplink_owner && H.uplink_owner == ply) - TC_uses += H.used_TC - uplink_true = 1 - var/list/refined_log = new() - for(var/datum/uplink_item/UI in H.purchase_log) - var/obj/I = new UI.path - refined_log.Add("[H.purchase_log[UI]]x\icon[I][UI.name]") - qdel(I) - purchases = english_list(refined_log, nothing_text = "") - if(uplink_true) - text += " (used [TC_uses] TC)" - if(purchases) - text += "
[purchases]" - - return text - -/datum/antagonist/proc/update_all_icons() - if(!antag_indicator) - return - for(var/datum/mind/antag in current_antagonists) - if(antag.current && antag.current.client) - for(var/image/I in antag.current.client.images) - if(I.icon_state == antag_indicator) - qdel(I) - for(var/datum/mind/other_antag in current_antagonists) - if(other_antag.current) - antag.current.client.images |= image('icons/mob/mob.dmi', loc = other_antag.current, icon_state = antag_indicator) - -/datum/antagonist/proc/update_icons_added(var/datum/mind/player) - if(!antag_indicator || !player.current) - return - spawn(0) - for(var/datum/mind/antag in current_antagonists) - if(!antag.current) - continue - if(antag.current.client) - antag.current.client.images |= image('icons/mob/mob.dmi', loc = player.current, icon_state = antag_indicator) - if(player.current.client) - player.current.client.images |= image('icons/mob/mob.dmi', loc = antag.current, icon_state = antag_indicator) - -/datum/antagonist/proc/update_icons_removed(var/datum/mind/player) - if(!antag_indicator || !player.current) - return - spawn(0) - for(var/datum/mind/antag in current_antagonists) - if(antag.current) - if(antag.current.client) - for(var/image/I in antag.current.client.images) - if(I.icon_state == antag_indicator && I.loc == player.current) - qdel(I) - if(player.current && player.current.client) - for(var/image/I in player.current.client.images) - if(I.icon_state == antag_indicator) - qdel(I) + // Update our boundaries. + if(!candidates.len) + return 0 + //Grab candidates randomly until we have enough. + while(candidates.len) + var/datum/mind/player = pick(candidates) + current_antagonists |= player + // Update job and role. + player.special_role = role_text + if(flags & ANTAG_OVERRIDE_JOB) + player.assigned_role = "MODE" + candidates -= player + return 1 diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm new file mode 100644 index 0000000000..9a0ef84e8d --- /dev/null +++ b/code/game/antagonist/antagonist_add.dm @@ -0,0 +1,22 @@ +/datum/antagonist/proc/add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance) + if(!istype(player)) + return 0 + if(player in current_antagonists) + return 0 + if(!can_become_antag(player, ignore_role)) + return 0 + current_antagonists |= player + create_antagonist(player, move_to_spawn, do_not_announce, preserve_appearance) + if(!do_not_equip && player.current) + equip(player.current) + return 1 + +/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted) + if(player in current_antagonists) + player.current << "You are no longer a [role_text]!" + current_antagonists -= player + player.special_role = null + update_icons_removed(player) + BITSET(player.current.hud_updateflag, SPECIALROLE_HUD) + return 1 + return 0 \ No newline at end of file diff --git a/code/game/antagonist/antagonist_build.dm b/code/game/antagonist/antagonist_create.dm similarity index 50% rename from code/game/antagonist/antagonist_build.dm rename to code/game/antagonist/antagonist_create.dm index 35af4e6f80..c7387d92a8 100644 --- a/code/game/antagonist/antagonist_build.dm +++ b/code/game/antagonist/antagonist_create.dm @@ -1,83 +1,34 @@ -/datum/antagonist/proc/create_objectives(var/datum/mind/player) - if(config.objectives_disabled) +/datum/antagonist/proc/create_antagonist(var/datum/mind/target, var/move, var/gag_announcement, var/preserve_appearance) + + if(!target) + return + + update_antag_mob(target, preserve_appearance) + if(!target.current) + remove_antagonist(target) return 0 - if(global_objectives && global_objectives.len) - player.objectives |= global_objectives - return 1 - -/datum/antagonist/proc/apply(var/datum/mind/player) - - if(flags & ANTAG_HAS_LEADER && !leader) - leader = current_antagonists[1] - - // Get the mob. - if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path)))) - var/mob/holder = player.current - player.current = new mob_path(get_turf(player.current)) - player.transfer_to(player.current) - if(holder) qdel(holder) - - player.original = player.current - return player.current - -/datum/antagonist/proc/equip(var/mob/living/carbon/human/player) - - if(!istype(player)) - return 0 - - // This could use work. - if(flags & ANTAG_CLEAR_EQUIPMENT) - for(var/obj/item/thing in player.contents) - player.drop_from_inventory(thing) - if(thing.loc != player) - qdel(thing) - return 1 - - if(flags & ANTAG_SET_APPEARANCE) - player.change_appearance(APPEARANCE_ALL, player.loc, player, valid_species, state = z_state) - -/datum/antagonist/proc/unequip(var/mob/living/carbon/human/player) - if(!istype(player)) - return 0 - return 1 - -/datum/antagonist/proc/greet(var/datum/mind/player) - - // Basic intro text. - player.current << "You are a [role_text]!" - if(leader_welcome_text && player.current == leader) - player.current << "[leader_welcome_text]" - else - player.current << "[welcome_text]" - show_objectives(player) - - // Choose a name, if any. if(flags & ANTAG_CHOOSE_NAME) - spawn(5) - var/newname = sanitize(input(player.current, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN) - if (newname) - player.current.real_name = newname - player.current.name = player.current.real_name - player.name = player.current.name - // Update any ID cards. - update_access(player.current) + spawn(1) + set_antag_name(target.current) + if(move) + place_mob(target.current) + update_leader() + create_objectives(target) + update_icons_added(target) + greet(target) + announce_antagonist_spawn() - // Clown clumsiness check, I guess downstream might use it. - if (player.current.mind) - if (player.current.mind.assigned_role == "Clown") - player.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself." - player.current.mutations.Remove(CLUMSY) - return 1 - -/datum/antagonist/proc/update_access(var/mob/living/player) - for(var/obj/item/weapon/card/id/id in player.contents) - id.name = "[player.real_name]'s ID Card" - id.registered_name = player.real_name - -/datum/antagonist/proc/random_spawn() - create_global_objectives() - attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB)) - finalize() +/datum/antagonist/proc/create_default(var/mob/source) + var/mob/living/M + if(mob_path) + M = new mob_path() + else + M = new /mob/living/carbon/human + M.real_name = source.real_name + M.name = M.real_name + M.ckey = source.ckey + add_antagonist(M.mind, 1, 0, 1) // Equip them and move them to spawn. + return M /datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player) @@ -96,7 +47,7 @@ player.equip_to_slot_or_del(R, slot_l_ear) return R -/datum/antagonist/proc/make_nuke(var/atom/paper_spawn_loc, var/datum/mind/code_owner) +/datum/antagonist/proc/create_nuke(var/atom/paper_spawn_loc, var/datum/mind/code_owner) // Decide on a code. var/obj/effect/landmark/nuke_spawn = locate(nuke_spawn_loc ? nuke_spawn_loc : "landmark*Nuclear-Bomb") @@ -109,19 +60,59 @@ if(code) if(!paper_spawn_loc) - paper_spawn_loc = get_turf(locate("landmark*Nuclear-Code")) + if(leader && leader.current) + paper_spawn_loc = get_turf(leader.current) + else + paper_spawn_loc = get_turf(locate("landmark*Nuclear-Code")) + if(paper_spawn_loc) // Create and pass on the bomb code paper. var/obj/item/weapon/paper/P = new(paper_spawn_loc) P.info = "The nuclear authorization code is: [code]" P.name = "nuclear bomb code" + if(leader && leader.current) + if(get_turf(P) == get_turf(leader.current) && !(leader.current.l_hand && leader.current.r_hand)) + leader.current.put_in_hands(P) + + if(!code_owner && leader) + code_owner = leader if(code_owner) code_owner.store_memory("Nuclear Bomb Code: [code]", 0, 0) code_owner.current << "The nuclear authorization code is: [code]" - else world << "Could not spawn nuclear bomb. Contact a developer." return spawned_nuke = code return code + +/datum/antagonist/proc/greet(var/datum/mind/player) + + // Basic intro text. + player.current << "You are a [role_text]!" + if(leader_welcome_text && player == leader) + player.current << "[leader_welcome_text]" + else + player.current << "[welcome_text]" + + if((flags & ANTAG_HAS_NUKE) && !spawned_nuke) + create_nuke() + + show_objectives(player) + + // Clown clumsiness check, I guess downstream might use it. + if (player.current.mind) + if (player.current.mind.assigned_role == "Clown") + player.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself." + player.current.mutations.Remove(CLUMSY) + return 1 + +/datum/antagonist/proc/set_antag_name(var/mob/living/player) + // Choose a name, if any. + var/newname = sanitize(input(player, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN) + if (newname) + player.real_name = newname + player.name = player.real_name + if(player.mind) player.mind.name = player.name + // Update any ID cards. + update_access(player) diff --git a/code/game/antagonist/antagonist_equip.dm b/code/game/antagonist/antagonist_equip.dm new file mode 100644 index 0000000000..2f4bc6da3a --- /dev/null +++ b/code/game/antagonist/antagonist_equip.dm @@ -0,0 +1,17 @@ +/datum/antagonist/proc/equip(var/mob/living/carbon/human/player) + + if(!istype(player)) + return 0 + + // This could use work. + if(flags & ANTAG_CLEAR_EQUIPMENT) + for(var/obj/item/thing in player.contents) + player.drop_from_inventory(thing) + if(thing.loc != player) + qdel(thing) + return 1 + +/datum/antagonist/proc/unequip(var/mob/living/carbon/human/player) + if(!istype(player)) + return 0 + return 1 \ No newline at end of file diff --git a/code/game/antagonist/antagonist_globals.dm b/code/game/antagonist/antagonist_globals.dm deleted file mode 100644 index 02ec5304fc..0000000000 --- a/code/game/antagonist/antagonist_globals.dm +++ /dev/null @@ -1,41 +0,0 @@ -var/global/list/all_antag_types = list() -var/global/list/all_antag_spawnpoints = list() -var/global/list/antag_names_to_ids = list() - -/proc/get_antag_data(var/antag_type) - if(all_antag_types[antag_type]) - return all_antag_types[antag_type] - else - for(var/cur_antag_type in all_antag_types) - var/datum/antagonist/antag = all_antag_types[cur_antag_type] - if(antag && antag.is_type(antag_type)) - return antag - -/proc/clear_antag_roles(var/datum/mind/player, var/implanted) - for(var/antag_type in all_antag_types) - var/datum/antagonist/antag = all_antag_types[antag_type] - if(!implanted || !(antag.flags & ANTAG_IMPLANT_IMMUNE)) - antag.remove_antagonist(player, 1, implanted) - -/proc/update_antag_icons(var/datum/mind/player) - for(var/antag_type in all_antag_types) - var/datum/antagonist/antag = all_antag_types[antag_type] - if(player) - antag.update_icons_removed(player) - if(antag.is_antagonist(player)) - antag.update_icons_added(player) - else - antag.update_all_icons() - -/proc/populate_antag_type_list() - for(var/antag_type in typesof(/datum/antagonist)-/datum/antagonist) - var/datum/antagonist/A = new antag_type - all_antag_types[A.id] = A - all_antag_spawnpoints[A.landmark_id] = list() - antag_names_to_ids[A.role_text] = A.id - -/proc/get_antags(var/atype) - var/datum/antagonist/antag = all_antag_types[atype] - if(antag && islist(antag.current_antagonists)) - return antag.current_antagonists - return list() \ No newline at end of file diff --git a/code/game/antagonist/antagonist_helpers.dm b/code/game/antagonist/antagonist_helpers.dm index 92556a817a..bf010b6003 100644 --- a/code/game/antagonist/antagonist_helpers.dm +++ b/code/game/antagonist/antagonist_helpers.dm @@ -1,10 +1,11 @@ -/datum/antagonist/proc/can_become_antag(var/datum/mind/player) +/datum/antagonist/proc/can_become_antag(var/datum/mind/player, var/ignore_role) if(player.current && jobban_isbanned(player.current, bantype)) return 0 - if(player.assigned_role in protected_jobs) - return 0 - if(config.protect_roles_from_antagonist && (player.assigned_role in restricted_jobs)) - return 0 + if(!ignore_role) + if(player.assigned_role in protected_jobs) + return 0 + if(config.protect_roles_from_antagonist && (player.assigned_role in restricted_jobs)) + return 0 return 1 /datum/antagonist/proc/antags_are_dead() @@ -27,3 +28,6 @@ if(antag_type == id || antag_type == role_text) return 1 return 0 + +/datum/antagonist/proc/is_votable() + return (flags & ANTAG_VOTABLE) \ No newline at end of file diff --git a/code/game/antagonist/antagonist_objectives.dm b/code/game/antagonist/antagonist_objectives.dm index 58997fa68e..010ba565cc 100644 --- a/code/game/antagonist/antagonist_objectives.dm +++ b/code/game/antagonist/antagonist_objectives.dm @@ -1,5 +1,16 @@ /datum/antagonist/proc/create_global_objectives() - return !((global_objectives && global_objectives.len) || config.objectives_disabled) + if(config.objectives_disabled) + return 0 + if(global_objectives && global_objectives.len) + return 0 + return 1 + +/datum/antagonist/proc/create_objectives(var/datum/mind/player) + if(config.objectives_disabled) + return 0 + if(create_global_objectives()) + player.objectives |= global_objectives + return 1 /datum/antagonist/proc/get_special_objective_text() return "" diff --git a/code/game/antagonist/antagonist_panel.dm b/code/game/antagonist/antagonist_panel.dm new file mode 100644 index 0000000000..ed8f1d9563 --- /dev/null +++ b/code/game/antagonist/antagonist_panel.dm @@ -0,0 +1,61 @@ +/datum/antagonist/proc/get_panel_entry(var/datum/mind/player) + + var/dat = "[role_text]:" + var/extra = get_extra_panel_options(player) + if(is_antagonist(player)) + dat += "\[-\]" + dat += "\[equip\]" + if(starting_locations && starting_locations.len) + dat += "\[move to spawn\]" + if(extra) dat += "[extra]" + else + dat += "\[+\]" + dat += "" + + return dat + +/datum/antagonist/proc/get_extra_panel_options() + return + +/datum/antagonist/proc/get_check_antag_output(var/datum/admins/caller) + + if(!current_antagonists || !current_antagonists.len) + return "" + + var/dat = "
" + for(var/datum/mind/player in current_antagonists) + var/mob/M = player.current + dat += "" + if(M) + dat += "" + dat += "" + else + dat += "" + dat += "" + dat += "
[role_text_plural]
[M.real_name]" + if(!M.client) dat += " (logged out)" + if(M.stat == DEAD) dat += " (DEAD)" + dat += "\[PM\]\[TP\]Mob not found!
" + + if(flags & ANTAG_HAS_NUKE) + dat += "
" + for(var/obj/item/weapon/disk/nuclear/N in world) + dat += "" + dat += "
Nuclear disk(s)
[N.name], " + var/atom/disk_loc = N.loc + while(!istype(disk_loc, /turf)) + if(istype(disk_loc, /mob)) + var/mob/M = disk_loc + dat += "carried by [M.real_name] " + if(istype(disk_loc, /obj)) + var/obj/O = disk_loc + dat += "in \a [O.name] " + disk_loc = disk_loc.loc + dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])
" + dat += get_additional_check_antag_output(caller) + dat += "
" + return dat + +//Overridden elsewhere. +/datum/antagonist/proc/get_additional_check_antag_output(var/datum/admins/caller) + return "" diff --git a/code/game/antagonist/antagonist_place.dm b/code/game/antagonist/antagonist_place.dm new file mode 100644 index 0000000000..1d69aaa96f --- /dev/null +++ b/code/game/antagonist/antagonist_place.dm @@ -0,0 +1,29 @@ +/datum/antagonist/proc/get_starting_locations() + if(landmark_id) + starting_locations = list() + for(var/obj/effect/landmark/L in landmarks_list) + if(L.name == landmark_id) + starting_locations |= get_turf(L) + +/datum/antagonist/proc/place_all_mobs() + if(!starting_locations || !starting_locations.len || !current_antagonists || !current_antagonists.len) + return + for(var/datum/mind/player in current_antagonists) + player.current.loc = pick(starting_locations) + +/datum/antagonist/proc/announce_antagonist_spawn() + if(spawn_announcement) + if(announced) + return + announced = 1 + if(spawn_announcement_delay) + sleep(spawn_announcement_delay) + if(spawn_announcement_sound) + command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound) + else + command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]") + +/datum/antagonist/proc/place_mob(var/mob/living/mob) + if(!starting_locations || !starting_locations.len) + return + mob.loc = pick(starting_locations) \ No newline at end of file diff --git a/code/game/antagonist/antagonist_print.dm b/code/game/antagonist/antagonist_print.dm new file mode 100644 index 0000000000..ae35c22820 --- /dev/null +++ b/code/game/antagonist/antagonist_print.dm @@ -0,0 +1,88 @@ +/datum/antagonist/proc/print_player_summary() + + if(!current_antagonists.len) + return 0 + + var/text = "
The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:" + for(var/datum/mind/P in current_antagonists) + text += print_player_full(P) + text += get_special_objective_text(P) + var/failed + if(!global_objectives.len && P.objectives && P.objectives.len) + var/num = 1 + for(var/datum/objective/O in P.objectives) + text += print_objective(O, num) + if(O.completed) // This is set actively in check_victory() + text += "Success!" + feedback_add_details(feedback_tag,"[O.type]|SUCCESS") + else + text += "Fail." + feedback_add_details(feedback_tag,"[O.type]|FAIL") + failed = 1 + num++ + + if(!config.objectives_disabled) + if(failed) + text += "
The [role_text] has failed." + else + text += "
The [role_text] was successful!" + + if(global_objectives && global_objectives.len) + text += "
Their objectives were:" + var/num = 1 + for(var/datum/objective/O in global_objectives) + text += print_objective(O, num, 1) + num++ + + // Display the results. + world << text + +/datum/antagonist/proc/print_objective(var/datum/objective/O, var/num, var/append_success) + var/text = "
Objective [num]: [O.explanation_text] " + if(append_success) + if(O.check_completion()) + text += "Success!" + else + text += "Fail." + return text + +/datum/antagonist/proc/print_player_lite(var/datum/mind/ply) + var/role = ply.assigned_role == "MODE" ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]" + var/text = "
[ply.name] ([ply.key]) as \a [role] (" + if(ply.current) + if(ply.current.stat == DEAD) + text += "died" + else if(isNotStationLevel(ply.current.z)) + text += "fled the station" + else + text += "survived" + if(ply.current.real_name != ply.name) + text += " as [ply.current.real_name]" + else + text += "body destroyed" + text += ")" + + return text + +/datum/antagonist/proc/print_player_full(var/datum/mind/ply) + var/text = print_player_lite(ply) + + var/TC_uses = 0 + var/uplink_true = 0 + var/purchases = "" + for(var/obj/item/device/uplink/H in world_uplinks) + if(H && H.uplink_owner && H.uplink_owner == ply) + TC_uses += H.used_TC + uplink_true = 1 + var/list/refined_log = new() + for(var/datum/uplink_item/UI in H.purchase_log) + var/obj/I = new UI.path + refined_log.Add("[H.purchase_log[UI]]x\icon[I][UI.name]") + qdel(I) + purchases = english_list(refined_log, nothing_text = "") + if(uplink_true) + text += " (used [TC_uses] TC)" + if(purchases) + text += "
[purchases]" + + return text \ No newline at end of file diff --git a/code/game/antagonist/antagonist_spawn.dm b/code/game/antagonist/antagonist_spawn.dm deleted file mode 100644 index c8453663fb..0000000000 --- a/code/game/antagonist/antagonist_spawn.dm +++ /dev/null @@ -1,85 +0,0 @@ -/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player, var/move_to_spawn) - - update_cur_max() - if(get_antag_count() >= cur_max) - return 0 - - player.current << "You have been selected this round as an antagonist!" - add_antagonist(player) - equip(player.current) - if(move_to_spawn) - place_mob(player.current) - return - -/datum/antagonist/proc/update_cur_max() - - candidates = list() - var/main_type - if(ticker && ticker.mode) - if(ticker.mode.antag_tag && ticker.mode.antag_tag == id) - main_type = 1 - else - return list() - - cur_max = (main_type ? max_antags_round : max_antags) - if(ticker.mode.antag_scaling_coeff) - cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max) - -/datum/antagonist/proc/attempt_spawn(var/ghosts_only) - - // Get the raw list of potential players. - update_cur_max() - candidates = get_candidates(ghosts_only) - - // Update our boundaries. - if(!candidates.len) - return 0 - - //Grab candidates randomly until we have enough. - while(candidates.len) - var/datum/mind/player = pick(candidates) - current_antagonists |= player - // Update job and role. - player.special_role = role_text - if(flags & ANTAG_OVERRIDE_JOB) - player.assigned_role = "MODE" - candidates -= player - return 1 - -/datum/antagonist/proc/place_mob(var/mob/living/mob) - if(!starting_locations || !starting_locations.len) - return - mob.loc = pick(starting_locations) - -/datum/antagonist/proc/add_antagonist(var/datum/mind/player) - if(!istype(player)) - return 0 - if(player in current_antagonists) - return 0 - if(!can_become_antag(player)) - return 0 - - current_antagonists |= player - apply(player) - finalize(player) - return 1 - -/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted) - if(player in current_antagonists) - player.current << "You are no longer a [role_text]!" - current_antagonists -= player - player.special_role = null - update_icons_removed(player) - BITSET(player.current.hud_updateflag, SPECIALROLE_HUD) - return 1 - return 0 - -/datum/antagonist/proc/get_candidates(var/ghosts_only) - - candidates = list() // Clear. - candidates = ticker.mode.get_players_for_role(role_type, id) - // Prune restricted jobs and status. - for(var/datum/mind/player in candidates) - if((ghosts_only && !istype(player.current, /mob/dead)) || player.special_role || (player.assigned_role in restricted_jobs)) - candidates -= player - return candidates \ No newline at end of file diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm new file mode 100644 index 0000000000..a06b3e5993 --- /dev/null +++ b/code/game/antagonist/antagonist_update.dm @@ -0,0 +1,76 @@ +/datum/antagonist/proc/update_leader() + if(!leader && current_antagonists.len && (flags & ANTAG_HAS_LEADER)) + leader = current_antagonists[1] + +/datum/antagonist/proc/update_antag_mob(var/datum/mind/player, var/preserve_appearance) + + // Get the mob. + if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path)))) + var/mob/holder = player.current + player.current = new mob_path(get_turf(player.current)) + player.transfer_to(player.current) + if(holder) qdel(holder) + player.original = player.current + if(!preserve_appearance && (flags & ANTAG_SET_APPEARANCE)) + spawn(3) + var/mob/living/carbon/human/H = player.current + if(istype(H)) H.change_appearance(APPEARANCE_ALL, H.loc, H, valid_species, state = z_state) + return player.current + +/datum/antagonist/proc/update_access(var/mob/living/player) + for(var/obj/item/weapon/card/id/id in player.contents) + id.name = "[player.real_name]'s ID Card" + id.registered_name = player.real_name + +/datum/antagonist/proc/update_all_icons() + if(!antag_indicator) + return + for(var/datum/mind/antag in current_antagonists) + if(antag.current && antag.current.client) + for(var/image/I in antag.current.client.images) + if(I.icon_state == antag_indicator) + qdel(I) + for(var/datum/mind/other_antag in current_antagonists) + if(other_antag.current) + antag.current.client.images |= image('icons/mob/mob.dmi', loc = other_antag.current, icon_state = antag_indicator) + +/datum/antagonist/proc/update_icons_added(var/datum/mind/player) + if(!antag_indicator || !player.current) + return + spawn(0) + for(var/datum/mind/antag in current_antagonists) + if(!antag.current) + continue + if(antag.current.client) + antag.current.client.images |= image('icons/mob/mob.dmi', loc = player.current, icon_state = antag_indicator) + if(player.current.client) + player.current.client.images |= image('icons/mob/mob.dmi', loc = antag.current, icon_state = antag_indicator) + +/datum/antagonist/proc/update_icons_removed(var/datum/mind/player) + if(!antag_indicator || !player.current) + return + spawn(0) + for(var/datum/mind/antag in current_antagonists) + if(antag.current) + if(antag.current.client) + for(var/image/I in antag.current.client.images) + if(I.icon_state == antag_indicator && I.loc == player.current) + qdel(I) + if(player.current && player.current.client) + for(var/image/I in player.current.client.images) + if(I.icon_state == antag_indicator) + qdel(I) + +/datum/antagonist/proc/update_current_antag_max() + + candidates = list() + var/main_type + if(ticker && ticker.mode) + if(ticker.mode.antag_tag && ticker.mode.antag_tag == id) + main_type = 1 + else + return list() + + cur_max = (main_type ? max_antags_round : max_antags) + if(ticker.mode.antag_scaling_coeff) + cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max) \ No newline at end of file diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm index 73c2c7fd78..9d95fcc4d3 100644 --- a/code/game/antagonist/outsider/deathsquad.dm +++ b/code/game/antagonist/outsider/deathsquad.dm @@ -7,7 +7,7 @@ var/datum/antagonist/deathsquad/deathsquad role_text_plural = "Death Commandos" welcome_text = "You work in the service of Central Command Asset Protection, answering directly to the Board of Directors." landmark_id = "Commando" - flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE + flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER max_antags = 4 max_antags_round = 6 default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage) @@ -23,6 +23,9 @@ var/datum/antagonist/deathsquad/deathsquad deployed = 1 /datum/antagonist/deathsquad/equip(var/mob/living/carbon/human/player) + if(!..()) + return + if (player.mind == leader) player.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(player), slot_w_uniform) else @@ -49,7 +52,7 @@ var/datum/antagonist/deathsquad/deathsquad id.icon_state = "centcom" create_radio(DTH_FREQ, player) -/datum/antagonist/deathsquad/apply(var/datum/mind/player) +/datum/antagonist/deathsquad/update_antag_mob(var/datum/mind/player) ..() @@ -76,9 +79,6 @@ var/datum/antagonist/deathsquad/deathsquad return -/datum/antagonist/deathsquad/finalize(var/datum/mind/target) - - ..() - - if(!deployed) +/datum/antagonist/deathsquad/create_antagonist() + if(..() && !deployed) deployed = 1 diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm index 946ff1dfc2..6bcb89a6bf 100644 --- a/code/game/antagonist/outsider/ert.dm +++ b/code/game/antagonist/outsider/ert.dm @@ -10,8 +10,13 @@ var/datum/antagonist/ert/ert leader_welcome_text = "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however." max_antags = 5 max_antags_round = 5 // ERT mode? + landmark_id = "Response Team" - flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE + flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER + +/datum/antagonist/ert/create_default(var/mob/source) + var/mob/living/carbon/human/M = ..() + if(istype(M)) M.age = rand(25,45) /datum/antagonist/ert/New() ..() diff --git a/code/game/antagonist/outsider/mercenary.dm b/code/game/antagonist/outsider/mercenary.dm index 72a6a56d62..1ddc6457d9 100644 --- a/code/game/antagonist/outsider/mercenary.dm +++ b/code/game/antagonist/outsider/mercenary.dm @@ -7,8 +7,9 @@ var/datum/antagonist/mercenary/mercs bantype = "operative" role_text_plural = "Mercenaries" landmark_id = "Syndicate-Spawn" + leader_welcome_text = "You are the leader of the mercenary strikeforce; hail to the chief. Use :t to speak to your underlings." welcome_text = "To speak on the strike team's private channel use :t." - flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE + flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER max_antags = 4 max_antags_round = 6 id_type = /obj/item/weapon/card/id/syndicate @@ -19,9 +20,10 @@ var/datum/antagonist/mercenary/mercs /datum/antagonist/mercenary/create_global_objectives() if(!..()) - return + return 0 global_objectives = list() global_objectives |= new /datum/objective/nuclear + return 1 /datum/antagonist/mercenary/equip(var/mob/living/carbon/human/player) @@ -50,7 +52,7 @@ var/datum/antagonist/mercenary/mercs if(spawnpos > starting_locations.len) spawnpos = 1 -/datum/antagonist/mercenary/make_nuke() +/datum/antagonist/mercenary/create_nuke() ..() // Create the radio. var/obj/effect/landmark/uplinkdevice = locate("landmark*Syndicate-Uplink") diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm index 4fed41aa13..17083eb89a 100644 --- a/code/game/antagonist/outsider/ninja.dm +++ b/code/game/antagonist/outsider/ninja.dm @@ -16,7 +16,7 @@ var/datum/antagonist/ninja/ninjas ..() ninjas = src -/datum/antagonist/ninja/random_spawn() +/datum/antagonist/ninja/attempt_random_spawn() if(config.ninjas_allowed) ..() /datum/antagonist/ninja/create_objectives(var/datum/mind/ninja) @@ -82,7 +82,7 @@ var/datum/antagonist/ninja/ninjas player.store_memory("Directive: [directive]
") player << "Remember your directive: [directive]." -/datum/antagonist/ninja/apply(var/datum/mind/player) +/datum/antagonist/ninja/update_antag_mob(var/datum/mind/player) ..() var/ninja_title = pick(ninja_titles) var/ninja_name = pick(ninja_names) diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm index a7949011fc..e17632dccb 100644 --- a/code/game/antagonist/outsider/raider.dm +++ b/code/game/antagonist/outsider/raider.dm @@ -8,7 +8,7 @@ var/datum/antagonist/raider/raiders bantype = "raider" landmark_id = "voxstart" welcome_text = "Use :H to talk on your encrypted channel." - flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE + flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER max_antags = 6 max_antags_round = 10 id_type = /obj/item/weapon/card/id/syndicate @@ -83,8 +83,8 @@ var/datum/antagonist/raider/raiders /datum/antagonist/raider/create_global_objectives() - if(global_objectives.len) - return + if(!..()) + return 0 var/i = 1 var/max_objectives = pick(2,2,2,2,3,3,3,4) @@ -107,6 +107,7 @@ var/datum/antagonist/raider/raiders i++ global_objectives |= new /datum/objective/heist/preserve_crew + return 1 /datum/antagonist/raider/check_victory() // Totally overrides the base proc. diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm index 2923008a7b..93e44974e9 100644 --- a/code/game/antagonist/outsider/wizard.dm +++ b/code/game/antagonist/outsider/wizard.dm @@ -58,7 +58,8 @@ var/datum/antagonist/wizard/wizards wizard.objectives |= hijack_objective return -/datum/antagonist/wizard/apply(var/datum/mind/wizard) +/datum/antagonist/wizard/update_antag_mob(var/datum/mind/wizard) + ..() wizard.store_memory("Remember: do not forget to prepare your spells.") wizard.current.real_name = "[pick(wizard_first)] [pick(wizard_second)]" wizard.current.name = wizard.current.real_name diff --git a/code/game/antagonist/station/changeling.dm b/code/game/antagonist/station/changeling.dm index 55b67cc29a..f6307b8ae8 100644 --- a/code/game/antagonist/station/changeling.dm +++ b/code/game/antagonist/station/changeling.dm @@ -13,7 +13,7 @@ /datum/antagonist/changeling/get_special_objective_text(var/datum/mind/player) return "
Changeling ID: [player.changeling.changelingID].
Genomes Absorbed: [player.changeling.absorbedcount]" -/datum/antagonist/changeling/apply(var/datum/mind/player) +/datum/antagonist/changeling/update_antag_mob(var/datum/mind/player) ..() player.current.make_changeling() diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm index adaa2b24f5..5c6a3c6782 100644 --- a/code/game/antagonist/station/cultist.dm +++ b/code/game/antagonist/station/cultist.dm @@ -111,8 +111,6 @@ var/datum/antagonist/cultist/cult /datum/antagonist/cultist/can_become_antag(var/datum/mind/player) if(!..()) return 0 - if(!istype(player.current, /mob/living/carbon/human)) - return 0 for(var/obj/item/weapon/implant/loyalty/L in player.current) if(L && (L.imp_in == player.current)) return 0 diff --git a/code/game/antagonist/station/revolutionary.dm b/code/game/antagonist/station/revolutionary.dm index ced1d58b38..59d12b50ad 100644 --- a/code/game/antagonist/station/revolutionary.dm +++ b/code/game/antagonist/station/revolutionary.dm @@ -50,13 +50,43 @@ var/datum/antagonist/revolutionary/revs ) mob.equip_in_one_of_slots(T, slots) -/datum/antagonist/revolutionary/finalize(var/datum/mind/target) +/* +datum/antagonist/revolutionary/finalize(var/datum/mind/target) if(target) return ..(target) current_antagonists |= head_revolutionaries create_global_objectives() ..() +/datum/antagonist/revolutionary/get_additional_check_antag_output(var/datum/admins/caller) + return ..() //Todo + + Rev extras: + dat += "
" + for(var/datum/mind/N in ticker.mode.head_revolutionaries) + var/mob/M = N.current + if(!M) + dat += "" + else + dat += "" + dat += "" + for(var/datum/mind/N in ticker.mode.revolutionaries) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + dat += "
Revolutionaries
Head Revolutionary not found!
[M.real_name] (Leader)[M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
" + for(var/datum/mind/N in ticker.mode.get_living_heads()) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + var/turf/mob_loc = get_turf(M) + dat += "" + else + dat += "" +*/ + /datum/antagonist/revolutionary/create_global_objectives() if(!..()) return @@ -166,7 +196,7 @@ var/datum/antagonist/revolutionary/revs if(choice == "Yes!") M << "You join the revolution!" src << "[M] joins the revolution!" - revs.add_antagonist(M.mind) + revs.add_antagonist(M.mind, 0, 0, 1) else if(choice == "No!") M << "You reject this traitorous cause!" src << "\The [M] does not support the revolution!" diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 755887ad83..76ab7b5106 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -285,9 +285,9 @@ var/global/list/additional_antag_types = list() spawn(rand(100,150)) announce_ert_disabled() - if(antag_templates && antag_templates.len) - for(var/datum/antagonist/antag in antag_templates) - antag.finalize() + //if(antag_templates && antag_templates.len) + // for(var/datum/antagonist/antag in antag_templates) + // antag.finalize() if(emergency_shuttle && auto_recall_shuttle) emergency_shuttle.auto_recall = 1 diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index d1d2a37ea2..23c6b80b5a 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -697,13 +697,14 @@ /obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) - + /* if(istype(W, /obj/item/device/mmi)) if(mmi_move_inside(W,user)) user << "[src]-MMI interface initialized successfuly" else user << "[src]-MMI interface initialization failed." return + */ if(istype(W, /obj/item/mecha_parts/mecha_equipment)) var/obj/item/mecha_parts/mecha_equipment/E = W diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 61f6921698..896b79655a 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -38,9 +38,12 @@ var/can_call_ert trigger_armed_response_team(1) client/verb/JoinResponseTeam() + + set name = "Join Response Team" set category = "IC" if(!MayRespawn(1)) + usr << "You cannot join the response team at this time." return if(istype(usr,/mob/dead/observer) || istype(usr,/mob/new_player)) @@ -50,18 +53,9 @@ client/verb/JoinResponseTeam() if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer")) usr << "You are jobbanned from the emergency reponse team!" return - - if(ert.current_antagonists.len > 5) usr << "The emergency response team is already full!" - - for (var/obj/effect/landmark/L in landmarks_list) if (L.name == "Commando") - L.name = null//Reserving the place. - var/new_name = sanitizeSafe(input(usr, "Pick a name","Name") as null|text, MAX_NAME_LEN) - if(!new_name)//Somebody changed his mind, place is available again. - L.name = "Commando" - return - create_response_team(L.loc, new_name) - qdel(L) - + if(ert.current_antagonists.len > 5) + usr << "The emergency response team is already full!" + ert.create_default(usr) else usr << "You need to be an observer or new player to use this." @@ -130,25 +124,3 @@ proc/trigger_armed_response_team(var/force = 0) sleep(600 * 5) send_emergency_team = 0 // Can no longer join the ERT. - -/client/proc/create_response_team(obj/spawn_location, commando_name) - - var/mob/living/carbon/human/M = new(null) - - - M.real_name = commando_name - M.name = commando_name - M.age = rand(25,45) - - M.check_dna(M) - M.dna.ready_dna(M)//Creates DNA. - - M.mind = new - M.mind.current = M - M.mind.original = M - if(!(M.mind in ticker.minds)) - ticker.minds += M.mind//Adds them to regular mind list. - M.loc = spawn_location - ert.add_antagonist(M.mind) - - return M diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 828667aa13..a25d2de043 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -410,43 +410,11 @@ dat += "Launching now..." dat += "[ticker.delay_end ? "End Round Normally" : "Delay Round End"]
" - - //todo - + dat += "
" + for(var/antag_type in all_antag_types) + var/datum/antagonist/A = all_antag_types[antag_type] + dat += A.get_check_antag_output(src) dat += "" usr << browse(dat, "window=roundstatus;size=400x500") else alert("The game hasn't started yet!") - -/proc/check_role_table(name, list/members, admins, show_objectives=1) - var/txt = "
Target(s)Location
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM[mob_loc.loc]
Head not found!
" - for(var/datum/mind/M in members) - txt += check_role_table_row(M.current, admins, show_objectives) - txt += "
[name]
" - return txt - -/proc/check_role_table_row(mob/M, admins=src, show_objectives) - if (!istype(M)) - return "Not found!" - - var/txt = {" - - - [M.real_name] - [M.client ? "" : " (logged out)"] - [M.is_dead() ? " (DEAD)" : ""] - - - PM - - "} - - if (show_objectives) - txt += {" - - Show Objective - - "} - - txt += "" - return txt diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 363c4ea15e..de3547dfe1 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1734,13 +1734,13 @@ feedback_add_details("admin_secrets_fun_used","Aliens") log_admin("[key_name(usr)] spawned an alien infestation", 1) message_admins("\blue [key_name_admin(usr)] attempted an alien infestation", 1) - xenomorphs.random_spawn() + xenomorphs.attempt_random_spawn() if("borers") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","Borers") log_admin("[key_name(usr)] spawned a cortical borer infestation.", 1) message_admins("\blue [key_name_admin(usr)] spawned a cortical borer infestation.", 1) - borers.random_spawn() + borers.attempt_random_spawn() if("power") feedback_inc("admin_secrets_fun_used",1) @@ -2046,7 +2046,7 @@ if("aliens") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","AL") - if(xenomorphs.random_spawn()) + if(xenomorphs.attempt_random_spawn()) message_admins("[key_name_admin(usr)] has spawned aliens", 1) if("spiders") feedback_inc("admin_secrets_fun_used",1) @@ -2644,4 +2644,4 @@ mob/living/carbon/human/can_centcom_reply() return istype(l_ear, /obj/item/device/radio/headset) || istype(r_ear, /obj/item/device/radio/headset) mob/living/silicon/ai/can_centcom_reply() - return common_radio != null && !check_unable(2) \ No newline at end of file + return common_radio != null && !check_unable(2) diff --git a/code/modules/events/random_antagonist.dm b/code/modules/events/random_antagonist.dm index 10f8778b3b..abe07472d1 100644 --- a/code/modules/events/random_antagonist.dm +++ b/code/modules/events/random_antagonist.dm @@ -10,4 +10,4 @@ valid_types |= antag if(valid_types.len) var/datum/antagonist/antag = pick(valid_types) - antag.random_spawn() + antag.attempt_random_spawn() diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 40746ff02f..d0215c7015 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -257,12 +257,13 @@ lawupdate = 0 src << "Systems rebooted. Loading base pattern maintenance protocol... loaded." full_law_reset() - src << "
You are a maintenance drone, a tiny-brained robotic repair machine." + welcome_drone() + +/mob/living/silicon/robot/drone/proc/welcome_drone() + src << "You are a maintenance drone, a tiny-brained robotic repair machine." src << "You have no individual will, no personality, and no drives or urges other than your laws." - src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." src << "Remember, you are lawed against interference with the crew. Also remember, you DO NOT take orders from the AI." - src << "Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets." - src << "If a crewmember has noticed you, you are probably breaking your third law." + src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." /mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM) @@ -293,6 +294,12 @@ can_pull_size = 5 can_pull_mobs = 1 +/mob/living/silicon/robot/drone/construction/welcome_drone() + src << "You are a construction drone, an autonomous engineering and fabrication system.." + src << "You are assigned to a Sol Central construction project. The name is irrelevant. Your task is to complete construction and subsystem integration as soon as possible." + src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." + src << "You do not follow orders from anyone; not the AI, not humans, and not other synthetics.." + /mob/living/silicon/robot/drone/construction/init() ..() flavor_text = "It's a bulky construction drone stamped with a Sol Central glyph." diff --git a/code/setup.dm b/code/setup.dm index d5b0dd3e7c..ba6762e3c7 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -815,18 +815,6 @@ var/list/be_special_flags = list( #define APPEARANCE_ALL_HAIR (APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR) #define APPEARANCE_ALL 511 -// Antagonist datum flags. -#define ANTAG_OVERRIDE_JOB 1 // Assigned job is set to MODE when spawning. -#define ANTAG_OVERRIDE_MOB 2 // Mob is recreated from datum mob_type var when spawning. -#define ANTAG_CLEAR_EQUIPMENT 4 // All preexisting equipment is purged. -#define ANTAG_CHOOSE_NAME 8 // Antagonists are prompted to enter a name. -#define ANTAG_IMPLANT_IMMUNE 16 // Cannot be loyalty implanted. -#define ANTAG_SUSPICIOUS 32 // Shows up on roundstart report. -#define ANTAG_HAS_LEADER 64 // Generates a leader antagonist. -#define ANTAG_HAS_NUKE 128 // Will spawn a nuke at supplied location. -#define ANTAG_RANDSPAWN 256 // Potentially randomly spawns due to events. -#define ANTAG_VOTABLE 512 // Can be voted as an additional antagonist before roundstart. -#define ANTAG_SET_APPEARANCE 1024 // Causes antagonists to use an appearance modifier on spawn. // Mode/antag template macros. #define MODE_BORER "borer" #define MODE_XENOMORPH "xeno" From d3bd63eec96863937df1c9a92f7cf2b7afde6ca6 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Sun, 21 Jun 2015 19:33:49 +0930 Subject: [PATCH 08/10] Refactor/tidies up latejoin antags/in-round antag spawning. --- baystation12.dme | 1 + code/game/antagonist/antagonist.dm | 45 ++++++---- code/game/antagonist/antagonist_add.dm | 15 +++- code/game/antagonist/antagonist_create.dm | 4 +- code/game/antagonist/antagonist_helpers.dm | 11 ++- code/game/antagonist/antagonist_objectives.dm | 2 - code/game/antagonist/antagonist_print.dm | 12 +-- code/game/antagonist/antagonist_update.dm | 7 +- code/game/antagonist/outsider/ninja.dm | 6 +- code/game/gamemodes/game_mode.dm | 90 +++---------------- code/game/gamemodes/game_mode_latespawn.dm | 43 +++++++++ code/modules/admin/admin.dm | 2 +- 12 files changed, 115 insertions(+), 123 deletions(-) create mode 100644 code/game/gamemodes/game_mode_latespawn.dm diff --git a/baystation12.dme b/baystation12.dme index 88966c957f..1497ff493b 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -252,6 +252,7 @@ #include "code\game\dna\genes\powers.dm" #include "code\game\gamemodes\events.dm" #include "code\game\gamemodes\game_mode.dm" +#include "code\game\gamemodes\game_mode_latespawn.dm" #include "code\game\gamemodes\gameticker.dm" #include "code\game\gamemodes\intercept_report.dm" #include "code\game\gamemodes\objective.dm" diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index c7cbde15ab..11431682a1 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -33,8 +33,9 @@ var/nuke_spawn_loc var/list/valid_species = list("Unathi","Tajara","Skrell","Human") // Used for setting appearance. - var/list/starting_locations = list() var/list/current_antagonists = list() + var/list/pending_antagonists = list() + var/list/starting_locations = list() var/list/global_objectives = list() var/list/restricted_jobs = list() var/list/protected_jobs = list() @@ -57,29 +58,32 @@ return 1 /datum/antagonist/proc/get_candidates(var/ghosts_only) - candidates = list() // Clear. candidates = ticker.mode.get_players_for_role(role_type, id) - // Prune restricted jobs and status. + // Prune restricted jobs and status. Broke it up for readability. for(var/datum/mind/player in candidates) - if((ghosts_only && !istype(player.current, /mob/dead)) || player.special_role || (player.assigned_role in restricted_jobs)) + if(ghosts_only && !istype(player.current, /mob/dead)) + candidates -= player + else if(player.special_role) + candidates -= player + else if (player in pending_antagonists) + candidates -= player + else if(!can_become_antag(player)) candidates -= player return candidates /datum/antagonist/proc/attempt_random_spawn() attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB)) -/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player, var/move_to_spawn) - - update_current_antag_max() - if(get_antag_count() >= cur_max) - return 0 - +/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player) + if(!can_late_spawn()) + return + if(!istype(player)) player = get_candidates(is_latejoin_template()) player.current << "You have been selected this round as an antagonist!" - if(move_to_spawn) - place_mob(player.current) - add_antagonist(player) - equip(player.current) + if(istype(player.current, /mob/dead)) + create_default(player.current) + else + add_antagonist(player,0,1,0,1,1) return /datum/antagonist/proc/attempt_spawn(var/ghosts_only) @@ -95,11 +99,14 @@ //Grab candidates randomly until we have enough. while(candidates.len) var/datum/mind/player = pick(candidates) - current_antagonists |= player - // Update job and role. - player.special_role = role_text - if(flags & ANTAG_OVERRIDE_JOB) - player.assigned_role = "MODE" + pending_antagonists |= player candidates -= player return 1 +/datum/antagonist/proc/finalize_spawn() + if(!pending_antagonists || !pending_antagonists.len) + return + for(var/datum/mind/player in pending_antagonists) + if(can_become_antag(player) && !player.special_role) + add_antagonist(player,0,0,1) + pending_antagonists.Cut() \ No newline at end of file diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm index 9a0ef84e8d..e3c653a4e5 100644 --- a/code/game/antagonist/antagonist_add.dm +++ b/code/game/antagonist/antagonist_add.dm @@ -1,14 +1,23 @@ /datum/antagonist/proc/add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance) if(!istype(player)) return 0 + if(!player.current) + return 0 if(player in current_antagonists) return 0 if(!can_become_antag(player, ignore_role)) return 0 + current_antagonists |= player - create_antagonist(player, move_to_spawn, do_not_announce, preserve_appearance) - if(!do_not_equip && player.current) - equip(player.current) + if(flags & ANTAG_OVERRIDE_JOB) + player.assigned_role = "MODE" + + if(istype(player.current, /mob/dead)) + create_default(player.current) + else + create_antagonist(player, move_to_spawn, do_not_announce, preserve_appearance) + if(!do_not_equip) + equip(player.current) return 1 /datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted) diff --git a/code/game/antagonist/antagonist_create.dm b/code/game/antagonist/antagonist_create.dm index c7387d92a8..0c1aab6898 100644 --- a/code/game/antagonist/antagonist_create.dm +++ b/code/game/antagonist/antagonist_create.dm @@ -21,9 +21,9 @@ /datum/antagonist/proc/create_default(var/mob/source) var/mob/living/M if(mob_path) - M = new mob_path() + M = new mob_path(get_turf(source)) else - M = new /mob/living/carbon/human + M = new /mob/living/carbon/human(get_turf(source)) M.real_name = source.real_name M.name = M.real_name M.ckey = source.ckey diff --git a/code/game/antagonist/antagonist_helpers.dm b/code/game/antagonist/antagonist_helpers.dm index bf010b6003..a578c1bf4f 100644 --- a/code/game/antagonist/antagonist_helpers.dm +++ b/code/game/antagonist/antagonist_helpers.dm @@ -30,4 +30,13 @@ return 0 /datum/antagonist/proc/is_votable() - return (flags & ANTAG_VOTABLE) \ No newline at end of file + return (flags & ANTAG_VOTABLE) + +/datum/antagonist/proc/can_late_spawn() + update_current_antag_max() + if(get_antag_count() >= cur_max) + return 0 + return 1 + +/datum/antagonist/proc/is_latejoin_template() + return (flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB)) \ No newline at end of file diff --git a/code/game/antagonist/antagonist_objectives.dm b/code/game/antagonist/antagonist_objectives.dm index 010ba565cc..432c3f6bbe 100644 --- a/code/game/antagonist/antagonist_objectives.dm +++ b/code/game/antagonist/antagonist_objectives.dm @@ -23,8 +23,6 @@ for(var/datum/objective/O in global_objectives) if(!O.completed && !O.check_completion()) result = 0 - else - O.completed = 1 //Will this break anything? if(result && victory_text) world << "[victory_text]" if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]") diff --git a/code/game/antagonist/antagonist_print.dm b/code/game/antagonist/antagonist_print.dm index ae35c22820..ab6271b35b 100644 --- a/code/game/antagonist/antagonist_print.dm +++ b/code/game/antagonist/antagonist_print.dm @@ -12,7 +12,7 @@ var/num = 1 for(var/datum/objective/O in P.objectives) text += print_objective(O, num) - if(O.completed) // This is set actively in check_victory() + if(O.check_completion()) text += "Success!" feedback_add_details(feedback_tag,"[O.type]|SUCCESS") else @@ -21,11 +21,11 @@ failed = 1 num++ - if(!config.objectives_disabled) - if(failed) - text += "
The [role_text] has failed." - else - text += "
The [role_text] was successful!" + if(!config.objectives_disabled) + if(failed) + text += "
The [role_text] has failed." + else + text += "
The [role_text] was successful!" if(global_objectives && global_objectives.len) text += "
Their objectives were:" diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm index a06b3e5993..0fd5fb2a93 100644 --- a/code/game/antagonist/antagonist_update.dm +++ b/code/game/antagonist/antagonist_update.dm @@ -62,15 +62,10 @@ qdel(I) /datum/antagonist/proc/update_current_antag_max() - - candidates = list() var/main_type if(ticker && ticker.mode) if(ticker.mode.antag_tag && ticker.mode.antag_tag == id) main_type = 1 - else - return list() - cur_max = (main_type ? max_antags_round : max_antags) if(ticker.mode.antag_scaling_coeff) - cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max) \ No newline at end of file + cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max) diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm index 17083eb89a..3149db81bc 100644 --- a/code/game/antagonist/outsider/ninja.dm +++ b/code/game/antagonist/outsider/ninja.dm @@ -9,8 +9,8 @@ var/datum/antagonist/ninja/ninjas landmark_id = "ninjastart" welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor." flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE - max_antags = 3 - max_antags_round = 3 + max_antags = 1//3 + max_antags_round = 1//3 /datum/antagonist/ninja/New() ..() @@ -164,7 +164,7 @@ var/datum/antagonist/ninja/ninjas if(17) directive += "The Spider Clan has recently begun recruiting outsiders. Consider suitable candidates and assess their behavior amongst the crew." if(18) - directive += "A cyborg liberation group has expressed interest in our serves. Prove the Spider Clan merciful towards law-bound synthetics." + directive += "A cyborg liberation group has expressed interest in our services. Prove the Spider Clan merciful towards law-bound synthetics." else directive += "There are no special supplemental instructions at this time." return directive diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 76ab7b5106..eaa7e67e5f 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -42,17 +42,10 @@ var/global/list/additional_antag_types = list() var/antag_tag // First (main) antag template to spawn. var/list/antag_templates // Extra antagonist types to include. - + var/list/latejoin_templates = list() var/round_autoantag = 0 // Will this round attempt to periodically spawn more antagonists? - var/antag_prob = 0 // Likelihood of a new antagonist spawning. - var/antag_count = 0 // Current number of antagonists. var/antag_scaling_coeff = 5 // Coefficient for scaling max antagonists to player count. - var/list/living_antag_templates = list() // Currently selected antag types that do not require a ghosted player. - var/list/ghost_antag_templates = list() // Inverse of above. - var/list/antag_candidates = list() // Living antag candidates. - var/list/ghost_candidates = list() // Observing antag candidates. - var/station_was_nuked = 0 // See nuclearbomb.dm and malfunction.dm. var/explosion_in_progress = 0 // Sit back and relax var/waittime_l = 600 // Lower bound on time before intercept arrives (in tenths of seconds) @@ -272,7 +265,6 @@ var/global/list/additional_antag_types = list() EMajor.delay_modifier = event_delay_mod_major ///post_setup() -///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things /datum/game_mode/proc/post_setup() refresh_event_modifiers() @@ -285,9 +277,11 @@ var/global/list/additional_antag_types = list() spawn(rand(100,150)) announce_ert_disabled() - //if(antag_templates && antag_templates.len) - // for(var/datum/antagonist/antag in antag_templates) - // antag.finalize() + if(antag_templates && antag_templates.len) + for(var/datum/antagonist/antag in antag_templates) + antag.finalize_spawn() + if(antag.is_latejoin_template()) + latejoin_templates |= antag if(emergency_shuttle && auto_recall_shuttle) emergency_shuttle.auto_recall = 1 @@ -336,67 +330,6 @@ var/global/list/additional_antag_types = list() ) command_announcement.Announce("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time, and post-evacuation recovery efforts will be substantially delayed.","Emergency Transmission") -///process() -///Called by the gameticker -/datum/game_mode/proc/process() - - if(emergency_shuttle.departed) - return - - if(!round_autoantag || !antag_templates || !antag_templates.len) - return - - var/player_count = 0 - antag_count = 0 - antag_candidates = list() - - for(var/mob/living/player in mob_list) - if(player.client) - player_count += 1 - if(player.mind) - if(player.stat == 2) // observing - ghost_candidates |= player - else - if(player.mind.special_role) - antag_count += 1 - else - antag_candidates |= player - - antag_prob = min(100,max(0,(player_count - 5 * 10) * 5)) // This is arbitrary, probably needs adjusting. - - var/datum/antagonist/spawn_antag - var/datum/mind/candidate - - var/from_ghosts - if(prob(antag_prob)) - if(ghost_candidates.len && ghost_antag_templates.len && prob(50)) - spawn_antag = pick(ghost_antag_templates) - candidate = pick(ghost_candidates) - from_ghosts = 1 - else if(antag_candidates.len && living_antag_templates.len) - spawn_antag = pick(living_antag_templates) - candidate = pick(antag_candidates) - else - return // Failed :( - else - return - - if(spawn_antag.can_become_antag(candidate)) - spawn_antag.attempt_late_spawn(candidate, from_ghosts) - -/datum/game_mode/proc/latespawn(mob/living/carbon/human/character) - - if(emergency_shuttle.departed || !character.mind) - return - - var/datum/antagonist/spawn_antag - if(prob(antag_prob) && round_autoantag && living_antag_templates.len) - spawn_antag = pick(living_antag_templates) - if(spawn_antag && spawn_antag.can_become_antag(character.mind)) - spawn_antag.attempt_late_spawn(character.mind) - - return 0 - /datum/game_mode/proc/check_finished() if(emergency_shuttle.returned() || station_was_nuked) return 1 @@ -623,13 +556,10 @@ var/global/list/additional_antag_types = list() if(antag_templates && antag_templates.len) for(var/datum/antagonist/antag in antag_templates) - if(antag.flags & ANTAG_OVERRIDE_JOB) - ghost_antag_templates |= antag - else if(antag.flags & ANTAG_RANDSPAWN) - living_antag_templates |= antag - else - antag_templates -= antag - world << "[antag.role_text_plural] are invalid for additional roundtype antags!" + if(antag.flags & (ANTAG_OVERRIDE_JOB|ANTAG_RANDSPAWN)) + continue + antag_templates -= antag + world << "[antag.role_text_plural] are invalid for additional roundtype antags!" newscaster_announcements = pick(newscaster_standard_feeds) diff --git a/code/game/gamemodes/game_mode_latespawn.dm b/code/game/gamemodes/game_mode_latespawn.dm new file mode 100644 index 0000000000..9af3524144 --- /dev/null +++ b/code/game/gamemodes/game_mode_latespawn.dm @@ -0,0 +1,43 @@ +/datum/game_mode/proc/get_usable_templates(var/list/supplied_templates) + var/list/usable_templates = list() + for(var/datum/antagonist/A in supplied_templates) + if(A.can_late_spawn()) + usable_templates |= A + return usable_templates + +///process() +///Called by the gameticker +/datum/game_mode/proc/process() + try_latespawn() + +/datum/game_mode/proc/latespawn(var/mob/living/carbon/human/character) + if(!character.mind) + return + try_latespawn(character.mind) + return 0 + +/datum/game_mode/proc/try_latespawn(var/datum/mind/player, var/latejoin_only) + + if(emergency_shuttle.departed || !round_autoantag) + return + + if(!prob(get_antag_prob())) + return + + var/list/usable_templates + if(latejoin_only && latejoin_templates.len) + usable_templates = get_usable_templates(latejoin_templates) + else if (antag_templates.len) + usable_templates = get_usable_templates(antag_templates) + else + return + if(usable_templates.len) + var/datum/antagonist/spawn_antag = pick(usable_templates) + spawn_antag.attempt_late_spawn(player) + +/datum/game_mode/proc/get_antag_prob() + var/player_count = 0 + for(var/mob/living/M in mob_list) + if(M.client) + player_count += 1 + return min(100,max(0,(player_count - 5 * 10) * 5)) \ No newline at end of file diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index c91d77dba2..452754d746 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1164,7 +1164,7 @@ proc/admin_notice(var/message, var/rights) out += "Core antag id: [ticker.mode.antag_tag].
" if(ticker.mode.round_autoantag) - out += "Autotraitor enabled ([ticker.mode.antag_prob]% spawn chance)" + out += "Autotraitor enabled ([ticker.mode.get_antag_prob()]% spawn chance)" if(ticker.mode.antag_scaling_coeff) out += " (scaling with [ticker.mode.antag_scaling_coeff])" out += "
" From 41cb4335175d444471a72af7bade7377d9d8eec1 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Sun, 21 Jun 2015 20:05:23 +0930 Subject: [PATCH 09/10] Fixes #9393 --- code/game/antagonist/outsider/ninja.dm | 6 +++--- code/game/antagonist/outsider/wizard.dm | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm index 3149db81bc..17083eb89a 100644 --- a/code/game/antagonist/outsider/ninja.dm +++ b/code/game/antagonist/outsider/ninja.dm @@ -9,8 +9,8 @@ var/datum/antagonist/ninja/ninjas landmark_id = "ninjastart" welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor." flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE - max_antags = 1//3 - max_antags_round = 1//3 + max_antags = 3 + max_antags_round = 3 /datum/antagonist/ninja/New() ..() @@ -164,7 +164,7 @@ var/datum/antagonist/ninja/ninjas if(17) directive += "The Spider Clan has recently begun recruiting outsiders. Consider suitable candidates and assess their behavior amongst the crew." if(18) - directive += "A cyborg liberation group has expressed interest in our services. Prove the Spider Clan merciful towards law-bound synthetics." + directive += "A cyborg liberation group has expressed interest in our serves. Prove the Spider Clan merciful towards law-bound synthetics." else directive += "There are no special supplemental instructions at this time." return directive diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm index 93e44974e9..74866d9247 100644 --- a/code/game/antagonist/outsider/wizard.dm +++ b/code/game/antagonist/outsider/wizard.dm @@ -10,6 +10,7 @@ var/datum/antagonist/wizard/wizards welcome_text = "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.
In your pockets you will find a teleport scroll. Use it as needed." flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE max_antags = 1 + max_antags_round = 1 /datum/antagonist/wizard/New() ..() From 7476160008434bbfe35f3470a8db1f668597fc3f Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Sun, 21 Jun 2015 20:08:13 +0930 Subject: [PATCH 10/10] Fixes #9876 --- code/game/antagonist/station/traitor.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm index 8813c41fe5..825f615bea 100644 --- a/code/game/antagonist/station/traitor.dm +++ b/code/game/antagonist/station/traitor.dm @@ -18,7 +18,7 @@ var/datum/antagonist/traitor/traitors /datum/antagonist/traitor/Topic(href, href_list) if (..()) return - if(href_list["spawn_uplink"]) spawn_uplink(href_list["spawn_uplink"]) + if(href_list["spawn_uplink"]) spawn_uplink(locate(href_list["spawn_uplink"])) /datum/antagonist/traitor/create_objectives(var/datum/mind/traitor) if(!..())