From 82a331e777c2f5cb2edf1c8ada4a5f73a3a506cf Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Thu, 2 Jun 2022 13:39:09 +0300 Subject: [PATCH 01/86] Update computer.dm --- code/modules/shuttle/computer.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/shuttle/computer.dm b/code/modules/shuttle/computer.dm index 829da6224a1c..642305964b0d 100644 --- a/code/modules/shuttle/computer.dm +++ b/code/modules/shuttle/computer.dm @@ -137,3 +137,7 @@ /obj/machinery/computer/shuttle/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE) if(port && (shuttleId == initial(shuttleId) || override)) shuttleId = port.id + +/obj/machinery/computer/shuttle/AltClick(user) + if(istype(user, /mob/living/carbon) || istype(user, /mob/living/simple_animal/hostile/asteroid/elite)) + ui_interact(user, null) From 3fc045e2e54c27799a4d48a9f1d8365041afce81 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Sat, 4 Jun 2022 16:50:12 +0300 Subject: [PATCH 02/86] Update meat.dm --- code/modules/food_and_drinks/food/snacks/meat.dm | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/code/modules/food_and_drinks/food/snacks/meat.dm b/code/modules/food_and_drinks/food/snacks/meat.dm index 15c73412feb7..12abbd676081 100644 --- a/code/modules/food_and_drinks/food/snacks/meat.dm +++ b/code/modules/food_and_drinks/food/snacks/meat.dm @@ -340,18 +340,6 @@ icon_state = "shadowmeat" desc = "It is covered in a strange darkness. This slab's magical properties appear to be drastically weakened due to the synthetic nature of the meat." -/obj/item/reagent_containers/food/snacks/meat/slab/plagued - name = "meat" - desc = "A slab of disease-ridden meat. Eating it is a questionable idea." - icon_state = "meat" - dried_type = /obj/item/reagent_containers/food/snacks/sosjerky/ - bitesize = 3 - list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/cooking_oil = 2, /datum/reagent/plaguebacteria = 3) //It is infected by plague - slice_path = /obj/item/reagent_containers/food/snacks/meat/raw_cutlet/plain - slices_num = 3 - filling_color = "#FF0000" - tastes = list("meat" = 2, "decay" = 1) - foodtype = MEAT | RAW ////////////////////////////////////// MEAT STEAKS /////////////////////////////////////////////////////////// From db1f40761e99e3395158c3c0a443b3efdae5b925 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 7 Jun 2022 16:11:33 +0300 Subject: [PATCH 03/86] Update objects.dm --- code/_globalvars/lists/objects.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 331f30de8bd1..87a4a0f38cb0 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -40,3 +40,5 @@ GLOBAL_LIST_EMPTY(ai_core_displays) GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert GLOBAL_LIST_INIT(alarms, list("Fire" = list(), "Atmosphere" = list(), "Power" = list())) //all engineering alerts for station alert consoles and alarm manager + +GLOBAL_LIST_EMPTY(hog_structures) From 2558753f387843ad6a8530920d15409b834899a1 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 14 Jun 2022 20:36:00 +0300 Subject: [PATCH 04/86] Update computer.dm --- code/modules/shuttle/computer.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/shuttle/computer.dm b/code/modules/shuttle/computer.dm index 642305964b0d..829da6224a1c 100644 --- a/code/modules/shuttle/computer.dm +++ b/code/modules/shuttle/computer.dm @@ -137,7 +137,3 @@ /obj/machinery/computer/shuttle/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE) if(port && (shuttleId == initial(shuttleId) || override)) shuttleId = port.id - -/obj/machinery/computer/shuttle/AltClick(user) - if(istype(user, /mob/living/carbon) || istype(user, /mob/living/simple_animal/hostile/asteroid/elite)) - ui_interact(user, null) From e5a044ca51e9fadb76cf73b230d6d66a2fd1c236 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 14 Jun 2022 20:36:31 +0300 Subject: [PATCH 05/86] Update meat.dm --- code/modules/food_and_drinks/food/snacks/meat.dm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/code/modules/food_and_drinks/food/snacks/meat.dm b/code/modules/food_and_drinks/food/snacks/meat.dm index 12abbd676081..15c73412feb7 100644 --- a/code/modules/food_and_drinks/food/snacks/meat.dm +++ b/code/modules/food_and_drinks/food/snacks/meat.dm @@ -340,6 +340,18 @@ icon_state = "shadowmeat" desc = "It is covered in a strange darkness. This slab's magical properties appear to be drastically weakened due to the synthetic nature of the meat." +/obj/item/reagent_containers/food/snacks/meat/slab/plagued + name = "meat" + desc = "A slab of disease-ridden meat. Eating it is a questionable idea." + icon_state = "meat" + dried_type = /obj/item/reagent_containers/food/snacks/sosjerky/ + bitesize = 3 + list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/cooking_oil = 2, /datum/reagent/plaguebacteria = 3) //It is infected by plague + slice_path = /obj/item/reagent_containers/food/snacks/meat/raw_cutlet/plain + slices_num = 3 + filling_color = "#FF0000" + tastes = list("meat" = 2, "decay" = 1) + foodtype = MEAT | RAW ////////////////////////////////////// MEAT STEAKS /////////////////////////////////////////////////////////// From 6705493de9ccbbe95b742bc166220935deedf83e Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 14 Jun 2022 20:36:53 +0300 Subject: [PATCH 06/86] Update objects.dm --- code/_globalvars/lists/objects.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 87a4a0f38cb0..331f30de8bd1 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -40,5 +40,3 @@ GLOBAL_LIST_EMPTY(ai_core_displays) GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert GLOBAL_LIST_INIT(alarms, list("Fire" = list(), "Atmosphere" = list(), "Power" = list())) //all engineering alerts for station alert consoles and alarm manager - -GLOBAL_LIST_EMPTY(hog_structures) From 86f4d4fe847dce628413babbdacf4a02e683cb00 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Mon, 27 Jun 2022 16:00:36 +0300 Subject: [PATCH 07/86] boowomp --- code/datums/mood_events/generic_negative_events.dm | 4 ++++ code/game/objects/items/clown_items.dm | 4 +++- yogstation/code/game/objects/items/clown_items.dm | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 9edfcb07ce9d..7079d65816ca 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -222,3 +222,7 @@ description = "HE'S CUTTING ME OPEN!!\n" mood_change = -8 +/datum/mood_event/boowomp + description = "I've been boowomped.\n" + mood_change = -1 + timeout = 4 MINUTES \ No newline at end of file diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index 599ccff1d2c9..300a38322176 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -153,6 +153,7 @@ throw_speed = 3 throw_range = 7 attack_verb = list("HONKED") + var/funny = TRUE /obj/item/bikehorn/afterattack(atom/target, mob/user, proximity_flag, click_parameters) . = ..() @@ -169,7 +170,8 @@ AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50) /obj/item/bikehorn/attack(mob/living/carbon/M, mob/living/carbon/user) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk) + if(funny) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk) return ..() /obj/item/bikehorn/suicide_act(mob/user) diff --git a/yogstation/code/game/objects/items/clown_items.dm b/yogstation/code/game/objects/items/clown_items.dm index 2a9fd7ba9756..52ef94d19346 100644 --- a/yogstation/code/game/objects/items/clown_items.dm +++ b/yogstation/code/game/objects/items/clown_items.dm @@ -24,7 +24,12 @@ name = "sad horn" desc = "Thank you, Doktor." attack_verb = list("Boowomped") + funny = FALSE /obj/item/bikehorn/sad/Initialize() . = ..() AddComponent(/datum/component/squeak, list('yogstation/sound/items/boowomp.ogg'=1), 50) + +/obj/item/bikehorn/sad/attack(mob/living/carbon/M, mob/living/carbon/user) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "boowomp", /datum/mood_event/boowomp) ///because it is a sad horn! + return ..() \ No newline at end of file From 7f26672d4b6ee1345dcfc678cf75ccdb25ae2fbf Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Mon, 27 Jun 2022 16:01:51 +0300 Subject: [PATCH 08/86] e --- code/datums/mood_events/generic_negative_events.dm | 5 ----- code/game/objects/items/clown_items.dm | 4 +--- yogstation/code/game/objects/items/clown_items.dm | 4 ---- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 7079d65816ca..e5fc41d754e2 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -221,8 +221,3 @@ /datum/mood_event/surgery description = "HE'S CUTTING ME OPEN!!\n" mood_change = -8 - -/datum/mood_event/boowomp - description = "I've been boowomped.\n" - mood_change = -1 - timeout = 4 MINUTES \ No newline at end of file diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index 300a38322176..599ccff1d2c9 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -153,7 +153,6 @@ throw_speed = 3 throw_range = 7 attack_verb = list("HONKED") - var/funny = TRUE /obj/item/bikehorn/afterattack(atom/target, mob/user, proximity_flag, click_parameters) . = ..() @@ -170,8 +169,7 @@ AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50) /obj/item/bikehorn/attack(mob/living/carbon/M, mob/living/carbon/user) - if(funny) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk) return ..() /obj/item/bikehorn/suicide_act(mob/user) diff --git a/yogstation/code/game/objects/items/clown_items.dm b/yogstation/code/game/objects/items/clown_items.dm index 52ef94d19346..a61ee950cdad 100644 --- a/yogstation/code/game/objects/items/clown_items.dm +++ b/yogstation/code/game/objects/items/clown_items.dm @@ -29,7 +29,3 @@ /obj/item/bikehorn/sad/Initialize() . = ..() AddComponent(/datum/component/squeak, list('yogstation/sound/items/boowomp.ogg'=1), 50) - -/obj/item/bikehorn/sad/attack(mob/living/carbon/M, mob/living/carbon/user) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "boowomp", /datum/mood_event/boowomp) ///because it is a sad horn! - return ..() \ No newline at end of file From 4d2a2f36ae00b8a5b41bd1e7f2014a976ed180f5 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Mon, 27 Jun 2022 16:03:52 +0300 Subject: [PATCH 09/86] s --- yogstation/code/game/objects/items/clown_items.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/yogstation/code/game/objects/items/clown_items.dm b/yogstation/code/game/objects/items/clown_items.dm index a61ee950cdad..2a9fd7ba9756 100644 --- a/yogstation/code/game/objects/items/clown_items.dm +++ b/yogstation/code/game/objects/items/clown_items.dm @@ -24,7 +24,6 @@ name = "sad horn" desc = "Thank you, Doktor." attack_verb = list("Boowomped") - funny = FALSE /obj/item/bikehorn/sad/Initialize() . = ..() From f2a5fd35194618acf3a65b16a09cf4f13b4dfaaa Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 28 Jun 2022 21:54:10 +0300 Subject: [PATCH 10/86] s --- code/__DEFINES/antagonists.dm | 2 + code/_onclick/hud/blob_overmind.dm | 6 +- code/_onclick/hud/radial.dm | 16 +++-- code/game/objects/effects/info.dm | 26 +++++++ .../blob/blobstrains/_blobstrain.dm | 2 +- code/modules/antagonists/blob/overmind.dm | 4 ++ code/modules/antagonists/blob/powers.dm | 70 ++++++++++++++----- 7 files changed, 98 insertions(+), 28 deletions(-) create mode 100644 code/game/objects/effects/info.dm diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index ccdc70876238..3e9067499976 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -124,3 +124,5 @@ #define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal)) #define IS_MONSTERHUNTER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/monsterhunter)) +/// How much does it cost to reroll strains? +#define BLOB_REROLL_COST 40 \ No newline at end of file diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index 5e352112f26b..bcb7856be825 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -93,17 +93,17 @@ /obj/screen/blob/ReadaptStrain icon_state = "ui_chemswap" - name = "Readapt Strain (40)" + name = "Readapt Strain" desc = "Allows you to choose a new strain from 4 random choices for 40 resources." /obj/screen/blob/ReadaptStrain/MouseEntered(location,control,params) if(hud && hud.mymob && isovermind(hud.mymob)) var/mob/camera/blob/B = hud.mymob if(B.free_strain_rerolls) - name = "Readapt Strain (FREE)" + name = "[initial(name)] (FREE)" desc = "Randomly rerolls your strain for free." else - name = initial(name) + name = "[initial(name)] ([BLOB_REROLL_COST])" desc = initial(desc) ..() diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 85e3914b8513..926f117858bd 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -211,16 +211,20 @@ GLOBAL_LIST_EMPTY(radial_menus) var/atom/movable/AM = choices_values[choice_id] //Movables only E.name = AM.name + E.choice = choice_id + E.maptext = null + E.next_page = FALSE + if(choices_icons[choice_id]) E.add_overlay(choices_icons[choice_id]) - var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id] - if(choice_datum && istext(choice_datum.info)) - E.desc = choice_datum.info + if (choice_datums[choice_id]) + var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id] + if (choice_datum.info) + var/obj/effect/abstract/info/info_button = new(E, choice_datum.info) + info_button.layer = ABOVE_HUD_LAYER + E.vis_contents += info_button - E.choice = choice_id - E.maptext = null - E.next_page = FALSE /datum/radial_menu/New() close_button = new diff --git a/code/game/objects/effects/info.dm b/code/game/objects/effects/info.dm new file mode 100644 index 000000000000..0c9e3abf252c --- /dev/null +++ b/code/game/objects/effects/info.dm @@ -0,0 +1,26 @@ +/// An info button that, when clicked, puts some text in the user's chat +/obj/effect/abstract/info + name = "info" + icon = 'icons/effects/effects.dmi' + icon_state = "info" + + /// What should the info button display when clicked? + var/info_text + +/obj/effect/abstract/info/Initialize(mapload, info_text) + . = ..() + + if (!isnull(info_text)) + src.info_text = info_text + +/obj/effect/abstract/info/Click() + . = ..() + to_chat(usr, info_text) + +/obj/effect/abstract/info/MouseEntered() + . = ..() + icon_state = "info_hovered" + +/obj/effect/abstract/info/MouseExited() + . = ..() + icon_state = initial(icon_state) \ No newline at end of file diff --git a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm index ad439d962de2..a9fa8350e79b 100644 --- a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm +++ b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm @@ -8,7 +8,7 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/ var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects var/effectdesc = null //any long, blob-tile specific effects var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp." - var/analyzerdesceffect = "N/A" + var/analyzerdesceffect var/blobbernaut_message = "slams" //blobbernaut attack verb var/message = "The blob strikes you" //message sent to any mob hit by the blob var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index 9cc0c8df26a9..5b1639414f1e 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -44,6 +44,9 @@ GLOBAL_LIST_EMPTY(blob_nodes) var/has_announced = FALSE var/basemodifier = 1 + /// The list of strains the blob can reroll for. + var/list/strain_choices + /mob/camera/blob/Initialize(mapload, starting_points = 60, pointmodifier = 1) validate_location() blob_points = starting_points @@ -186,6 +189,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) BM.overmind = null BM.update_icons() GLOB.overminds -= src + QDEL_LIST_ASSOC_VAL(strain_choices) SSshuttle.clearHostileEnvironment(src) STOP_PROCESSING(SSobj, src) diff --git a/code/modules/antagonists/blob/powers.dm b/code/modules/antagonists/blob/powers.dm index 5a8110bfc7ca..1131e4017bf2 100644 --- a/code/modules/antagonists/blob/powers.dm +++ b/code/modules/antagonists/blob/powers.dm @@ -1,3 +1,6 @@ +#define BLOB_REROLL_CHOICES 6 +#define BLOB_REROLL_RADIUS 60 + /mob/camera/blob/proc/can_buy(cost = 15) if(blob_points < cost) to_chat(src, span_warning("You cannot afford this, you need at least [cost] resources!")) @@ -340,25 +343,53 @@ set category = "Blob" set name = "Reactive Strain Adaptation (40)" set desc = "Replaces your strain with a random, different one." - if(!rerolling && (free_strain_rerolls || can_buy(40))) - rerolling = TRUE - reroll_strain() - rerolling = FALSE - if(free_strain_rerolls) - free_strain_rerolls-- - last_reroll_time = world.time - -/mob/camera/blob/proc/reroll_strain() - var/list/choices = list() - while (length(choices) < 4) - var/datum/blobstrain/bs = pick((GLOB.valid_blobstrains)) - choices[initial(bs.name)] = bs - - var/choice = input(usr, "Please choose a new strain","Strain") as anything in choices - if (choice && choices[choice] && !QDELETED(src)) - var/datum/blobstrain/bs = choices[choice] - set_strain(bs) + if (!free_strain_rerolls && blob_points < BLOB_REROLL_COST) + to_chat(src, "You need at least [BLOB_REROLL_COST] resources to reroll your strain again!") + return + + open_reroll_menu() + +/// Open the menu to reroll strains +/mob/camera/blob/proc/open_reroll_menu() + if (!strain_choices) + strain_choices = list() + + var/list/new_strains = GLOB.valid_blobstrains.Copy() + for (var/_ in 1 to BLOB_REROLL_CHOICES) + var/datum/blobstrain/strain = pick_n_take(new_strains) + + var/image/strain_icon = image('icons/mob/blob.dmi', "blob_core") + strain_icon.color = initial(strain.color) + + var/info_text = "[initial(strain.name)]" + info_text += "
[initial(strain.analyzerdescdamage)]" + if (!isnull(initial(strain.analyzerdesceffect))) + info_text += "
[initial(strain.analyzerdesceffect)]" + + var/datum/radial_menu_choice/choice = new + choice.image = strain_icon + choice.info = info_text + + strain_choices[initial(strain.name)] = choice + var/strain_result = show_radial_menu(src, src, strain_choices, radius = BLOB_REROLL_RADIUS, tooltips = TRUE) + if (isnull(strain_result)) + return + + if (!free_strain_rerolls && !can_buy(BLOB_REROLL_COST)) + return + + for (var/_other_strain in GLOB.valid_blobstrains) + var/datum/blobstrain/other_strain = _other_strain + if (initial(other_strain.name) == strain_result) + set_strain(other_strain) + + if (free_strain_rerolls) + free_strain_rerolls -= 1 + + last_reroll_time = world.time + + return /mob/camera/blob/verb/blob_help() set category = "Blob" @@ -383,3 +414,6 @@ if(!placed && autoplace_max_time <= world.time) to_chat(src, span_big("You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)].")) to_chat(src, span_big("You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen.")) + +#undef BLOB_REROLL_CHOICES +#undef BLOB_REROLL_RADIUS \ No newline at end of file From dfc5e8a49e6c48061fabff8ec95b0b2c6cbaf567 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 28 Jun 2022 22:28:51 +0300 Subject: [PATCH 11/86] 3 --- code/modules/antagonists/blob/structures/_blob.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm index a65b79e33b41..68fdf4075658 100644 --- a/code/modules/antagonists/blob/structures/_blob.dm +++ b/code/modules/antagonists/blob/structures/_blob.dm @@ -244,7 +244,7 @@ if(overmind) . += list("Material: [overmind.blobstrain.name][span_notice(".")]", "Material Effects: [span_notice("[overmind.blobstrain.analyzerdescdamage]")]", - "Material Properties: [span_notice("[overmind.blobstrain.analyzerdesceffect]")]") + "Material Properties: [overmind.blobstrain.analyzerdesceffect || "N/A"]") else . += "No Material Detected!" From 7ae0659d568481d4c91a7364836c55ea34666ad4 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 14:45:05 +0300 Subject: [PATCH 12/86] rev --- code/__DEFINES/role_preferences.dm | 1 + code/controllers/subsystem/job.dm | 2 + code/datums/mind.dm | 2 + .../gamemodes/dynamic/dynamic_rulesets.dm | 5 - .../dynamic/dynamic_rulesets_latejoin.dm | 58 ++---- .../dynamic/dynamic_rulesets_roundstart.dm | 51 +----- code/modules/admin/antag_panel.dm | 2 +- .../antagonists/revolution/revolution.dm | 165 ++++++++++++++++-- code/modules/events/bureaucratic_error.dm | 18 +- code/modules/jobs/job_types/_job.dm | 3 + code/modules/jobs/job_types/ai.dm | 1 + strings/anti_union_propaganda.txt | 4 + 12 files changed, 197 insertions(+), 115 deletions(-) create mode 100644 strings/anti_union_propaganda.txt diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 07bb830ece9a..388bba808595 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -16,6 +16,7 @@ #define ROLE_MALF "Malf AI" #define ROLE_REV "Revolutionary" #define ROLE_REV_HEAD "Head Revolutionary" +#define ROLE_REV_SUCCESSFUL "Victorious Revolutionary" #define ROLE_ALIEN "Xenomorph" #define ROLE_PAI "pAI" #define ROLE_CULTIST "Cultist" diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index d0de6312dba6..fb921b14c20a 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -30,11 +30,13 @@ SUBSYSTEM_DEF(job) var/datum/job/new_overflow = GetJob(new_overflow_role) var/cap = CONFIG_GET(number/overflow_cap) + new_overflow.allow_bureaucratic_error = FALSE new_overflow.spawn_positions = cap new_overflow.total_positions = cap if(new_overflow_role != overflow_role) var/datum/job/old_overflow = GetJob(overflow_role) + old_overflow.allow_bureaucratic_error = initial(old_overflow.allow_bureaucratic_error) old_overflow.spawn_positions = initial(old_overflow.spawn_positions) old_overflow.total_positions = initial(old_overflow.total_positions) overflow_role = new_overflow_role diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 43f063a24237..079ad25db409 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -88,6 +88,8 @@ var/afk_verb_used = FALSE /// The timer for the afk verb var/afk_verb_timer + /// A lazy list of statuses to add next to this mind in the traitor panel + var/list/special_statuses /datum/mind/New(key) src.key = key diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index efbab7a576eb..600e34fbb43a 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -183,11 +183,6 @@ /// Only called if ruleset is flagged as HIGH_IMPACT_RULESET /datum/dynamic_ruleset/proc/round_result() -/// Checks if round is finished, return true to end the round. -/// Only called if ruleset is flagged as HIGH_IMPACT_RULESET -/datum/dynamic_ruleset/proc/check_finished() - return FALSE - ////////////////////////////////////////////// // // // ROUNDSTART RULESETS // diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 2cf8d95e5442..721a7f928d78 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -93,6 +93,8 @@ blocking_rules = list(/datum/dynamic_ruleset/roundstart/revs) var/required_heads_of_staff = 3 var/finished = FALSE + /// How much threat should be injected when the revolution wins? + var/revs_win_threat_injection = 20 var/datum/team/revolution/revolution /datum/dynamic_ruleset/latejoin/provocateur/ready(forced=FALSE) @@ -119,7 +121,7 @@ new_head = M.mind.add_antag_datum(new_head, revolution) revolution.update_objectives() revolution.update_heads() - SSshuttle.registerHostileEnvironment(src) + SSshuttle.registerHostileEnvironment(revolution) return TRUE else log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.") @@ -127,27 +129,12 @@ return FALSE /datum/dynamic_ruleset/latejoin/provocateur/rule_process() - if(check_rev_victory()) - finished = REVOLUTION_VICTORY - return RULESET_STOP_PROCESSING - else if (check_heads_victory()) - finished = STATION_VICTORY - SSshuttle.clearHostileEnvironment(src) - revolution.save_members() - for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions. - if(M.has_antag_datum(/datum/antagonist/rev/head)) - var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head) - R.remove_revolutionary(FALSE, "gamemode") - if(M.current) - var/mob/living/carbon/C = M.current - if(istype(C) && C.stat == DEAD) - C.makeUncloneable() - if(M.has_antag_datum(/datum/antagonist/rev)) - var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev) - R.remove_revolutionary(FALSE, "gamemode") - priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \ - We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division") - return RULESET_STOP_PROCESSING + var/winner = revolution.process_victory(revs_win_threat_injection) + if (isnull(winner)) + return + + finished = winner + return RULESET_STOP_PROCESSING @@ -158,33 +145,8 @@ return TRUE return FALSE -/datum/dynamic_ruleset/latejoin/provocateur/check_finished() - if(finished == REVOLUTION_VICTORY) - return TRUE - else - return ..() - -/datum/dynamic_ruleset/latejoin/provocateur/proc/check_rev_victory() - for(var/datum/objective/mutiny/objective in revolution.objectives) - if(!(objective.check_completion())) - return FALSE - return TRUE - -/datum/dynamic_ruleset/latejoin/provocateur/proc/check_heads_victory() - for(var/datum/mind/rev_mind in revolution.head_revolutionaries()) - var/turf/T = get_turf(rev_mind.current) - if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z)) - if(ishuman(rev_mind.current) || ismonkey(rev_mind.current)) - return FALSE - return TRUE - /datum/dynamic_ruleset/latejoin/provocateur/round_result() - if(finished == REVOLUTION_VICTORY) - SSticker.mode_result = "win - heads killed" - SSticker.news_report = REVS_WIN - else if(finished == STATION_VICTORY) - SSticker.mode_result = "loss - rev heads killed" - SSticker.news_report = REVS_LOSE + revolution.round_result(finished) ////////////////////////////////////////////// // // diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 6f75591d5968..a472e53b9cf3 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -410,7 +410,7 @@ if(revolution.members.len) revolution.update_objectives() revolution.update_heads() - SSshuttle.registerHostileEnvironment(src) + SSshuttle.registerHostileEnvironment(revolution) return TRUE log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.") return FALSE @@ -420,30 +420,12 @@ ..() /datum/dynamic_ruleset/roundstart/revs/rule_process() - if(!revolution) - log_game("DYNAMIC: Something went horrifically wrong with [name] - and the antag datum could not be created. Notify coders.") + var/winner = revolution.process_victory(revs_win_threat_injection) + if (isnull(winner)) return - if(check_rev_victory()) - finished = REVOLUTION_VICTORY - return RULESET_STOP_PROCESSING - else if (check_heads_victory()) - finished = STATION_VICTORY - SSshuttle.clearHostileEnvironment(src) - revolution.save_members() - for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions. - if(M.has_antag_datum(/datum/antagonist/rev/head)) - var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head) - R.remove_revolutionary(FALSE, "gamemode") - if(M.current) - var/mob/living/carbon/C = M.current - if(istype(C) && C.stat == DEAD) - C.makeUncloneable() - if(M.has_antag_datum(/datum/antagonist/rev)) - var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev) - R.remove_revolutionary(FALSE, "gamemode") - priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \ - We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division") - return RULESET_STOP_PROCESSING + + finished = winner + return RULESET_STOP_PROCESSING /// Checks for revhead loss conditions and other antag datums. /datum/dynamic_ruleset/roundstart/revs/proc/check_eligible(var/datum/mind/M) @@ -458,27 +440,8 @@ else return ..() -/datum/dynamic_ruleset/roundstart/revs/proc/check_rev_victory() - for(var/datum/objective/mutiny/objective in revolution.objectives) - if(!(objective.check_completion())) - return FALSE - return TRUE - -/datum/dynamic_ruleset/roundstart/revs/proc/check_heads_victory() - for(var/datum/mind/rev_mind in revolution.head_revolutionaries()) - var/turf/T = get_turf(rev_mind.current) - if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z)) - if(ishuman(rev_mind.current) || ismonkey(rev_mind.current)) - return FALSE - return TRUE - /datum/dynamic_ruleset/roundstart/revs/round_result() - if(finished == REVOLUTION_VICTORY) - SSticker.mode_result = "win - heads killed" - SSticker.news_report = REVS_WIN - else if(finished == STATION_VICTORY) - SSticker.mode_result = "loss - rev heads killed" - SSticker.news_report = REVS_LOSE + revolution.round_result(finished) // Admin only rulesets. The threat requirement is 101 so it is not possible to roll them. diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm index a41a7ff229b1..12254c2e155d 100644 --- a/code/modules/admin/antag_panel.dm +++ b/code/modules/admin/antag_panel.dm @@ -78,7 +78,7 @@ GLOBAL_VAR(antag_prototypes) return common_commands /datum/mind/proc/get_special_statuses() - var/list/result = list() + var/list/result = LAZYCOPY(special_statuses) if(!current) result += span_bad("No body!") if(current && HAS_TRAIT(current, TRAIT_MINDSHIELD)) diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index ebb9aa0d6066..7f4da5843334 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -1,3 +1,5 @@ +#define DECONVERTER_STATION_WIN "gamemode_station_win" +#define DECONVERTER_REVS_WIN "gamemode_revs_win" //How often to check for promotion possibility #define HEAD_UPDATE_PERIOD 300 @@ -10,6 +12,9 @@ var/hud_type = "rev" var/datum/team/revolution/rev_team + /// What message should the player receive when they are being demoted, and the revolution has won? + var/victory_message = "The revolution has overpowered the command staff! Viva la revolution! Execute any head of staff and security should you find them alive." + /datum/antagonist/rev/can_be_owned(datum/mind/new_owner) . = ..() if(.) @@ -209,7 +214,22 @@ new_rev.silent = FALSE to_chat(old_owner, span_userdanger("Revolution has been disappointed of your leader traits! You are a regular revolutionary now!")) +/// Checks if the revolution succeeded, and lets them know. +/datum/antagonist/rev/proc/announce_victorious() + . = rev_team.check_rev_victory() + + if (!.) + return + + to_chat(owner, "[victory_message]") + var/policy = get_policy(ROLE_REV_SUCCESSFUL) + if (policy) + to_chat(owner, policy) + /datum/antagonist/rev/farewell() + if (announce_victorious()) + return + if(ishuman(owner.current) || ismonkey(owner.current)) owner.current.visible_message("[span_deconversion_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!")]", null, null, null, owner.current) to_chat(owner, span_userdanger("You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...")) @@ -223,13 +243,13 @@ if(borged) message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]") owner.special_role = null - if(iscarbon(owner.current)) + if(iscarbon(owner.current) && deconverter != DECONVERTER_REVS_WIN) var/mob/living/carbon/C = owner.current C.Unconscious(100) owner.remove_antag_datum(type) /datum/antagonist/rev/head/remove_revolutionary(borged,deconverter) - if(borged || deconverter == "gamemode") + if(borged || deconverter == DECONVERTER_STATION_WIN || deconverter == DECONVERTER_REVS_WIN) . = ..() /datum/antagonist/rev/head/equip_rev() @@ -259,6 +279,22 @@ S.Insert(H, special = FALSE, drop_if_replaced = FALSE) to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.") +/// "Enemy of the Revolutionary", given to heads and security when the revolution wins +/datum/antagonist/revolution_enemy + name = "Enemy of the Revolution" + show_in_antagpanel = FALSE + +/datum/antagonist/revolution_enemy/on_gain() + owner.special_role = "revolution enemy" + + var/datum/objective/survive/survive = new /datum/objective/survive + survive.owner = owner + survive.explanation_text = "The station has been overrun by revolutionaries, stay alive until the end." + objectives += survive + + return ..() + + /datum/antagonist/rev/head/on_gain() . = ..() company = /datum/corporation/bolsynpowell @@ -327,6 +363,101 @@ ex_headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE) ex_revs = get_antag_minds(/datum/antagonist/rev, TRUE) +/// Checks if revs have won +/datum/team/revolution/proc/check_rev_victory() + for(var/datum/objective/mutiny/objective in objectives) + if(!(objective.check_completion())) + return FALSE + return TRUE + +/// Checks if heads have won +/datum/team/revolution/proc/check_heads_victory() + for(var/datum/mind/rev_mind in head_revolutionaries()) + var/turf/rev_turf = get_turf(rev_mind.current) + if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(rev_turf.z)) + if(ishuman(rev_mind.current)) + return FALSE + return TRUE + +/// Updates the state of the world depending on if revs won or loss. +/// Returns who won, at which case this method should no longer be called. +/// If revs_win_injection_amount is passed, then that amount of threat will be added if the revs win. +/datum/team/revolution/proc/process_victory(revs_win_injection_amount) + if (check_rev_victory()) + . = REVOLUTION_VICTORY + else if (check_heads_victory()) + . = STATION_VICTORY + else + return + + SSshuttle.clearHostileEnvironment(src) + save_members() + + // Remove everyone as a revolutionary + for (var/_rev_mind in members) + var/datum/mind/rev_mind = _rev_mind + if (rev_mind.has_antag_datum(/datum/antagonist/rev)) + var/datum/antagonist/rev/rev_antag = rev_mind.has_antag_datum(/datum/antagonist/rev) + rev_antag.remove_revolutionary(FALSE, . == STATION_VICTORY ? DECONVERTER_STATION_WIN : DECONVERTER_REVS_WIN) + LAZYADD(rev_mind.special_statuses, "Former [(rev_mind in ex_headrevs) ? "head revolutionary" : "revolutionary"]") + + if (. == STATION_VICTORY) + // If the revolution was quelled, make rev heads unable to be revived through pods + for (var/_rev_head_mind in ex_revs) + var/datum/mind/rev_head_mind = _rev_head_mind + var/mob/living/carbon/rev_head_body = rev_head_mind.current + if(istype(rev_head_body) && rev_head_body.stat == DEAD) + rev_head_body.makeUncloneable() + + priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \ + We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division") + else + for (var/_player in GLOB.player_list) + var/mob/player = _player + var/datum/mind/mind = player.mind + + if (isnull(mind)) + continue + + if (!(mind.assigned_role in GLOB.command_positions + GLOB.security_positions)) + continue + + var/mob/living/carbon/target_body = mind.current + + mind.add_antag_datum(/datum/antagonist/revolution_enemy) + + if (!istype(target_body)) + continue + + if (target_body.stat == DEAD) + target_body.makeUncloneable() + else + mind.announce_objectives() + + for (var/job_name in GLOB.command_positions + GLOB.security_positions) + var/datum/job/job = SSjob.GetJob(job_name) + job.allow_bureaucratic_error = FALSE + job.total_positions = 0 + + if (revs_win_injection_amount) + var/datum/game_mode/dynamic/dynamic = SSticker.mode + dynamic.create_threat(revs_win_injection_amount) + dynamic.threat_log += "[worldtime2text()]: Revolution victory. Added [revs_win_injection_amount] threat." + + priority_announce("A recent assessment of your station has marked your station as a severe risk area for high ranking Nanotrasen officials. \ + For the safety of our staff, we have blacklisted your station for new employment of security and command. \ + [pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division") + +/// Mutates the ticker to report that the revs have won +/datum/team/revolution/proc/round_result(finished) + if (finished == REVOLUTION_VICTORY) + SSticker.mode_result = "win - heads killed" + SSticker.news_report = REVS_WIN + else if (finished == STATION_VICTORY) + SSticker.mode_result = "loss - rev heads killed" + SSticker.news_report = REVS_LOSE + + /datum/team/revolution/proc/check_victory() for(var/datum/objective/O in objectives) if(!O.check_completion()) @@ -341,18 +472,6 @@ result += "
" - var/num_revs = 0 - var/num_survivors = 0 - for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) - if(survivor.ckey) - num_survivors++ - if(survivor.mind) - if(is_revolutionary(survivor)) - num_revs++ - if(num_survivors) - result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
" - - var/list/targets = list() var/list/datum/mind/headrevs var/list/datum/mind/revs @@ -365,6 +484,17 @@ revs = ex_revs else revs = get_antag_minds(/datum/antagonist/rev, TRUE) + + var/num_revs = 0 + var/num_survivors = 0 + for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) + if(survivor.ckey) + num_survivors += 1 + if ((survivor.mind in revs) || (survivor.mind in headrevs)) + num_revs += 1 + + if(num_survivors) + result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
" if(check_victory()) for(var/H in revs) @@ -376,13 +506,13 @@ if(headrevs.len) var/list/headrev_part = list() headrev_part += span_header("The head revolutionaries were:") - headrev_part += printplayerlist(headrevs,TRUE) + headrev_part += printplayerlist(headrevs, !check_rev_victory()) result += headrev_part.Join("
") if(revs.len) var/list/rev_part = list() rev_part += span_header("The revolutionaries were:") - rev_part += printplayerlist(revs,TRUE) + rev_part += printplayerlist(revs, !check_rev_victory()) result += rev_part.Join("
") var/list/heads = SSjob.get_all_heads() @@ -435,3 +565,6 @@ /datum/team/revolution/is_gamemode_hero() return SSticker.mode.name == "revolution" + +#undef DECONVERTER_STATION_WIN +#undef DECONVERTER_REVS_WIN \ No newline at end of file diff --git a/code/modules/events/bureaucratic_error.dm b/code/modules/events/bureaucratic_error.dm index 64919c6818b8..0f5c42391fb3 100644 --- a/code/modules/events/bureaucratic_error.dm +++ b/code/modules/events/bureaucratic_error.dm @@ -12,4 +12,20 @@ priority_announce("A recent bureaucratic error in the Organic Resources Department may result in personnel shortages in some departments and redundant staffing in others.", "Paperwork Mishap Alert") /datum/round_event/bureaucratic_error/start() - SSjob.set_overflow_role(pick(get_all_jobs())) + var/list/jobs = SSjob.occupations.Copy() + if(prob(33)) // Only allows latejoining as a single role. Add latejoin AI bluespace pods for fun later. + var/datum/job/overflow = pick_n_take(jobs) + overflow.spawn_positions = -1 + overflow.total_positions = -1 // Ensures infinite slots as this role. Assistant will still be open for those that cant play it. + for(var/job in jobs) + var/datum/job/current = job + if(!current.allow_bureaucratic_error) + continue + current.total_positions = 0 + else // Adds/removes a random amount of job slots from all jobs. + for(var/job in jobs) + var/datum/job/current = job + if(!current.allow_bureaucratic_error) + continue + var/ran = rand(-2,4) + current.total_positions = max(current.total_positions + ran, 0) diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index c85904d4a217..7484d34cd1ac 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -70,6 +70,9 @@ var/list/changed_maps = list() // Maps on which the job is changed. Should use the same name as the mapping config + /// Should this job be allowed to be picked for the bureaucratic error event? + var/allow_bureaucratic_error = TRUE + /* If you want to change a job on a specific map with this system, you will want to go onto that job datum and add said map's name to the changed_maps list, like so: diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm index fe094589de30..3cdc17b738db 100644 --- a/code/modules/jobs/job_types/ai.dm +++ b/code/modules/jobs/job_types/ai.dm @@ -12,6 +12,7 @@ minimal_player_age = 30 exp_requirements = 180 exp_type = EXP_TYPE_CREW + allow_bureaucratic_error = FALSE exp_type_department = EXP_TYPE_SILICON display_order = JOB_DISPLAY_ORDER_AI var/do_special_check = TRUE diff --git a/strings/anti_union_propaganda.txt b/strings/anti_union_propaganda.txt new file mode 100644 index 000000000000..e1e6f68721a1 --- /dev/null +++ b/strings/anti_union_propaganda.txt @@ -0,0 +1,4 @@ +Remember, union dues cost around 70,000 credits a year. A new video game system with the latest hits sounds like fun. Put your money towards that instead of paying dues to the union. +Remember, tickets & food to the Toolbox Tournament aren't cheap. That money in union dues you'd be paying every year could sure go a long way. +Remember, nothing's more enjoyable than a night out watching a thunderdome match with your buddies. All those union dues you pay every year could buy a few rounds. +Nanotrasen's open door policy is designed to help you feel comfortable taking up issues to your assigned head of staff. It's hard for us to maintain this when they're dead. \ No newline at end of file From 42f71b8d8217a4050b27af40bbb6489491791d30 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 14:57:02 +0300 Subject: [PATCH 13/86] Update antagonists.dm --- code/__DEFINES/antagonists.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 3e9067499976..3bb45151bb3b 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -123,6 +123,3 @@ #define IS_BLOODSUCKER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/bloodsucker)) #define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal)) #define IS_MONSTERHUNTER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/monsterhunter)) - -/// How much does it cost to reroll strains? -#define BLOB_REROLL_COST 40 \ No newline at end of file From 55a1411206fcf4234e4da47a3aa844c743f2448d Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:00:38 +0300 Subject: [PATCH 14/86] Update blob_overmind.dm --- code/_onclick/hud/blob_overmind.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index bcb7856be825..e028a89b4772 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -93,17 +93,17 @@ /obj/screen/blob/ReadaptStrain icon_state = "ui_chemswap" - name = "Readapt Strain" + name = "Readapt Strain (40)" desc = "Allows you to choose a new strain from 4 random choices for 40 resources." /obj/screen/blob/ReadaptStrain/MouseEntered(location,control,params) if(hud && hud.mymob && isovermind(hud.mymob)) var/mob/camera/blob/B = hud.mymob if(B.free_strain_rerolls) - name = "[initial(name)] (FREE)" + name = "Readapt Strain (FREE)" desc = "Randomly rerolls your strain for free." else - name = "[initial(name)] ([BLOB_REROLL_COST])" + name = initial(name) desc = initial(desc) ..() @@ -174,4 +174,4 @@ using = new /obj/screen/blob/RelocateCore() using.screen_loc = ui_storage2 - static_inventory += using \ No newline at end of file + static_inventory += using From dd6e91b03bdb001e35a2ee0b2be2fda6923a9136 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:00:58 +0300 Subject: [PATCH 15/86] Update radial.dm --- code/_onclick/hud/radial.dm | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 926f117858bd..85e3914b8513 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -211,20 +211,16 @@ GLOBAL_LIST_EMPTY(radial_menus) var/atom/movable/AM = choices_values[choice_id] //Movables only E.name = AM.name - E.choice = choice_id - E.maptext = null - E.next_page = FALSE - if(choices_icons[choice_id]) E.add_overlay(choices_icons[choice_id]) - if (choice_datums[choice_id]) - var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id] - if (choice_datum.info) - var/obj/effect/abstract/info/info_button = new(E, choice_datum.info) - info_button.layer = ABOVE_HUD_LAYER - E.vis_contents += info_button + var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id] + if(choice_datum && istext(choice_datum.info)) + E.desc = choice_datum.info + E.choice = choice_id + E.maptext = null + E.next_page = FALSE /datum/radial_menu/New() close_button = new From 0ac0cb4d0cd4ff8395aab39dff0341180b34bdbf Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:01:11 +0300 Subject: [PATCH 16/86] Delete info.dm --- code/game/objects/effects/info.dm | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 code/game/objects/effects/info.dm diff --git a/code/game/objects/effects/info.dm b/code/game/objects/effects/info.dm deleted file mode 100644 index 0c9e3abf252c..000000000000 --- a/code/game/objects/effects/info.dm +++ /dev/null @@ -1,26 +0,0 @@ -/// An info button that, when clicked, puts some text in the user's chat -/obj/effect/abstract/info - name = "info" - icon = 'icons/effects/effects.dmi' - icon_state = "info" - - /// What should the info button display when clicked? - var/info_text - -/obj/effect/abstract/info/Initialize(mapload, info_text) - . = ..() - - if (!isnull(info_text)) - src.info_text = info_text - -/obj/effect/abstract/info/Click() - . = ..() - to_chat(usr, info_text) - -/obj/effect/abstract/info/MouseEntered() - . = ..() - icon_state = "info_hovered" - -/obj/effect/abstract/info/MouseExited() - . = ..() - icon_state = initial(icon_state) \ No newline at end of file From d4bdf34f3c15c529bcb70e8f9581db2387c30d4e Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:01:52 +0300 Subject: [PATCH 17/86] Update overmind.dm --- code/modules/antagonists/blob/overmind.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index 5b1639414f1e..2efd527ae5e0 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -44,8 +44,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) var/has_announced = FALSE var/basemodifier = 1 - /// The list of strains the blob can reroll for. - var/list/strain_choices /mob/camera/blob/Initialize(mapload, starting_points = 60, pointmodifier = 1) validate_location() From 5fc36bff4ecfc074ba097c0f5944aee39fb6d45c Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:02:13 +0300 Subject: [PATCH 18/86] Update overmind.dm --- code/modules/antagonists/blob/overmind.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index 2efd527ae5e0..9cc0c8df26a9 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -44,7 +44,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) var/has_announced = FALSE var/basemodifier = 1 - /mob/camera/blob/Initialize(mapload, starting_points = 60, pointmodifier = 1) validate_location() blob_points = starting_points @@ -187,7 +186,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) BM.overmind = null BM.update_icons() GLOB.overminds -= src - QDEL_LIST_ASSOC_VAL(strain_choices) SSshuttle.clearHostileEnvironment(src) STOP_PROCESSING(SSobj, src) From a2838367dcea232fc8843dc87b87ac6f1f591636 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:03:44 +0300 Subject: [PATCH 19/86] Update powers.dm --- code/modules/antagonists/blob/powers.dm | 70 +++++++------------------ 1 file changed, 18 insertions(+), 52 deletions(-) diff --git a/code/modules/antagonists/blob/powers.dm b/code/modules/antagonists/blob/powers.dm index 1131e4017bf2..5a8110bfc7ca 100644 --- a/code/modules/antagonists/blob/powers.dm +++ b/code/modules/antagonists/blob/powers.dm @@ -1,6 +1,3 @@ -#define BLOB_REROLL_CHOICES 6 -#define BLOB_REROLL_RADIUS 60 - /mob/camera/blob/proc/can_buy(cost = 15) if(blob_points < cost) to_chat(src, span_warning("You cannot afford this, you need at least [cost] resources!")) @@ -343,53 +340,25 @@ set category = "Blob" set name = "Reactive Strain Adaptation (40)" set desc = "Replaces your strain with a random, different one." - if (!free_strain_rerolls && blob_points < BLOB_REROLL_COST) - to_chat(src, "You need at least [BLOB_REROLL_COST] resources to reroll your strain again!") - return - - open_reroll_menu() - -/// Open the menu to reroll strains -/mob/camera/blob/proc/open_reroll_menu() - if (!strain_choices) - strain_choices = list() - - var/list/new_strains = GLOB.valid_blobstrains.Copy() - for (var/_ in 1 to BLOB_REROLL_CHOICES) - var/datum/blobstrain/strain = pick_n_take(new_strains) - - var/image/strain_icon = image('icons/mob/blob.dmi', "blob_core") - strain_icon.color = initial(strain.color) - - var/info_text = "[initial(strain.name)]" - info_text += "
[initial(strain.analyzerdescdamage)]" - if (!isnull(initial(strain.analyzerdesceffect))) - info_text += "
[initial(strain.analyzerdesceffect)]" - - var/datum/radial_menu_choice/choice = new - choice.image = strain_icon - choice.info = info_text - - strain_choices[initial(strain.name)] = choice + if(!rerolling && (free_strain_rerolls || can_buy(40))) + rerolling = TRUE + reroll_strain() + rerolling = FALSE + if(free_strain_rerolls) + free_strain_rerolls-- + last_reroll_time = world.time + +/mob/camera/blob/proc/reroll_strain() + var/list/choices = list() + while (length(choices) < 4) + var/datum/blobstrain/bs = pick((GLOB.valid_blobstrains)) + choices[initial(bs.name)] = bs + + var/choice = input(usr, "Please choose a new strain","Strain") as anything in choices + if (choice && choices[choice] && !QDELETED(src)) + var/datum/blobstrain/bs = choices[choice] + set_strain(bs) - var/strain_result = show_radial_menu(src, src, strain_choices, radius = BLOB_REROLL_RADIUS, tooltips = TRUE) - if (isnull(strain_result)) - return - - if (!free_strain_rerolls && !can_buy(BLOB_REROLL_COST)) - return - - for (var/_other_strain in GLOB.valid_blobstrains) - var/datum/blobstrain/other_strain = _other_strain - if (initial(other_strain.name) == strain_result) - set_strain(other_strain) - - if (free_strain_rerolls) - free_strain_rerolls -= 1 - - last_reroll_time = world.time - - return /mob/camera/blob/verb/blob_help() set category = "Blob" @@ -414,6 +383,3 @@ if(!placed && autoplace_max_time <= world.time) to_chat(src, span_big("You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)].")) to_chat(src, span_big("You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen.")) - -#undef BLOB_REROLL_CHOICES -#undef BLOB_REROLL_RADIUS \ No newline at end of file From 172019b8de767740e8aa751c7279a575ff66f1de Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:24:53 +0300 Subject: [PATCH 20/86] Update role_preferences.dm --- code/__DEFINES/role_preferences.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 388bba808595..07bb830ece9a 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -16,7 +16,6 @@ #define ROLE_MALF "Malf AI" #define ROLE_REV "Revolutionary" #define ROLE_REV_HEAD "Head Revolutionary" -#define ROLE_REV_SUCCESSFUL "Victorious Revolutionary" #define ROLE_ALIEN "Xenomorph" #define ROLE_PAI "pAI" #define ROLE_CULTIST "Cultist" From e329b12815170e18d8bd0067a3f208b0b741173e Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:25:31 +0300 Subject: [PATCH 21/86] Update job.dm --- code/controllers/subsystem/job.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index fb921b14c20a..d0de6312dba6 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -30,13 +30,11 @@ SUBSYSTEM_DEF(job) var/datum/job/new_overflow = GetJob(new_overflow_role) var/cap = CONFIG_GET(number/overflow_cap) - new_overflow.allow_bureaucratic_error = FALSE new_overflow.spawn_positions = cap new_overflow.total_positions = cap if(new_overflow_role != overflow_role) var/datum/job/old_overflow = GetJob(overflow_role) - old_overflow.allow_bureaucratic_error = initial(old_overflow.allow_bureaucratic_error) old_overflow.spawn_positions = initial(old_overflow.spawn_positions) old_overflow.total_positions = initial(old_overflow.total_positions) overflow_role = new_overflow_role From 5515ca0ba09d9e78fe0d7f58458bccf196030341 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:26:35 +0300 Subject: [PATCH 22/86] Update mind.dm --- code/datums/mind.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 079ad25db409..43f063a24237 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -88,8 +88,6 @@ var/afk_verb_used = FALSE /// The timer for the afk verb var/afk_verb_timer - /// A lazy list of statuses to add next to this mind in the traitor panel - var/list/special_statuses /datum/mind/New(key) src.key = key From f01a65e4acceca5ab1026ea88789c27a09c06c53 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:26:59 +0300 Subject: [PATCH 23/86] Update dynamic_rulesets.dm --- code/game/gamemodes/dynamic/dynamic_rulesets.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 600e34fbb43a..efbab7a576eb 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -183,6 +183,11 @@ /// Only called if ruleset is flagged as HIGH_IMPACT_RULESET /datum/dynamic_ruleset/proc/round_result() +/// Checks if round is finished, return true to end the round. +/// Only called if ruleset is flagged as HIGH_IMPACT_RULESET +/datum/dynamic_ruleset/proc/check_finished() + return FALSE + ////////////////////////////////////////////// // // // ROUNDSTART RULESETS // From 986a19999755448af2eafbcbca9a813c6f0a6f35 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:27:36 +0300 Subject: [PATCH 24/86] Update dynamic_rulesets_latejoin.dm --- .../dynamic/dynamic_rulesets_latejoin.dm | 58 +++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 721a7f928d78..2cf8d95e5442 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -93,8 +93,6 @@ blocking_rules = list(/datum/dynamic_ruleset/roundstart/revs) var/required_heads_of_staff = 3 var/finished = FALSE - /// How much threat should be injected when the revolution wins? - var/revs_win_threat_injection = 20 var/datum/team/revolution/revolution /datum/dynamic_ruleset/latejoin/provocateur/ready(forced=FALSE) @@ -121,7 +119,7 @@ new_head = M.mind.add_antag_datum(new_head, revolution) revolution.update_objectives() revolution.update_heads() - SSshuttle.registerHostileEnvironment(revolution) + SSshuttle.registerHostileEnvironment(src) return TRUE else log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.") @@ -129,12 +127,27 @@ return FALSE /datum/dynamic_ruleset/latejoin/provocateur/rule_process() - var/winner = revolution.process_victory(revs_win_threat_injection) - if (isnull(winner)) - return - - finished = winner - return RULESET_STOP_PROCESSING + if(check_rev_victory()) + finished = REVOLUTION_VICTORY + return RULESET_STOP_PROCESSING + else if (check_heads_victory()) + finished = STATION_VICTORY + SSshuttle.clearHostileEnvironment(src) + revolution.save_members() + for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions. + if(M.has_antag_datum(/datum/antagonist/rev/head)) + var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head) + R.remove_revolutionary(FALSE, "gamemode") + if(M.current) + var/mob/living/carbon/C = M.current + if(istype(C) && C.stat == DEAD) + C.makeUncloneable() + if(M.has_antag_datum(/datum/antagonist/rev)) + var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev) + R.remove_revolutionary(FALSE, "gamemode") + priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \ + We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division") + return RULESET_STOP_PROCESSING @@ -145,8 +158,33 @@ return TRUE return FALSE +/datum/dynamic_ruleset/latejoin/provocateur/check_finished() + if(finished == REVOLUTION_VICTORY) + return TRUE + else + return ..() + +/datum/dynamic_ruleset/latejoin/provocateur/proc/check_rev_victory() + for(var/datum/objective/mutiny/objective in revolution.objectives) + if(!(objective.check_completion())) + return FALSE + return TRUE + +/datum/dynamic_ruleset/latejoin/provocateur/proc/check_heads_victory() + for(var/datum/mind/rev_mind in revolution.head_revolutionaries()) + var/turf/T = get_turf(rev_mind.current) + if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z)) + if(ishuman(rev_mind.current) || ismonkey(rev_mind.current)) + return FALSE + return TRUE + /datum/dynamic_ruleset/latejoin/provocateur/round_result() - revolution.round_result(finished) + if(finished == REVOLUTION_VICTORY) + SSticker.mode_result = "win - heads killed" + SSticker.news_report = REVS_WIN + else if(finished == STATION_VICTORY) + SSticker.mode_result = "loss - rev heads killed" + SSticker.news_report = REVS_LOSE ////////////////////////////////////////////// // // From a4bd274fb0c5fa4b8dc6bb56b14cbae2efa36eac Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:28:15 +0300 Subject: [PATCH 25/86] Update dynamic_rulesets_roundstart.dm --- .../dynamic/dynamic_rulesets_roundstart.dm | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index a472e53b9cf3..6f75591d5968 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -410,7 +410,7 @@ if(revolution.members.len) revolution.update_objectives() revolution.update_heads() - SSshuttle.registerHostileEnvironment(revolution) + SSshuttle.registerHostileEnvironment(src) return TRUE log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.") return FALSE @@ -420,12 +420,30 @@ ..() /datum/dynamic_ruleset/roundstart/revs/rule_process() - var/winner = revolution.process_victory(revs_win_threat_injection) - if (isnull(winner)) + if(!revolution) + log_game("DYNAMIC: Something went horrifically wrong with [name] - and the antag datum could not be created. Notify coders.") return - - finished = winner - return RULESET_STOP_PROCESSING + if(check_rev_victory()) + finished = REVOLUTION_VICTORY + return RULESET_STOP_PROCESSING + else if (check_heads_victory()) + finished = STATION_VICTORY + SSshuttle.clearHostileEnvironment(src) + revolution.save_members() + for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions. + if(M.has_antag_datum(/datum/antagonist/rev/head)) + var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head) + R.remove_revolutionary(FALSE, "gamemode") + if(M.current) + var/mob/living/carbon/C = M.current + if(istype(C) && C.stat == DEAD) + C.makeUncloneable() + if(M.has_antag_datum(/datum/antagonist/rev)) + var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev) + R.remove_revolutionary(FALSE, "gamemode") + priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \ + We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division") + return RULESET_STOP_PROCESSING /// Checks for revhead loss conditions and other antag datums. /datum/dynamic_ruleset/roundstart/revs/proc/check_eligible(var/datum/mind/M) @@ -440,8 +458,27 @@ else return ..() +/datum/dynamic_ruleset/roundstart/revs/proc/check_rev_victory() + for(var/datum/objective/mutiny/objective in revolution.objectives) + if(!(objective.check_completion())) + return FALSE + return TRUE + +/datum/dynamic_ruleset/roundstart/revs/proc/check_heads_victory() + for(var/datum/mind/rev_mind in revolution.head_revolutionaries()) + var/turf/T = get_turf(rev_mind.current) + if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z)) + if(ishuman(rev_mind.current) || ismonkey(rev_mind.current)) + return FALSE + return TRUE + /datum/dynamic_ruleset/roundstart/revs/round_result() - revolution.round_result(finished) + if(finished == REVOLUTION_VICTORY) + SSticker.mode_result = "win - heads killed" + SSticker.news_report = REVS_WIN + else if(finished == STATION_VICTORY) + SSticker.mode_result = "loss - rev heads killed" + SSticker.news_report = REVS_LOSE // Admin only rulesets. The threat requirement is 101 so it is not possible to roll them. From 32c0f01474214cd9849618d939720b057d8852d2 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:30:15 +0300 Subject: [PATCH 26/86] Update antag_panel.dm --- code/modules/admin/antag_panel.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm index 12254c2e155d..a41a7ff229b1 100644 --- a/code/modules/admin/antag_panel.dm +++ b/code/modules/admin/antag_panel.dm @@ -78,7 +78,7 @@ GLOBAL_VAR(antag_prototypes) return common_commands /datum/mind/proc/get_special_statuses() - var/list/result = LAZYCOPY(special_statuses) + var/list/result = list() if(!current) result += span_bad("No body!") if(current && HAS_TRAIT(current, TRAIT_MINDSHIELD)) From 3ade95a1ff2015eb2e18346f158ecb7bd215eb4d Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:31:09 +0300 Subject: [PATCH 27/86] Update revolution.dm --- .../antagonists/revolution/revolution.dm | 165 ++---------------- 1 file changed, 16 insertions(+), 149 deletions(-) diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index 7f4da5843334..ebb9aa0d6066 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -1,5 +1,3 @@ -#define DECONVERTER_STATION_WIN "gamemode_station_win" -#define DECONVERTER_REVS_WIN "gamemode_revs_win" //How often to check for promotion possibility #define HEAD_UPDATE_PERIOD 300 @@ -12,9 +10,6 @@ var/hud_type = "rev" var/datum/team/revolution/rev_team - /// What message should the player receive when they are being demoted, and the revolution has won? - var/victory_message = "The revolution has overpowered the command staff! Viva la revolution! Execute any head of staff and security should you find them alive." - /datum/antagonist/rev/can_be_owned(datum/mind/new_owner) . = ..() if(.) @@ -214,22 +209,7 @@ new_rev.silent = FALSE to_chat(old_owner, span_userdanger("Revolution has been disappointed of your leader traits! You are a regular revolutionary now!")) -/// Checks if the revolution succeeded, and lets them know. -/datum/antagonist/rev/proc/announce_victorious() - . = rev_team.check_rev_victory() - - if (!.) - return - - to_chat(owner, "[victory_message]") - var/policy = get_policy(ROLE_REV_SUCCESSFUL) - if (policy) - to_chat(owner, policy) - /datum/antagonist/rev/farewell() - if (announce_victorious()) - return - if(ishuman(owner.current) || ismonkey(owner.current)) owner.current.visible_message("[span_deconversion_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!")]", null, null, null, owner.current) to_chat(owner, span_userdanger("You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...")) @@ -243,13 +223,13 @@ if(borged) message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]") owner.special_role = null - if(iscarbon(owner.current) && deconverter != DECONVERTER_REVS_WIN) + if(iscarbon(owner.current)) var/mob/living/carbon/C = owner.current C.Unconscious(100) owner.remove_antag_datum(type) /datum/antagonist/rev/head/remove_revolutionary(borged,deconverter) - if(borged || deconverter == DECONVERTER_STATION_WIN || deconverter == DECONVERTER_REVS_WIN) + if(borged || deconverter == "gamemode") . = ..() /datum/antagonist/rev/head/equip_rev() @@ -279,22 +259,6 @@ S.Insert(H, special = FALSE, drop_if_replaced = FALSE) to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.") -/// "Enemy of the Revolutionary", given to heads and security when the revolution wins -/datum/antagonist/revolution_enemy - name = "Enemy of the Revolution" - show_in_antagpanel = FALSE - -/datum/antagonist/revolution_enemy/on_gain() - owner.special_role = "revolution enemy" - - var/datum/objective/survive/survive = new /datum/objective/survive - survive.owner = owner - survive.explanation_text = "The station has been overrun by revolutionaries, stay alive until the end." - objectives += survive - - return ..() - - /datum/antagonist/rev/head/on_gain() . = ..() company = /datum/corporation/bolsynpowell @@ -363,101 +327,6 @@ ex_headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE) ex_revs = get_antag_minds(/datum/antagonist/rev, TRUE) -/// Checks if revs have won -/datum/team/revolution/proc/check_rev_victory() - for(var/datum/objective/mutiny/objective in objectives) - if(!(objective.check_completion())) - return FALSE - return TRUE - -/// Checks if heads have won -/datum/team/revolution/proc/check_heads_victory() - for(var/datum/mind/rev_mind in head_revolutionaries()) - var/turf/rev_turf = get_turf(rev_mind.current) - if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(rev_turf.z)) - if(ishuman(rev_mind.current)) - return FALSE - return TRUE - -/// Updates the state of the world depending on if revs won or loss. -/// Returns who won, at which case this method should no longer be called. -/// If revs_win_injection_amount is passed, then that amount of threat will be added if the revs win. -/datum/team/revolution/proc/process_victory(revs_win_injection_amount) - if (check_rev_victory()) - . = REVOLUTION_VICTORY - else if (check_heads_victory()) - . = STATION_VICTORY - else - return - - SSshuttle.clearHostileEnvironment(src) - save_members() - - // Remove everyone as a revolutionary - for (var/_rev_mind in members) - var/datum/mind/rev_mind = _rev_mind - if (rev_mind.has_antag_datum(/datum/antagonist/rev)) - var/datum/antagonist/rev/rev_antag = rev_mind.has_antag_datum(/datum/antagonist/rev) - rev_antag.remove_revolutionary(FALSE, . == STATION_VICTORY ? DECONVERTER_STATION_WIN : DECONVERTER_REVS_WIN) - LAZYADD(rev_mind.special_statuses, "Former [(rev_mind in ex_headrevs) ? "head revolutionary" : "revolutionary"]") - - if (. == STATION_VICTORY) - // If the revolution was quelled, make rev heads unable to be revived through pods - for (var/_rev_head_mind in ex_revs) - var/datum/mind/rev_head_mind = _rev_head_mind - var/mob/living/carbon/rev_head_body = rev_head_mind.current - if(istype(rev_head_body) && rev_head_body.stat == DEAD) - rev_head_body.makeUncloneable() - - priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \ - We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division") - else - for (var/_player in GLOB.player_list) - var/mob/player = _player - var/datum/mind/mind = player.mind - - if (isnull(mind)) - continue - - if (!(mind.assigned_role in GLOB.command_positions + GLOB.security_positions)) - continue - - var/mob/living/carbon/target_body = mind.current - - mind.add_antag_datum(/datum/antagonist/revolution_enemy) - - if (!istype(target_body)) - continue - - if (target_body.stat == DEAD) - target_body.makeUncloneable() - else - mind.announce_objectives() - - for (var/job_name in GLOB.command_positions + GLOB.security_positions) - var/datum/job/job = SSjob.GetJob(job_name) - job.allow_bureaucratic_error = FALSE - job.total_positions = 0 - - if (revs_win_injection_amount) - var/datum/game_mode/dynamic/dynamic = SSticker.mode - dynamic.create_threat(revs_win_injection_amount) - dynamic.threat_log += "[worldtime2text()]: Revolution victory. Added [revs_win_injection_amount] threat." - - priority_announce("A recent assessment of your station has marked your station as a severe risk area for high ranking Nanotrasen officials. \ - For the safety of our staff, we have blacklisted your station for new employment of security and command. \ - [pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division") - -/// Mutates the ticker to report that the revs have won -/datum/team/revolution/proc/round_result(finished) - if (finished == REVOLUTION_VICTORY) - SSticker.mode_result = "win - heads killed" - SSticker.news_report = REVS_WIN - else if (finished == STATION_VICTORY) - SSticker.mode_result = "loss - rev heads killed" - SSticker.news_report = REVS_LOSE - - /datum/team/revolution/proc/check_victory() for(var/datum/objective/O in objectives) if(!O.check_completion()) @@ -472,6 +341,18 @@ result += "
" + var/num_revs = 0 + var/num_survivors = 0 + for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) + if(survivor.ckey) + num_survivors++ + if(survivor.mind) + if(is_revolutionary(survivor)) + num_revs++ + if(num_survivors) + result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
" + + var/list/targets = list() var/list/datum/mind/headrevs var/list/datum/mind/revs @@ -484,17 +365,6 @@ revs = ex_revs else revs = get_antag_minds(/datum/antagonist/rev, TRUE) - - var/num_revs = 0 - var/num_survivors = 0 - for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) - if(survivor.ckey) - num_survivors += 1 - if ((survivor.mind in revs) || (survivor.mind in headrevs)) - num_revs += 1 - - if(num_survivors) - result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
" if(check_victory()) for(var/H in revs) @@ -506,13 +376,13 @@ if(headrevs.len) var/list/headrev_part = list() headrev_part += span_header("The head revolutionaries were:") - headrev_part += printplayerlist(headrevs, !check_rev_victory()) + headrev_part += printplayerlist(headrevs,TRUE) result += headrev_part.Join("
") if(revs.len) var/list/rev_part = list() rev_part += span_header("The revolutionaries were:") - rev_part += printplayerlist(revs, !check_rev_victory()) + rev_part += printplayerlist(revs,TRUE) result += rev_part.Join("
") var/list/heads = SSjob.get_all_heads() @@ -565,6 +435,3 @@ /datum/team/revolution/is_gamemode_hero() return SSticker.mode.name == "revolution" - -#undef DECONVERTER_STATION_WIN -#undef DECONVERTER_REVS_WIN \ No newline at end of file From 9152bcdebeb69f2d7db2ff6722adb240be35cd98 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:31:31 +0300 Subject: [PATCH 28/86] Update bureaucratic_error.dm --- code/modules/events/bureaucratic_error.dm | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/code/modules/events/bureaucratic_error.dm b/code/modules/events/bureaucratic_error.dm index 0f5c42391fb3..64919c6818b8 100644 --- a/code/modules/events/bureaucratic_error.dm +++ b/code/modules/events/bureaucratic_error.dm @@ -12,20 +12,4 @@ priority_announce("A recent bureaucratic error in the Organic Resources Department may result in personnel shortages in some departments and redundant staffing in others.", "Paperwork Mishap Alert") /datum/round_event/bureaucratic_error/start() - var/list/jobs = SSjob.occupations.Copy() - if(prob(33)) // Only allows latejoining as a single role. Add latejoin AI bluespace pods for fun later. - var/datum/job/overflow = pick_n_take(jobs) - overflow.spawn_positions = -1 - overflow.total_positions = -1 // Ensures infinite slots as this role. Assistant will still be open for those that cant play it. - for(var/job in jobs) - var/datum/job/current = job - if(!current.allow_bureaucratic_error) - continue - current.total_positions = 0 - else // Adds/removes a random amount of job slots from all jobs. - for(var/job in jobs) - var/datum/job/current = job - if(!current.allow_bureaucratic_error) - continue - var/ran = rand(-2,4) - current.total_positions = max(current.total_positions + ran, 0) + SSjob.set_overflow_role(pick(get_all_jobs())) From 27d126770742f73d12077eb550ebb74328ae2755 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:31:54 +0300 Subject: [PATCH 29/86] Update _job.dm --- code/modules/jobs/job_types/_job.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 7484d34cd1ac..c701ca035c63 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -70,8 +70,6 @@ var/list/changed_maps = list() // Maps on which the job is changed. Should use the same name as the mapping config - /// Should this job be allowed to be picked for the bureaucratic error event? - var/allow_bureaucratic_error = TRUE /* If you want to change a job on a specific map with this system, you will want to go onto that job datum From 05a1a1629f5a136c3aef6d2f7a5ea41fb5d7308a Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:32:15 +0300 Subject: [PATCH 30/86] Update ai.dm --- code/modules/jobs/job_types/ai.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm index 3cdc17b738db..fe094589de30 100644 --- a/code/modules/jobs/job_types/ai.dm +++ b/code/modules/jobs/job_types/ai.dm @@ -12,7 +12,6 @@ minimal_player_age = 30 exp_requirements = 180 exp_type = EXP_TYPE_CREW - allow_bureaucratic_error = FALSE exp_type_department = EXP_TYPE_SILICON display_order = JOB_DISPLAY_ORDER_AI var/do_special_check = TRUE From dafd04d0ff063d765c66cfaa273ee6bb7ba5e6df Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:32:24 +0300 Subject: [PATCH 31/86] Delete anti_union_propaganda.txt --- strings/anti_union_propaganda.txt | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 strings/anti_union_propaganda.txt diff --git a/strings/anti_union_propaganda.txt b/strings/anti_union_propaganda.txt deleted file mode 100644 index e1e6f68721a1..000000000000 --- a/strings/anti_union_propaganda.txt +++ /dev/null @@ -1,4 +0,0 @@ -Remember, union dues cost around 70,000 credits a year. A new video game system with the latest hits sounds like fun. Put your money towards that instead of paying dues to the union. -Remember, tickets & food to the Toolbox Tournament aren't cheap. That money in union dues you'd be paying every year could sure go a long way. -Remember, nothing's more enjoyable than a night out watching a thunderdome match with your buddies. All those union dues you pay every year could buy a few rounds. -Nanotrasen's open door policy is designed to help you feel comfortable taking up issues to your assigned head of staff. It's hard for us to maintain this when they're dead. \ No newline at end of file From e8d7e8e8d9ea77db4037505e771e42525d472289 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:35:55 +0300 Subject: [PATCH 32/86] Update antagonists.dm --- code/__DEFINES/antagonists.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 3bb45151bb3b..ccdc70876238 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -123,3 +123,4 @@ #define IS_BLOODSUCKER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/bloodsucker)) #define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal)) #define IS_MONSTERHUNTER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/monsterhunter)) + From 6cb432a30503e4bc21c81813a9186022542db497 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:36:26 +0300 Subject: [PATCH 33/86] Update blob_overmind.dm --- code/_onclick/hud/blob_overmind.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index e028a89b4772..e2c1c0a5712d 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -175,3 +175,4 @@ using = new /obj/screen/blob/RelocateCore() using.screen_loc = ui_storage2 static_inventory += using + From 4adce07dd8b13ea9354d87ef1a588d4a540274d9 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:36:44 +0300 Subject: [PATCH 34/86] Update generic_negative_events.dm --- code/datums/mood_events/generic_negative_events.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index e5fc41d754e2..9edfcb07ce9d 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -221,3 +221,4 @@ /datum/mood_event/surgery description = "HE'S CUTTING ME OPEN!!\n" mood_change = -8 + From 02370485ee0bab17c9f905daf9e8e6a11dd85b04 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:36:57 +0300 Subject: [PATCH 35/86] Update _blobstrain.dm --- code/modules/antagonists/blob/blobstrains/_blobstrain.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm index a9fa8350e79b..ad439d962de2 100644 --- a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm +++ b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm @@ -8,7 +8,7 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/ var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects var/effectdesc = null //any long, blob-tile specific effects var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp." - var/analyzerdesceffect + var/analyzerdesceffect = "N/A" var/blobbernaut_message = "slams" //blobbernaut attack verb var/message = "The blob strikes you" //message sent to any mob hit by the blob var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt From fb0ad0605d4d3ac02afc0b9f01a79508b66d0a50 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:37:15 +0300 Subject: [PATCH 36/86] Update _blob.dm --- code/modules/antagonists/blob/structures/_blob.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm index 68fdf4075658..a65b79e33b41 100644 --- a/code/modules/antagonists/blob/structures/_blob.dm +++ b/code/modules/antagonists/blob/structures/_blob.dm @@ -244,7 +244,7 @@ if(overmind) . += list("Material: [overmind.blobstrain.name][span_notice(".")]", "Material Effects: [span_notice("[overmind.blobstrain.analyzerdescdamage]")]", - "Material Properties: [overmind.blobstrain.analyzerdesceffect || "N/A"]") + "Material Properties: [span_notice("[overmind.blobstrain.analyzerdesceffect]")]") else . += "No Material Detected!" From c3269d84c5c6a498c82148290ed0163b8af924bc Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 29 Jun 2022 15:37:32 +0300 Subject: [PATCH 37/86] Update _job.dm --- code/modules/jobs/job_types/_job.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index c701ca035c63..c85904d4a217 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -70,7 +70,6 @@ var/list/changed_maps = list() // Maps on which the job is changed. Should use the same name as the mapping config - /* If you want to change a job on a specific map with this system, you will want to go onto that job datum and add said map's name to the changed_maps list, like so: From a384daa1d477a370df4151a8015c0a486b0af7f5 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Sat, 2 Jul 2022 14:19:12 +0300 Subject: [PATCH 38/86] amonus --- code/__DEFINES/antagonists.dm | 7 --- code/__DEFINES/role_preferences.dm | 1 + code/__DEFINES/status_effects.dm | 4 -- code/__DEFINES/traits.dm | 3 +- code/datums/mind.dm | 4 ++ .../mood_events/generic_positive_events.dm | 10 +++++ .../dynamic/dynamic_rulesets_roundstart.dm | 34 +++++++++++++++ code/game/gamemodes/hivemind/hivemind.dm | 43 ++++++++++++------- code/game/gamemodes/hivemind/objectives.dm | 14 +++++- 9 files changed, 91 insertions(+), 29 deletions(-) diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index ccdc70876238..341cf1c6a942 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -76,13 +76,6 @@ /// Prevents hijacking same way as non-antags #define HIJACK_PREVENT 2 -//Assimilation -#define TRACKER_DEFAULT_TIME 900 -#define TRACKER_MINDSHIELD_TIME 1200 -#define TRACKER_AWAKENED_TIME 3000 -#define TRACKER_BONUS_LARGE 300 -#define TRACKER_BONUS_SMALL 100 - //Syndicate Contracts #define CONTRACT_STATUS_INACTIVE 1 #define CONTRACT_STATUS_ACTIVE 2 diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 07bb830ece9a..cb975ac3f8f2 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -30,6 +30,7 @@ #define ROLE_BROTHER "Blood Brother" #define ROLE_BRAINWASHED "Brainwashed Victim" #define ROLE_HIVE "Hivemind Host" +#define ROLE_HIVE_VESSEL "Awakened Vessel" #define ROLE_OBSESSED "Obsessed" #define ROLE_SENTIENCE "Sentience Potion Spawn" #define ROLE_MIND_TRANSFER "Mind Transfer Potion" diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 4afbccca45e9..3dcd959bd438 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -137,10 +137,6 @@ #define STATUS_EFFECT_BUGGED /datum/status_effect/bugged //Lets other mobs listen in on what it hears -#define STATUS_EFFECT_HIVE_TRACKER /datum/status_effect/hive_track - -#define STATUS_EFFECT_HIVE_RADAR /datum/status_effect/agent_pinpointer/hivemind - #define STATUS_EFFECT_BOUNTY /datum/status_effect/bounty //rewards the person who added this to the target with refreshed spells and a fair heal #define STATUS_EFFECT_HELDUP /datum/status_effect/heldup // someone is currently pointing a gun at you diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index bcfdfb97bfc0..c28887f30f2a 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -220,6 +220,7 @@ #define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat #define TRAIT_MASQUERADE "masquerade" // Falsifies Health analyzer blood levels #define TRAIT_COLDBLOODED "coldblooded" // Your body is literal room temperature. Does not make you immune to the temp +#define TRAIT_HIVE_BURNT "hive-burnt" //non-mob traits /// Used for limb-based paralysis, where replacing the limb will fix it. @@ -321,7 +322,7 @@ #define LOCKED_HELMET_TRAIT "locked-helmet" #define NINJA_SUIT_TRAIT "ninja-suit" #define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant" -#define HIVEMIND_ONE_MIND_TRAIT "one_mind" +#define HIVEMIND_TRAIT "hivemind-trait" #define VR_ZONE_TRAIT "vr_zone_trait" #define GUARDIAN_TRAIT "guardian_trait" #define RANDOM_BLACKOUTS "random_blackouts" diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 43f063a24237..a162b28a9552 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -283,6 +283,10 @@ if(O) O.unlock_code = null +/datum/mind/proc/remove_from_hives() + SIGNAL_HANDLER + remove_hivemember(src) + /datum/mind/proc/remove_all_antag() //For the Lazy amongst us. remove_changeling() remove_traitor() diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 0fb6810f229d..98dfa995ad6b 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -114,6 +114,16 @@ mood_change = 10 hidden = TRUE +/datum/mood_event/hivehost + description = "Our psyche expands, our influence broadens.\n" + mood_change = 5 + hidden = TRUE + +/datum/mood_event/hiveawakened + description = "True purpose has been revealed to us, at last!.\n" + mood_change = 2 + hidden = TRUE + /datum/mood_event/family_heirloom description = "My family heirloom is safe with me.\n" mood_change = 1 diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 6f75591d5968..b4d71ab85c4d 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -1002,3 +1002,37 @@ if(!bloodsuckermind.make_bloodsucker(assigned_bloodsuckers)) assigned -= assigned_bloodsuckers return TRUE + +////////////////////////////////////////////// +// // +// ASSIMILATION // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/roundstart/hivemind + name = "Assimilation" + antag_flag = ROLE_HIVE + antag_datum = /datum/antagonist/hivemind + protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain") + restricted_roles = list("Cyborg","AI") + required_candidates = 3 + weight = 3 + cost = 30 + requirements = list(100,90,80,60,40,30,10,10,10,10) + flags = HIGH_IMPACT_RULESET + +/datum/dynamic_ruleset/roundstart/hivemind/pre_execute(population) + . = ..() + var/num_hosts = max( 3 , rand(0,1) + min(8, round(population / 8) ) ) + for (var/i = 1 to num_hosts) + var/mob/M = pick_n_take(candidates) + assigned += M.mind + M.mind.restricted_roles = restricted_roles + M.mind.special_role = ROLE_HIVE + return TRUE + +/datum/dynamic_ruleset/roundstart/hivemind/execute() + for(var/datum/mind/host in assigned) + var/datum/antagonist/hivemind/new_antag = new antag_datum() + host.add_antag_datum(new_antag) + return TRUE \ No newline at end of file diff --git a/code/game/gamemodes/hivemind/hivemind.dm b/code/game/gamemodes/hivemind/hivemind.dm index 28838d59675e..4a97379aca08 100644 --- a/code/game/gamemodes/hivemind/hivemind.dm +++ b/code/game/gamemodes/hivemind/hivemind.dm @@ -1,13 +1,15 @@ +GLOBAL_LIST_EMPTY(hivehosts) + /datum/game_mode/hivemind - name = "Assimilation" + name = "assimilation" config_tag = "hivemind" report_type = "hivemind" antag_flag = ROLE_HIVE false_report_weight = 5 protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Brig Physician") //Yogs: Added "Brig Physician restricted_jobs = list("Cyborg","AI") - required_players = 24 - required_enemies = 2 + required_players = 30 + required_enemies = 3 recommended_enemies = 3 reroll_friendly = 1 enemy_minimum_age = 0 @@ -24,15 +26,10 @@ return return M.mind.has_antag_datum(/datum/antagonist/hivemind) -/mob/living/proc/is_real_hivehost() //This proc ignores mind controlled vessels - for(var/datum/antagonist/hivemind/hive in GLOB.antagonists) +/mob/living/proc/is_real_hivehost() + for(var/datum/antagonist/hivemind/hive as() in GLOB.hivehosts) if(!hive.owner?.spell_list) continue - var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in hive.owner.spell_list - if((!the_spell || !the_spell.active ) && mind == hive.owner) - return TRUE - if(the_spell?.active && the_spell.original_body == src) - return TRUE return FALSE /mob/living/proc/get_real_hivehost() //Returns src unless it's under mind control, then it returns the original body @@ -41,9 +38,6 @@ return if(!is_hivehost(M) || is_real_hivehost(M)) return M - var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in M.mind.spell_list - if(the_spell?.active) - return the_spell.original_body return M /proc/is_hivemember(mob/living/L) @@ -52,7 +46,7 @@ var/datum/mind/M = L.mind if(!M) return FALSE - for(var/datum/antagonist/hivemind/H in GLOB.antagonists) + for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts) if(H.hivemembers.Find(M)) return TRUE return FALSE @@ -61,7 +55,7 @@ var/datum/mind/M = L?.mind if(!M) return - for(var/datum/antagonist/hivemind/H in GLOB.antagonists) + for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts) if(H.hivemembers.Find(M)) H.hivemembers -= M H.calc_size() @@ -77,7 +71,7 @@ if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" - var/num_hosts = max( 1 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra + var/num_hosts = max( 3 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra for(var/j = 0, j < num_hosts, j++) if (!antag_candidates.len) @@ -105,3 +99,20 @@ return "Reports of psychic activity have been showing up in this sector, and we believe this may have to do with a containment breach on \[REDACTED\] last month \ when a sapient hive intelligence displaying paranormal powers escaped into the unknown. They present a very large risk as they can assimilate people into \ the hivemind with ease, although they appear unable to affect mindshielded personnel." + +/datum/game_mode/hivemind/generate_credit_text() + var/list/round_credits = list() + var/len_before_addition + + for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts) + round_credits += "

Hive [H.hiveID]:

" + len_before_addition = round_credits.len + round_credits += "

[H.name] as the Hivemind Host

" + for(var/datum/antagonist/hivevessel/V as() in H.avessels) + round_credits += "

[V.name] as an Awakened Vessel

" + if(len_before_addition == round_credits.len) + round_credits += list("

Hive [H.hiveID] couldn't withstand the competition!

") + round_credits += "
" + + round_credits += ..() + return round_credits \ No newline at end of file diff --git a/code/game/gamemodes/hivemind/objectives.dm b/code/game/gamemodes/hivemind/objectives.dm index 00c0245e4071..749cac2165aa 100644 --- a/code/game/gamemodes/hivemind/objectives.dm +++ b/code/game/gamemodes/hivemind/objectives.dm @@ -30,6 +30,18 @@ /datum/objective/hivemind/hiveescape/update_explanation_text() explanation_text = "Have at least [target_amount] members of the hive escape on the shuttle alive and free." +/datum/objective/hivemind/dominance/New() + update_explanation_text() + +/datum/objective/hivemind/dominance/update_explanation_text() + explanation_text = "Assert dominance after having twenty more vessels and more integrations than any other hive." + +/datum/objective/hivemind/dominance/check_completion() + var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind) + if(!host) + return ..() + return host?.unlocked_dominance || ..() + /datum/objective/hivemind/hiveescape/check_completion() if(..()) return TRUE @@ -51,7 +63,7 @@ var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind) if(!host) return FALSE - for(var/datum/antagonist/hivemind/H in GLOB.antagonists) + for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts) if(H == host) continue if(H.hive_size >= host.hive_size) From f216470da92eaa03453cd27224c7782ed6173aca Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Sat, 2 Jul 2022 14:19:32 +0300 Subject: [PATCH 39/86] del --- code/game/gamemodes/hivemind/radar.dm | 74 --------------------------- 1 file changed, 74 deletions(-) delete mode 100644 code/game/gamemodes/hivemind/radar.dm diff --git a/code/game/gamemodes/hivemind/radar.dm b/code/game/gamemodes/hivemind/radar.dm deleted file mode 100644 index 27c1154d8d6a..000000000000 --- a/code/game/gamemodes/hivemind/radar.dm +++ /dev/null @@ -1,74 +0,0 @@ -#define HIVEMIND_RADAR_MIN_DISTANCE 0 //Very generous, as the targets are only tracked for a few minutes. -#define HIVEMIND_RADAR_MAX_DISTANCE 50 -#define HIVEMIND_RADAR_PING_TIME 40 //4s update time. - -//Modified IA/changeling pinpointer, points to the nearest person who is afflicted with the hive tracker status effect -/datum/status_effect/agent_pinpointer/hivemind - id = "hive_pinpointer" - alert_type = /obj/screen/alert/status_effect/agent_pinpointer/hivemind - minimum_range = HIVEMIND_RADAR_MIN_DISTANCE - tick_interval = HIVEMIND_RADAR_PING_TIME - range_fuzz_factor = 0 - -/datum/status_effect/agent_pinpointer/hivemind/point_to_target() //If we found what we're looking for, show the distance and direction - if(scan_target) - if(owner.mind) - var/datum/antagonist/hivemind/hive = owner.mind.has_antag_datum(/datum/antagonist/hivemind) - if(hive) - range_far = range_mid * (2-hive.get_threat_multiplier()) - if(scan_target.mind) - var/datum/antagonist/hivemind/enemy_hive = scan_target.mind.has_antag_datum(/datum/antagonist/hivemind) - if(enemy_hive) - range_far = max(range_mid * (1+enemy_hive.get_threat_multiplier()), range_far) - - ..() - -/datum/status_effect/agent_pinpointer/hivemind/scan_for_target() - var/turf/my_loc = get_turf(owner) - - var/list/mob/living/carbon/targets = list() - var/trackable_targets_exist = FALSE - - for(var/mob/living/carbon/C in GLOB.alive_mob_list) - if(C == owner) - continue - var/datum/status_effect/hive_track/mark = C.has_status_effect(STATUS_EFFECT_HIVE_TRACKER) - if(mark && mark.tracked_by == owner) - trackable_targets_exist = TRUE - var/their_loc = get_turf(C) - var/distance = get_dist_euclidian(my_loc, their_loc) - if (distance < HIVEMIND_RADAR_MAX_DISTANCE) - var/multiplier = 0.5 - if(C.mind) - var/datum/antagonist/hivemind/hive = C.mind.has_antag_datum(/datum/antagonist/hivemind) - if(hive) - multiplier = hive.get_threat_multiplier() - targets[C] = ((HIVEMIND_RADAR_MAX_DISTANCE ** 2) - (distance ** 2)) * multiplier - - if(targets.len) - scan_target = pickweight(targets) //Point at a 'random' target, biasing heavily towards closer ones. - else - scan_target = null - if(!trackable_targets_exist) - to_chat(owner, span_assimilator("The psychic energies eminating from afar have died down... for now")) - owner.remove_status_effect(STATUS_EFFECT_HIVE_RADAR) - -//"Trackable" status effect -/datum/status_effect/hive_track - id = "hive_track" - duration = 1200 - status_type = STATUS_EFFECT_MULTIPLE - alert_type = null - var/mob/living/tracked_by - -/datum/status_effect/hive_track/on_creation(mob/living/new_owner, mob/living/hunter, set_duration) - . = ..() - if(.) - tracked_by = hunter - if(isnum(set_duration)) - duration = world.time + set_duration - -//Screen alert -/obj/screen/alert/status_effect/agent_pinpointer/hivemind - name = "Psychic link" - desc = "Somebody is there, and they're definitely not friendly." From 3abc65d67c14a78d4f2312a15ae219a1fa1e3e90 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 13:51:41 +0300 Subject: [PATCH 40/86] e --- code/__DEFINES/melee.dm | 1 + yogstation/code/datums/martial/stealth.dm | 95 +++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 yogstation/code/datums/martial/stealth.dm diff --git a/code/__DEFINES/melee.dm b/code/__DEFINES/melee.dm index 79a42444763f..972f2638f851 100644 --- a/code/__DEFINES/melee.dm +++ b/code/__DEFINES/melee.dm @@ -12,6 +12,7 @@ #define MARTIALART_FLYINGFANG "flying fang" #define MARTIALART_HUNTERFU "hunterfu" #define MARTIALART_FRENZYGRAB "frenzy grabbing" +#define MARTIALART_PRETERNISSTEALTH "preternis stealth" //Weapon stat defines diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm new file mode 100644 index 000000000000..597e2c2112a0 --- /dev/null +++ b/yogstation/code/datums/martial/stealth.dm @@ -0,0 +1,95 @@ +///hidden dagger +#define PRE_DAGGER_COMBO "HH" +#define DAGGER_COMBO "HHG" +///injection +#define PRE_INJECTION_COMBO "DH" +#define INJECTION_COMBO "DHD" +///fingergun +#define PRE_FINGERGUN_COMBO "HD" +#define FINGERGUN_COMBO "HDD" + +/datum/martial_art/stealth + name = "Stealth" //Sorry for shitty name, I am bad at this + id = MARTIALART_PRETERNISSTEALTH + //help_verb = /mob/living/carbon/human/proc/CQC_help + +/datum/martial_art/stealth/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) // A!=D prevents grabbing yourself + add_to_streak("G",D) + if(check_streak(A,D)) //if a combo is made no grab upgrade is done + return TRUE + return TRUE + else + return FALSE + +/datum/martial_art/stealth/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_use(A)) + return FALSE + add_to_streak("H",D) + if(check_streak(A,D)) + return TRUE + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) + var/armor_block = D.run_armor_check(affecting, MELEE, armour_penetration = 10) + D.apply_damage(A.dna.species.punchdamagehigh + 2, A.dna.species.attack_type, selected_zone, armor_block) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + D.visible_message(span_danger("[A] assaulted [D]!"), \ + span_userdanger("[A] assaults you!")) + log_combat(A, D, "assaulted") + + +/datum/martial_art/stealth/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!(can_use(A))) + return FALSE + add_to_streak("D",D) + if(check_streak(A,D)) + return TRUE + A.do_attack_animation(D, ATTACK_EFFECT_DISARM) + user.visible_message(span_danger("[user.name] shoves [target.name]!"), + span_danger("You shove [target.name]!"), null, COMBAT_MESSAGE_RANGE) + var/target_held_item = target.get_active_held_item() + var/knocked_item = FALSE + if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types)) + target_held_item = null + if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE)) + target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH) + if(target_held_item) + target.visible_message(span_danger("[target.name]'s grip on \the [target_held_item] loosens!"), + span_danger("Your grip on \the [target_held_item] loosens!"), null, COMBAT_MESSAGE_RANGE) + addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) + else if(target_held_item) + target.dropItemToGround(target_held_item) + knocked_item = TRUE + target.visible_message(span_danger("[target.name] drops \the [target_held_item]!!"), + span_danger("You drop \the [target_held_item]!!"), null, COMBAT_MESSAGE_RANGE) + var/append_message = "" + if(target_held_item) + if(knocked_item) + append_message = "causing them to drop [target_held_item]" + else + append_message = "loosening their grip on [target_held_item]" + log_combat(user, target, "shoved", append_message) + +/datum/martial_art/stealth/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_use(A)) + return + if(findtext(streak, PRE_DAGGER_COMBO)) + hidden_knife(A,D) + return TRUE + if(findtext(streak, PRE_INJECTION_COMBO)) + injection(A,D) + return TRUE + if(findtext(streak, PRE_FINGERGUN_COMBO)) + fingergun(A,D) + return TRUE + +/datum/martial_art/stealth/proc/hidden_knife(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(findtext(streak, DAGGER_COMBO)) + var/selected_zone = A.zone_selected + var/armor_block = D.run_armor_check(affecting, MELEE, armour_penetration = 40) + D.apply_damage(30, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) + +/datum/martial_art/stealth/proc/injection(mob/living/carbon/human/A, mob/living/carbon/human/D) + +/datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A, mob/living/carbon/human/D) + From 5f70b2c49ff1a79830ebcd07fa26ea5f8d47a505 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:07:42 +0300 Subject: [PATCH 41/86] e --- yogstation/code/datums/martial/stealth.dm | 60 ++++++++++------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index 597e2c2112a0..f10791081309 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -28,14 +28,7 @@ add_to_streak("H",D) if(check_streak(A,D)) return TRUE - var/selected_zone = A.zone_selected - var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, MELEE, armour_penetration = 10) - D.apply_damage(A.dna.species.punchdamagehigh + 2, A.dna.species.attack_type, selected_zone, armor_block) - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - D.visible_message(span_danger("[A] assaulted [D]!"), \ - span_userdanger("[A] assaults you!")) - log_combat(A, D, "assaulted") + return FALSE ///We need it work like a generic, non martial art attack /datum/martial_art/stealth/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) @@ -44,38 +37,13 @@ add_to_streak("D",D) if(check_streak(A,D)) return TRUE - A.do_attack_animation(D, ATTACK_EFFECT_DISARM) - user.visible_message(span_danger("[user.name] shoves [target.name]!"), - span_danger("You shove [target.name]!"), null, COMBAT_MESSAGE_RANGE) - var/target_held_item = target.get_active_held_item() - var/knocked_item = FALSE - if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types)) - target_held_item = null - if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE)) - target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH) - if(target_held_item) - target.visible_message(span_danger("[target.name]'s grip on \the [target_held_item] loosens!"), - span_danger("Your grip on \the [target_held_item] loosens!"), null, COMBAT_MESSAGE_RANGE) - addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) - else if(target_held_item) - target.dropItemToGround(target_held_item) - knocked_item = TRUE - target.visible_message(span_danger("[target.name] drops \the [target_held_item]!!"), - span_danger("You drop \the [target_held_item]!!"), null, COMBAT_MESSAGE_RANGE) - var/append_message = "" - if(target_held_item) - if(knocked_item) - append_message = "causing them to drop [target_held_item]" - else - append_message = "loosening their grip on [target_held_item]" - log_combat(user, target, "shoved", append_message) + return FALSE ///Same as with harm_act /datum/martial_art/stealth/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) return if(findtext(streak, PRE_DAGGER_COMBO)) - hidden_knife(A,D) - return TRUE + return hidden_knife(A,D) if(findtext(streak, PRE_INJECTION_COMBO)) injection(A,D) return TRUE @@ -86,10 +54,32 @@ /datum/martial_art/stealth/proc/hidden_knife(mob/living/carbon/human/A, mob/living/carbon/human/D) if(findtext(streak, DAGGER_COMBO)) var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(selected_zone)) var/armor_block = D.run_armor_check(affecting, MELEE, armour_penetration = 40) D.apply_damage(30, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) + to_chat(A, span_warning("You stab [D] with a hidden blade!")) + to_chat(D, span_userdanger("You are suddenly stabbed with a blade!")) + streak = "" + return TRUE + else + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(selected_zone)) + var/armor_block = D.run_armor_check(affecting, MELEE, armour_penetration = 10) + D.apply_damage(20, STAMINA, affecting, armor_block) + D.apply_damage(5, BRUTE, affecting, armor_block) + return FALSE //Because it is a stealthy martial art, we need it to work like... a normal shove, so people nearby couldn't understand so easy that you know a martial art. + /datum/martial_art/stealth/proc/injection(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(findtext(streak, INJECTION_COMBO)) + D.reagents.add_reagent(/datum/reagent/toxin/sodium_thiopental, 8) + to_chat(A, span_warning("You inject sodium thiopental into [D]!")) + to_chat(D, span_notice("You feel a tiny prick.")) + streak = "" + else + D.reagents.add_reagent(/datum/reagent/toxin/cyanide, 5) + to_chat(A, span_warning("You inject cyanide into [D]!")) + to_chat(D, span_notice("You feel a tiny prick.")) /datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A, mob/living/carbon/human/D) From aaeaf3b84f205dc6517662821dee267c440e073f Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:37:25 +0300 Subject: [PATCH 42/86] i hope ot will work --- yogstation.dme | 1 + yogstation/code/datums/martial/stealth.dm | 44 ++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/yogstation.dme b/yogstation.dme index 5bea18dda1e9..c46e74546070 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -3344,6 +3344,7 @@ #include "yogstation\code\datums\diseases\advance\symptoms\confusion.dm" #include "yogstation\code\datums\diseases\advance\symptoms\heal.dm" #include "yogstation\code\datums\looping_sounds\darkspawn.dm" +#include "yogstation\code\datums\martial\stealth.dm" #include "yogstation\code\datums\mood_events\generic_positive_events.dm" #include "yogstation\code\datums\mutations\alcohol.dm" #include "yogstation\code\datums\mutations\extendoarm.dm" diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index f10791081309..da318034bfc2 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -5,7 +5,6 @@ #define PRE_INJECTION_COMBO "DH" #define INJECTION_COMBO "DHD" ///fingergun -#define PRE_FINGERGUN_COMBO "HD" #define FINGERGUN_COMBO "HDD" /datum/martial_art/stealth @@ -47,8 +46,8 @@ if(findtext(streak, PRE_INJECTION_COMBO)) injection(A,D) return TRUE - if(findtext(streak, PRE_FINGERGUN_COMBO)) - fingergun(A,D) + if(findtext(streak, FINGERGUN_COMBO)) + fingergun(A) return TRUE /datum/martial_art/stealth/proc/hidden_knife(mob/living/carbon/human/A, mob/living/carbon/human/D) @@ -81,5 +80,42 @@ to_chat(A, span_warning("You inject cyanide into [D]!")) to_chat(D, span_notice("You feel a tiny prick.")) -/datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A, mob/living/carbon/human/D) +/datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A) + var/obj/item/gun = new /obj/item/gun/ballistic/automatic/pistol/martial (A) ///I don't check does the user have an item in a hand, because it is a martial art action, and to use it... you need to have a empty hand + user.put_in_hands(gun) + to_chat(A, span_notice("You extract a hiden gun from your hand.")) + streak = "" +/obj/item/gun/ballistic/automatic/pistol/martial + desc = "A concelated version of a stechkin APS pistol, that comes with special Preternis upgrade modules." + can_suppress = TRUE + fire_sound_volume = 30 + lefthand_file = null ///We don't want it to be visible inhands + righthand_file = null + var/dying = FALSE + +/obj/item/gun/ballistic/automatic/pistol/martial/Initialize(mapload) + . = ..() + var/obj/item/suppressor/S = new(src) + install_suppressor(S) + +/obj/item/gun/ballistic/automatic/pistol/martial/eject_magazine(mob/user, display_message = TRUE, obj/item/ammo_box/magazine/tac_load = null) + return FALSE + +/obj/item/gun/ballistic/automatic/pistol/martial/insert_magazine(mob/user, obj/item/ammo_box/magazine/AM, display_message = TRUE) + return FALSE + +/obj/item/gun/ballistic/automatic/pistol/martial/attack_self(mob/living/user) + to_chat(A, span_notice("You decide that it isn't the best time to use [src]")) + qdel(src) + return + +/obj/item/gun/ballistic/automatic/pistol/martial/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) + if(!dying) + addtimer(CALLBACK(src, .proc/process_burst), 2 SECONDS) ///I, kinda, don't very understand what gun code does, but it seems to be OK. + dying = TRUE + . = ..() + +/obj/item/gun/ballistic/automatic/pistol/martial/proc/Die() + to_chat(A, span_warning("You hide [src].")) + qdel(src) \ No newline at end of file From 9f218929d5c38c1ebf83928f143c02c907e544d3 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:47:32 +0300 Subject: [PATCH 43/86] Update antagonists.dm --- code/__DEFINES/antagonists.dm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 341cf1c6a942..ccdc70876238 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -76,6 +76,13 @@ /// Prevents hijacking same way as non-antags #define HIJACK_PREVENT 2 +//Assimilation +#define TRACKER_DEFAULT_TIME 900 +#define TRACKER_MINDSHIELD_TIME 1200 +#define TRACKER_AWAKENED_TIME 3000 +#define TRACKER_BONUS_LARGE 300 +#define TRACKER_BONUS_SMALL 100 + //Syndicate Contracts #define CONTRACT_STATUS_INACTIVE 1 #define CONTRACT_STATUS_ACTIVE 2 From 881dc02e8a9a9bd7b0c074b826cfac9de3f2f2c5 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:47:52 +0300 Subject: [PATCH 44/86] Update role_preferences.dm --- code/__DEFINES/role_preferences.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index cb975ac3f8f2..07bb830ece9a 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -30,7 +30,6 @@ #define ROLE_BROTHER "Blood Brother" #define ROLE_BRAINWASHED "Brainwashed Victim" #define ROLE_HIVE "Hivemind Host" -#define ROLE_HIVE_VESSEL "Awakened Vessel" #define ROLE_OBSESSED "Obsessed" #define ROLE_SENTIENCE "Sentience Potion Spawn" #define ROLE_MIND_TRANSFER "Mind Transfer Potion" From 215425731dad15240a71e64d2fb24dd632200dee Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:48:08 +0300 Subject: [PATCH 45/86] Update status_effects.dm --- code/__DEFINES/status_effects.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 3dcd959bd438..4afbccca45e9 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -137,6 +137,10 @@ #define STATUS_EFFECT_BUGGED /datum/status_effect/bugged //Lets other mobs listen in on what it hears +#define STATUS_EFFECT_HIVE_TRACKER /datum/status_effect/hive_track + +#define STATUS_EFFECT_HIVE_RADAR /datum/status_effect/agent_pinpointer/hivemind + #define STATUS_EFFECT_BOUNTY /datum/status_effect/bounty //rewards the person who added this to the target with refreshed spells and a fair heal #define STATUS_EFFECT_HELDUP /datum/status_effect/heldup // someone is currently pointing a gun at you From acf5409d56cd515db27a71aece31acf63be7e36e Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:48:34 +0300 Subject: [PATCH 46/86] Update traits.dm --- code/__DEFINES/traits.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index c28887f30f2a..1a76af1d51df 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -322,7 +322,7 @@ #define LOCKED_HELMET_TRAIT "locked-helmet" #define NINJA_SUIT_TRAIT "ninja-suit" #define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant" -#define HIVEMIND_TRAIT "hivemind-trait" +#define HIVEMIND_ONE_MIND_TRAIT "one_mind" #define VR_ZONE_TRAIT "vr_zone_trait" #define GUARDIAN_TRAIT "guardian_trait" #define RANDOM_BLACKOUTS "random_blackouts" From 2bf21a5d5b62c8a3b671f7e0df36c7ac935d793c Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:48:54 +0300 Subject: [PATCH 47/86] Update mind.dm --- code/datums/mind.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index a162b28a9552..43f063a24237 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -283,10 +283,6 @@ if(O) O.unlock_code = null -/datum/mind/proc/remove_from_hives() - SIGNAL_HANDLER - remove_hivemember(src) - /datum/mind/proc/remove_all_antag() //For the Lazy amongst us. remove_changeling() remove_traitor() From 949cec989a0a52d8e3d439840bcdb3084d4cf121 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:49:42 +0300 Subject: [PATCH 48/86] Update objectives.dm --- code/game/gamemodes/hivemind/objectives.dm | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/code/game/gamemodes/hivemind/objectives.dm b/code/game/gamemodes/hivemind/objectives.dm index 749cac2165aa..3e3723ce5428 100644 --- a/code/game/gamemodes/hivemind/objectives.dm +++ b/code/game/gamemodes/hivemind/objectives.dm @@ -30,18 +30,6 @@ /datum/objective/hivemind/hiveescape/update_explanation_text() explanation_text = "Have at least [target_amount] members of the hive escape on the shuttle alive and free." -/datum/objective/hivemind/dominance/New() - update_explanation_text() - -/datum/objective/hivemind/dominance/update_explanation_text() - explanation_text = "Assert dominance after having twenty more vessels and more integrations than any other hive." - -/datum/objective/hivemind/dominance/check_completion() - var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind) - if(!host) - return ..() - return host?.unlocked_dominance || ..() - /datum/objective/hivemind/hiveescape/check_completion() if(..()) return TRUE From 29b50d5c08872700c054e5e1c79c25fc19379c5f Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:50:04 +0300 Subject: [PATCH 49/86] Update objectives.dm --- code/game/gamemodes/hivemind/objectives.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/hivemind/objectives.dm b/code/game/gamemodes/hivemind/objectives.dm index 3e3723ce5428..00c0245e4071 100644 --- a/code/game/gamemodes/hivemind/objectives.dm +++ b/code/game/gamemodes/hivemind/objectives.dm @@ -51,7 +51,7 @@ var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind) if(!host) return FALSE - for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts) + for(var/datum/antagonist/hivemind/H in GLOB.antagonists) if(H == host) continue if(H.hive_size >= host.hive_size) From b670dd3a9642095dbe47ba9d06c7e0ccf87536a5 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:50:43 +0300 Subject: [PATCH 50/86] Update traits.dm --- code/__DEFINES/traits.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 1a76af1d51df..bcfdfb97bfc0 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -220,7 +220,6 @@ #define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat #define TRAIT_MASQUERADE "masquerade" // Falsifies Health analyzer blood levels #define TRAIT_COLDBLOODED "coldblooded" // Your body is literal room temperature. Does not make you immune to the temp -#define TRAIT_HIVE_BURNT "hive-burnt" //non-mob traits /// Used for limb-based paralysis, where replacing the limb will fix it. From 938e28c037e772664390ece8b55fe415773ea60d Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:51:28 +0300 Subject: [PATCH 51/86] Update generic_positive_events.dm --- code/datums/mood_events/generic_positive_events.dm | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 98dfa995ad6b..0fb6810f229d 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -114,16 +114,6 @@ mood_change = 10 hidden = TRUE -/datum/mood_event/hivehost - description = "Our psyche expands, our influence broadens.\n" - mood_change = 5 - hidden = TRUE - -/datum/mood_event/hiveawakened - description = "True purpose has been revealed to us, at last!.\n" - mood_change = 2 - hidden = TRUE - /datum/mood_event/family_heirloom description = "My family heirloom is safe with me.\n" mood_change = 1 From 157f1acbfe2299f75e3881c1c7a380fc4231ac9a Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:51:48 +0300 Subject: [PATCH 52/86] Update dynamic_rulesets_roundstart.dm --- .../dynamic/dynamic_rulesets_roundstart.dm | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index b4d71ab85c4d..6f75591d5968 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -1002,37 +1002,3 @@ if(!bloodsuckermind.make_bloodsucker(assigned_bloodsuckers)) assigned -= assigned_bloodsuckers return TRUE - -////////////////////////////////////////////// -// // -// ASSIMILATION // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/roundstart/hivemind - name = "Assimilation" - antag_flag = ROLE_HIVE - antag_datum = /datum/antagonist/hivemind - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain") - restricted_roles = list("Cyborg","AI") - required_candidates = 3 - weight = 3 - cost = 30 - requirements = list(100,90,80,60,40,30,10,10,10,10) - flags = HIGH_IMPACT_RULESET - -/datum/dynamic_ruleset/roundstart/hivemind/pre_execute(population) - . = ..() - var/num_hosts = max( 3 , rand(0,1) + min(8, round(population / 8) ) ) - for (var/i = 1 to num_hosts) - var/mob/M = pick_n_take(candidates) - assigned += M.mind - M.mind.restricted_roles = restricted_roles - M.mind.special_role = ROLE_HIVE - return TRUE - -/datum/dynamic_ruleset/roundstart/hivemind/execute() - for(var/datum/mind/host in assigned) - var/datum/antagonist/hivemind/new_antag = new antag_datum() - host.add_antag_datum(new_antag) - return TRUE \ No newline at end of file From 0cc3edbeabb371b51427ae81b27361e5ee95343d Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:53:03 +0300 Subject: [PATCH 53/86] Update hivemind.dm --- code/game/gamemodes/hivemind/hivemind.dm | 43 +++++++++--------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/code/game/gamemodes/hivemind/hivemind.dm b/code/game/gamemodes/hivemind/hivemind.dm index 4a97379aca08..28838d59675e 100644 --- a/code/game/gamemodes/hivemind/hivemind.dm +++ b/code/game/gamemodes/hivemind/hivemind.dm @@ -1,15 +1,13 @@ -GLOBAL_LIST_EMPTY(hivehosts) - /datum/game_mode/hivemind - name = "assimilation" + name = "Assimilation" config_tag = "hivemind" report_type = "hivemind" antag_flag = ROLE_HIVE false_report_weight = 5 protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Brig Physician") //Yogs: Added "Brig Physician restricted_jobs = list("Cyborg","AI") - required_players = 30 - required_enemies = 3 + required_players = 24 + required_enemies = 2 recommended_enemies = 3 reroll_friendly = 1 enemy_minimum_age = 0 @@ -26,10 +24,15 @@ GLOBAL_LIST_EMPTY(hivehosts) return return M.mind.has_antag_datum(/datum/antagonist/hivemind) -/mob/living/proc/is_real_hivehost() - for(var/datum/antagonist/hivemind/hive as() in GLOB.hivehosts) +/mob/living/proc/is_real_hivehost() //This proc ignores mind controlled vessels + for(var/datum/antagonist/hivemind/hive in GLOB.antagonists) if(!hive.owner?.spell_list) continue + var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in hive.owner.spell_list + if((!the_spell || !the_spell.active ) && mind == hive.owner) + return TRUE + if(the_spell?.active && the_spell.original_body == src) + return TRUE return FALSE /mob/living/proc/get_real_hivehost() //Returns src unless it's under mind control, then it returns the original body @@ -38,6 +41,9 @@ GLOBAL_LIST_EMPTY(hivehosts) return if(!is_hivehost(M) || is_real_hivehost(M)) return M + var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in M.mind.spell_list + if(the_spell?.active) + return the_spell.original_body return M /proc/is_hivemember(mob/living/L) @@ -46,7 +52,7 @@ GLOBAL_LIST_EMPTY(hivehosts) var/datum/mind/M = L.mind if(!M) return FALSE - for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts) + for(var/datum/antagonist/hivemind/H in GLOB.antagonists) if(H.hivemembers.Find(M)) return TRUE return FALSE @@ -55,7 +61,7 @@ GLOBAL_LIST_EMPTY(hivehosts) var/datum/mind/M = L?.mind if(!M) return - for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts) + for(var/datum/antagonist/hivemind/H in GLOB.antagonists) if(H.hivemembers.Find(M)) H.hivemembers -= M H.calc_size() @@ -71,7 +77,7 @@ GLOBAL_LIST_EMPTY(hivehosts) if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" - var/num_hosts = max( 3 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra + var/num_hosts = max( 1 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra for(var/j = 0, j < num_hosts, j++) if (!antag_candidates.len) @@ -99,20 +105,3 @@ GLOBAL_LIST_EMPTY(hivehosts) return "Reports of psychic activity have been showing up in this sector, and we believe this may have to do with a containment breach on \[REDACTED\] last month \ when a sapient hive intelligence displaying paranormal powers escaped into the unknown. They present a very large risk as they can assimilate people into \ the hivemind with ease, although they appear unable to affect mindshielded personnel." - -/datum/game_mode/hivemind/generate_credit_text() - var/list/round_credits = list() - var/len_before_addition - - for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts) - round_credits += "

Hive [H.hiveID]:

" - len_before_addition = round_credits.len - round_credits += "

[H.name] as the Hivemind Host

" - for(var/datum/antagonist/hivevessel/V as() in H.avessels) - round_credits += "

[V.name] as an Awakened Vessel

" - if(len_before_addition == round_credits.len) - round_credits += list("

Hive [H.hiveID] couldn't withstand the competition!

") - round_credits += "
" - - round_credits += ..() - return round_credits \ No newline at end of file From 9a136a5f26b36ca7840ab44e2d5073d47709f222 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:54:47 +0300 Subject: [PATCH 54/86] Create radar.dm --- code/game/gamemodes/hivemind/radar.dm | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 code/game/gamemodes/hivemind/radar.dm diff --git a/code/game/gamemodes/hivemind/radar.dm b/code/game/gamemodes/hivemind/radar.dm new file mode 100644 index 000000000000..27c1154d8d6a --- /dev/null +++ b/code/game/gamemodes/hivemind/radar.dm @@ -0,0 +1,74 @@ +#define HIVEMIND_RADAR_MIN_DISTANCE 0 //Very generous, as the targets are only tracked for a few minutes. +#define HIVEMIND_RADAR_MAX_DISTANCE 50 +#define HIVEMIND_RADAR_PING_TIME 40 //4s update time. + +//Modified IA/changeling pinpointer, points to the nearest person who is afflicted with the hive tracker status effect +/datum/status_effect/agent_pinpointer/hivemind + id = "hive_pinpointer" + alert_type = /obj/screen/alert/status_effect/agent_pinpointer/hivemind + minimum_range = HIVEMIND_RADAR_MIN_DISTANCE + tick_interval = HIVEMIND_RADAR_PING_TIME + range_fuzz_factor = 0 + +/datum/status_effect/agent_pinpointer/hivemind/point_to_target() //If we found what we're looking for, show the distance and direction + if(scan_target) + if(owner.mind) + var/datum/antagonist/hivemind/hive = owner.mind.has_antag_datum(/datum/antagonist/hivemind) + if(hive) + range_far = range_mid * (2-hive.get_threat_multiplier()) + if(scan_target.mind) + var/datum/antagonist/hivemind/enemy_hive = scan_target.mind.has_antag_datum(/datum/antagonist/hivemind) + if(enemy_hive) + range_far = max(range_mid * (1+enemy_hive.get_threat_multiplier()), range_far) + + ..() + +/datum/status_effect/agent_pinpointer/hivemind/scan_for_target() + var/turf/my_loc = get_turf(owner) + + var/list/mob/living/carbon/targets = list() + var/trackable_targets_exist = FALSE + + for(var/mob/living/carbon/C in GLOB.alive_mob_list) + if(C == owner) + continue + var/datum/status_effect/hive_track/mark = C.has_status_effect(STATUS_EFFECT_HIVE_TRACKER) + if(mark && mark.tracked_by == owner) + trackable_targets_exist = TRUE + var/their_loc = get_turf(C) + var/distance = get_dist_euclidian(my_loc, their_loc) + if (distance < HIVEMIND_RADAR_MAX_DISTANCE) + var/multiplier = 0.5 + if(C.mind) + var/datum/antagonist/hivemind/hive = C.mind.has_antag_datum(/datum/antagonist/hivemind) + if(hive) + multiplier = hive.get_threat_multiplier() + targets[C] = ((HIVEMIND_RADAR_MAX_DISTANCE ** 2) - (distance ** 2)) * multiplier + + if(targets.len) + scan_target = pickweight(targets) //Point at a 'random' target, biasing heavily towards closer ones. + else + scan_target = null + if(!trackable_targets_exist) + to_chat(owner, span_assimilator("The psychic energies eminating from afar have died down... for now")) + owner.remove_status_effect(STATUS_EFFECT_HIVE_RADAR) + +//"Trackable" status effect +/datum/status_effect/hive_track + id = "hive_track" + duration = 1200 + status_type = STATUS_EFFECT_MULTIPLE + alert_type = null + var/mob/living/tracked_by + +/datum/status_effect/hive_track/on_creation(mob/living/new_owner, mob/living/hunter, set_duration) + . = ..() + if(.) + tracked_by = hunter + if(isnum(set_duration)) + duration = world.time + set_duration + +//Screen alert +/obj/screen/alert/status_effect/agent_pinpointer/hivemind + name = "Psychic link" + desc = "Somebody is there, and they're definitely not friendly." From d7cfd5605aea430d900409efa79bc9abf5a200a3 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:58:55 +0300 Subject: [PATCH 55/86] fixes --- yogstation/code/datums/martial/stealth.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index da318034bfc2..3ffa4ac1fbcb 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -53,7 +53,7 @@ /datum/martial_art/stealth/proc/hidden_knife(mob/living/carbon/human/A, mob/living/carbon/human/D) if(findtext(streak, DAGGER_COMBO)) var/selected_zone = A.zone_selected - var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(selected_zone)) + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) var/armor_block = D.run_armor_check(affecting, MELEE, armour_penetration = 40) D.apply_damage(30, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) to_chat(A, span_warning("You stab [D] with a hidden blade!")) @@ -62,7 +62,7 @@ return TRUE else var/selected_zone = A.zone_selected - var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(selected_zone)) + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) var/armor_block = D.run_armor_check(affecting, MELEE, armour_penetration = 10) D.apply_damage(20, STAMINA, affecting, armor_block) D.apply_damage(5, BRUTE, affecting, armor_block) @@ -82,7 +82,7 @@ /datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A) var/obj/item/gun = new /obj/item/gun/ballistic/automatic/pistol/martial (A) ///I don't check does the user have an item in a hand, because it is a martial art action, and to use it... you need to have a empty hand - user.put_in_hands(gun) + A.put_in_hands(gun) to_chat(A, span_notice("You extract a hiden gun from your hand.")) streak = "" @@ -106,7 +106,7 @@ return FALSE /obj/item/gun/ballistic/automatic/pistol/martial/attack_self(mob/living/user) - to_chat(A, span_notice("You decide that it isn't the best time to use [src]")) + to_chat(user, span_notice("You decide that it isn't the best time to use [src]")) qdel(src) return @@ -117,5 +117,5 @@ . = ..() /obj/item/gun/ballistic/automatic/pistol/martial/proc/Die() - to_chat(A, span_warning("You hide [src].")) + to_chat(user, span_warning("You hide [src].")) qdel(src) \ No newline at end of file From 716d01335193fda4291aa895d154c3ef17b78f5f Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 15:03:16 +0300 Subject: [PATCH 56/86] fix2 --- yogstation/code/datums/martial/stealth.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index 3ffa4ac1fbcb..541094f53f7e 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -82,6 +82,7 @@ /datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A) var/obj/item/gun = new /obj/item/gun/ballistic/automatic/pistol/martial (A) ///I don't check does the user have an item in a hand, because it is a martial art action, and to use it... you need to have a empty hand + gun.master = A A.put_in_hands(gun) to_chat(A, span_notice("You extract a hiden gun from your hand.")) streak = "" @@ -92,6 +93,7 @@ fire_sound_volume = 30 lefthand_file = null ///We don't want it to be visible inhands righthand_file = null + var/mob/master //Dungeon master var/dying = FALSE /obj/item/gun/ballistic/automatic/pistol/martial/Initialize(mapload) @@ -117,5 +119,5 @@ . = ..() /obj/item/gun/ballistic/automatic/pistol/martial/proc/Die() - to_chat(user, span_warning("You hide [src].")) + to_chat(master, span_warning("You hide [src].")) qdel(src) \ No newline at end of file From 1cac7f7b764eb4342aa2851fe24e1ca8851507c0 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 15:08:50 +0300 Subject: [PATCH 57/86] fix3 --- yogstation/code/datums/martial/stealth.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index 541094f53f7e..257a2792c0d6 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -82,7 +82,7 @@ /datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A) var/obj/item/gun = new /obj/item/gun/ballistic/automatic/pistol/martial (A) ///I don't check does the user have an item in a hand, because it is a martial art action, and to use it... you need to have a empty hand - gun.master = A + gun.gun_owner = A A.put_in_hands(gun) to_chat(A, span_notice("You extract a hiden gun from your hand.")) streak = "" @@ -93,7 +93,7 @@ fire_sound_volume = 30 lefthand_file = null ///We don't want it to be visible inhands righthand_file = null - var/mob/master //Dungeon master + var/mob/gun_owner var/dying = FALSE /obj/item/gun/ballistic/automatic/pistol/martial/Initialize(mapload) @@ -119,5 +119,5 @@ . = ..() /obj/item/gun/ballistic/automatic/pistol/martial/proc/Die() - to_chat(master, span_warning("You hide [src].")) + to_chat(gun_owner, span_warning("You hide [src].")) qdel(src) \ No newline at end of file From 664023ca1397f129e7c3d5f8360066370ab6758e Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Tue, 5 Jul 2022 15:12:27 +0300 Subject: [PATCH 58/86] fix4 --- yogstation/code/datums/martial/stealth.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index 257a2792c0d6..757c3336112a 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -81,7 +81,7 @@ to_chat(D, span_notice("You feel a tiny prick.")) /datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A) - var/obj/item/gun = new /obj/item/gun/ballistic/automatic/pistol/martial (A) ///I don't check does the user have an item in a hand, because it is a martial art action, and to use it... you need to have a empty hand + var/obj/item/gun/ballistic/automatic/pistol/martial/gun = new /obj/item/gun/ballistic/automatic/pistol/martial (A) ///I don't check does the user have an item in a hand, because it is a martial art action, and to use it... you need to have a empty hand gun.gun_owner = A A.put_in_hands(gun) to_chat(A, span_notice("You extract a hiden gun from your hand.")) From a8823db71da7d66f22214cfa64434e2aa9cf8a98 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 6 Jul 2022 15:40:26 +0300 Subject: [PATCH 59/86] tverb --- yogstation/code/datums/martial/stealth.dm | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index 757c3336112a..267056e3056f 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -10,7 +10,7 @@ /datum/martial_art/stealth name = "Stealth" //Sorry for shitty name, I am bad at this id = MARTIALART_PRETERNISSTEALTH - //help_verb = /mob/living/carbon/human/proc/CQC_help + help_verb = /mob/living/carbon/human/proc/preternis_martial_help /datum/martial_art/stealth/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) // A!=D prevents grabbing yourself @@ -47,8 +47,8 @@ injection(A,D) return TRUE if(findtext(streak, FINGERGUN_COMBO)) - fingergun(A) - return TRUE + fingergun(A,D) + return FALSE /datum/martial_art/stealth/proc/hidden_knife(mob/living/carbon/human/A, mob/living/carbon/human/D) if(findtext(streak, DAGGER_COMBO)) @@ -80,11 +80,12 @@ to_chat(A, span_warning("You inject cyanide into [D]!")) to_chat(D, span_notice("You feel a tiny prick.")) -/datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A) +/datum/martial_art/stealth/proc/fingergun(mob/living/carbon/human/A, mob/living/carbon/human/D) var/obj/item/gun/ballistic/automatic/pistol/martial/gun = new /obj/item/gun/ballistic/automatic/pistol/martial (A) ///I don't check does the user have an item in a hand, because it is a martial art action, and to use it... you need to have a empty hand gun.gun_owner = A A.put_in_hands(gun) to_chat(A, span_notice("You extract a hiden gun from your hand.")) + D.Paralyze(1 SECONDS) streak = "" /obj/item/gun/ballistic/automatic/pistol/martial @@ -100,6 +101,7 @@ . = ..() var/obj/item/suppressor/S = new(src) install_suppressor(S) + ADD_TRAIT(src, TRAIT_NODROP, "martial") /obj/item/gun/ballistic/automatic/pistol/martial/eject_magazine(mob/user, display_message = TRUE, obj/item/ammo_box/magazine/tac_load = null) return FALSE @@ -120,4 +122,14 @@ /obj/item/gun/ballistic/automatic/pistol/martial/proc/Die() to_chat(gun_owner, span_warning("You hide [src].")) - qdel(src) \ No newline at end of file + qdel(src) + +/mob/living/carbon/human/proc/preternis_martial_help() + set name = "Refresh Data" + set desc = "You try to remember some basic actions from your upgraded combat modules." + set category = "Combat Modules" + to_chat(usr, "You try to remember some basic actions from your upgraded combat modules.") + + to_chat(usr, "[span_notice("Hidden Blade")]: Harm Harm Grab. The second strike will deal 20 stamina and 5 brute damage, and finishing the combo will make you stab the victim with a hiden blade, dealing 30 brute damage.") + to_chat(usr, "[span_notice("Injection")]: Disarm Harm Disarm. The second and third attack will stealthy inject respectively 5 units of cyanide and 8 unites of sodium thiopental.") + to_chat(usr, "[span_notice("Finger gun")]: Harm Disarm Disarm. Finishing the combo will paralyze your target and place a stealthy version of a stechkin in your hand.") \ No newline at end of file From 6de20ae4a02c3e03c3c73740a1b544eb23b3b9ae Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:52:52 +0300 Subject: [PATCH 60/86] explosive fisting is 300$ --- .../code/datums/martial/explosive_fist.dm | 123 ++++++++++++++++++ yogstation/code/datums/martial/stealth.dm | 13 +- 2 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 yogstation/code/datums/martial/explosive_fist.dm diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm new file mode 100644 index 000000000000..9ef91c4da89f --- /dev/null +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -0,0 +1,123 @@ +#define EXPLOSIVE_DISARM_COMBO "DD" + +#define DETONATE_COMBO "HHDH" +#define PRE_DETONATE_COMBO "HH" +#define ALMOST_DETONATE_COMBO "HHD" + + +/datum/martial_art/explosive_fist + name = "Explosive Fist" + id = MARTIALART_PRETERNISSTEALTH + //help_verb = /mob/living/carbon/human/proc/preternis_martial_help + +/datum/martial_art/explosive_fist/can_use(mob/living/carbon/human/H) + return isplasmaman(H) + +/datum/martial_art/explosive_fist/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) // A!=D prevents grabbing yourself + add_to_streak("G",D) + if(check_streak(A,D)) //if a combo is made no grab upgrade is done + return TRUE + return FALSE + else + return FALSE + +/datum/martial_art/explosive_fist/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_use(A)) + return FALSE + add_to_streak("H",D) + if(check_streak(A,D)) + return TRUE + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) + var/brute_block = D.run_armor_check(affecting, MELEE, 0) + var/burn_block = D.run_armor_check(affecting, BOMB, 0) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) + D.apply_damage(10, BRUTE, selected_zone, brute_block) + D.apply_damage(10, BURN, selected_zone, burn_block) + D.visible_message(span_danger("[A] [A.dna.species.attack_verb]s [D]!"), \ + span_userdanger("[A] [A.dna.species.atk_verb]s you!")) + log_combat(A, D, "[A.dna.species.atk_verb]s(Explosive Fist)") + + +/datum/martial_art/explosive_fist/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!(can_use(A))) + return FALSE + add_to_streak("D",D) + if(check_streak(A,D)) + return TRUE + return FALSE ///Same as with harm_act + +/datum/martial_art/explosive_fist/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_use(A)) + return + if(findtext(streak, EXPLOSIVE_DISARM_COMBO)) + explosive_disarm(A,D) + return TRUE + if(findtext(streak, PRE_DETONATE_COMBO)) + detonate(A,D) + return TRUE + +/datum/martial_art/explosive_fist/proc/explosive_disarm(mob/living/carbon/human/A, mob/living/carbon/human/D) + A.adjustFireLoss(10) + D.adjustFireLoss(18) + D.Knockdown(3 SECONDS) + playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) + A.do_attack_animation(D, ATTACK_EFFECT_DISARM) + log_combat(A, D, "blasts(Explosive Fist)") + D.visible_message(span_danger("[A] blasts [D]!"), \ + span_userdanger("[A] blasts you!")) + var/atom/throw_target = get_edge_target_turf(D, dir) + D.throw_at(throw_target, rand(1,2), 7, A) + streak = "" + +/datum/martial_art/explosive_fist/proc/detonate(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(findtext(streak, DETONATE_COMBO)) + A.do_attack_animation(D, ATTACK_EFFECT_SMASH) + log_combat(A, D, "detonates(Explosive Fist)") + D.visible_message(span_danger("[A] detonates [D]!"), \ + span_userdanger("[A] detonates you!")) + D.adjust_fire_stacks(1) + D.IgniteMob() + playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) + + var/obj/item/bodypart/affecting = target.get_bodypart(BODY_ZONE_CHEST) + var/armor_block = target.run_armor_check(affecting, BOMB) + A.apply_damage(15, BRUTE, BODY_ZONE_CHEST, armor_block) + streak = "" + + else if(findtext(streak, ALMOST_DETONATE_COMBO)) + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) + var/armor_block = D.run_armor_check(affecting, MELEE, 0) + A.do_attack_animation(D, ATTACK_EFFECT_DISARM) + playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) + var/current_stamina_damage = D.getStaminaLoss() + var/damage_to_deal = 55 + + if(current_stamina_damage > 50) ///We apply a stamina slowdown on our target, our do nothing! + damage_to_deal = 0 + D.apply_damage(damage_to_deal, STAMINA, selected_zone, armor_block) + D.visible_message(span_danger("[A] activates [D]!"), \ + span_userdanger("[A] activates you!")) + log_combat(A, D, "activates(Explosive Fist)") + D.adjust_fire_stacks(4) + + else + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) + var/brute_block = D.run_armor_check(affecting, MELEE, 0) + var/burn_block = D.run_armor_check(affecting, BOMB, 0) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) + D.apply_damage(12, BRUTE, selected_zone, brute_block) + D.apply_damage(12, BURN, selected_zone, burn_block) + D.adjust_fire_stacks(2) + D.visible_message(span_danger("[A] primes [D]!"), \ + span_userdanger("[A] primes you!")) + log_combat(A, D, "primes(Explosive Fist)") + + + + \ No newline at end of file diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index 267056e3056f..1aa00439ec1d 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -12,12 +12,15 @@ id = MARTIALART_PRETERNISSTEALTH help_verb = /mob/living/carbon/human/proc/preternis_martial_help +/datum/martial_art/stealth/can_use(mob/living/carbon/human/H) + return ispreternis(H) + /datum/martial_art/stealth/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) // A!=D prevents grabbing yourself add_to_streak("G",D) if(check_streak(A,D)) //if a combo is made no grab upgrade is done return TRUE - return TRUE + return FALSE else return FALSE @@ -132,4 +135,10 @@ to_chat(usr, "[span_notice("Hidden Blade")]: Harm Harm Grab. The second strike will deal 20 stamina and 5 brute damage, and finishing the combo will make you stab the victim with a hiden blade, dealing 30 brute damage.") to_chat(usr, "[span_notice("Injection")]: Disarm Harm Disarm. The second and third attack will stealthy inject respectively 5 units of cyanide and 8 unites of sodium thiopental.") - to_chat(usr, "[span_notice("Finger gun")]: Harm Disarm Disarm. Finishing the combo will paralyze your target and place a stealthy version of a stechkin in your hand.") \ No newline at end of file + to_chat(usr, "[span_notice("Finger gun")]: Harm Disarm Disarm. Finishing the combo will paralyze your target and place a stealthy version of a stechkin in your hand.") + +#undef PRE_DAGGER_COMBO +#undef DAGGER_COMBO +#undef PRE_INJECTION_COMBO +#undef INJECTION_COMBO +#undef FINGERGUN_COMBO \ No newline at end of file From 3d98a81c6b5fda78918ac7261c9ad71210edfa9b Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:55:46 +0300 Subject: [PATCH 61/86] e --- yogstation/code/datums/martial/explosive_fist.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index 9ef91c4da89f..36640c420653 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -92,7 +92,7 @@ var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) var/armor_block = D.run_armor_check(affecting, MELEE, 0) A.do_attack_animation(D, ATTACK_EFFECT_DISARM) - playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) + playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) var/current_stamina_damage = D.getStaminaLoss() var/damage_to_deal = 55 From 73543c4747b13075b46cb2bdab9a15512e900422 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Thu, 7 Jul 2022 15:22:18 +0300 Subject: [PATCH 62/86] e --- code/datums/martial.dm | 2 +- .../code/datums/martial/explosive_fist.dm | 96 +++++++++++++++++-- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/code/datums/martial.dm b/code/datums/martial.dm index 056d232b7704..0bb1ffb25dc4 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -209,4 +209,4 @@ /datum/martial_art/proc/on_remove(mob/living/carbon/human/H) if(help_verb) remove_verb(H, help_verb) - return + return \ No newline at end of file diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index 36640c420653..66d828d3acc7 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -4,11 +4,16 @@ #define PRE_DETONATE_COMBO "HH" #define ALMOST_DETONATE_COMBO "HHD" +#define LIFEFORCE_TRADE_COMBO "DGDG" +#define PRE_LIFEFORCE_TRADE_COMBO "DG" +#define ALMOST_LIFEFORCE_TRADE_COMBO "DGD" + /datum/martial_art/explosive_fist name = "Explosive Fist" id = MARTIALART_PRETERNISSTEALTH //help_verb = /mob/living/carbon/human/proc/preternis_martial_help + var/life_force_trade_active = FALSE /datum/martial_art/explosive_fist/can_use(mob/living/carbon/human/H) return isplasmaman(H) @@ -58,10 +63,20 @@ if(findtext(streak, PRE_DETONATE_COMBO)) detonate(A,D) return TRUE + if(findtext(streak, PRE_LIFEFORCE_TRADE_COMBO)) + lifeforce_trade(A,D) + return TRUE /datum/martial_art/explosive_fist/proc/explosive_disarm(mob/living/carbon/human/A, mob/living/carbon/human/D) - A.adjustFireLoss(10) - D.adjustFireLoss(18) + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) + var/armor_block = D.run_armor_check(affecting, BOMB, 0) + D.apply_damage(18, BURN, BODY_ZONE_CHEST, armor_block) + + var/obj/item/bodypart/affecting_p = A.get_bodypart(BODY_ZONE_CHEST) // p - plasmamen + var/armor_block_p = A.run_armor_check(affecting_p, BOMB) + A.apply_damage(10, BURN, BODY_ZONE_CHEST, armor_block_p) + D.Knockdown(3 SECONDS) playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) A.do_attack_animation(D, ATTACK_EFFECT_DISARM) @@ -78,11 +93,11 @@ log_combat(A, D, "detonates(Explosive Fist)") D.visible_message(span_danger("[A] detonates [D]!"), \ span_userdanger("[A] detonates you!")) - D.adjust_fire_stacks(1) + explosion(get_turf(affected_mob), -1, 0, 2, 0, 0, 2) D.IgniteMob() playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) - var/obj/item/bodypart/affecting = target.get_bodypart(BODY_ZONE_CHEST) + var/obj/item/bodypart/affecting = A.get_bodypart(BODY_ZONE_CHEST) var/armor_block = target.run_armor_check(affecting, BOMB) A.apply_damage(15, BRUTE, BODY_ZONE_CHEST, armor_block) streak = "" @@ -118,6 +133,75 @@ span_userdanger("[A] primes you!")) log_combat(A, D, "primes(Explosive Fist)") +/datum/martial_art/explosive_fist/proc/lifeforce_trade(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(findtext(streak, LIFEFORCE_TRADE_COMBO)) + if(A.get_item_by_slot(ITEM_SLOT_HEAD)) + A.do_attack_animation(D, ATTACK_EFFECT_SMASH) + playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1) + + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) + var/brute_block = D.run_armor_check(affecting, MELEE, 0) + var/burn_block = D.run_armor_check(affecting, BOMB, 0) + D.apply_damage(25, BRUTE, selected_zone, brute_block) + D.apply_damage(25, BURN, selected_zone, burn_block) + + var/obj/item/bodypart/affecting_p = A.get_bodypart(BODY_ZONE_CHEST) + var/brute_block_p = A.run_armor_check(affecting_p, MELEE) + var/burn_block_p = A.run_armor_check(affecting_p, BOMB) + A.apply_damage(5, BRUTE, BODY_ZONE_CHEST, brute_block_p) + A.apply_damage(5, BURN, BODY_ZONE_CHEST, burn_block_p) + + D.visible_message(span_danger("[A] headbutts [D]!"), \ + span_userdanger("[A] headbutts you!")) + log_combat(A, D, "headbutts(Explosive Fist)") + streak = "" + else + if(!life_force_trade_active) + return + if(A.grab_state < GRAB_NECK) + A.grab_state = GRAB_NECK + if(!(A.pulling == D)) + D.grabbedby(A, 1) + streak = "" + A.adjust_fire_stacks(3) + D.adjust_fire_stacks(3) + A.IgniteMob() + D.IgniteMob() + proceed_lifeforce_trade(A, D) + +/datum/martial_art/explosive_fist/proc/proceed_lifeforce_trade(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_suck_life(A, D)) + return + if(!do_mob(A, D, 1 SECONDS)) + return + if(!can_suck_life(A, D)) + return + var/message = pick("You feel your life force being drained!", "It hurts!", "You stare into [A]'s expressionless skull and see only fire and death.") + to_chat(D, span_userdanger(message)) + D.emote("scream") + var/dam = 2 + D.adjustFireLoss(dam) + var/bruteloss = D.getBruteLoss() + var/fireloss = D.getFireLoss() + A.heal_overall_damage(bruteloss/2, fireloss/2, 0, required_status, updating_health = TRUE, CONSCIOUS, TRUE) + to_chat(A, span_notice("You drain lifeforce from [D]")) + proceed_lifeforce_trade(A, D) + +/datum/martial_art/explosive_fist/proc/can_suck_life(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_use(A)) + return + if(A.get_item_by_slot(ITEM_SLOT_HEAD)) + return FALSE + if(!A.pulling) + return FALSE + if(!(A.pulling == D)) + return FALSE + if(A.grab_state < GRAB_NECK) + return FALSE + if(A.stat == DEAD || A.stat == UNCONSCIOUS) + return FALSE + if(D.stat == DEAD || D.stat == UNCONSCIOUS) + return FALSE + return TRUE - - \ No newline at end of file From 0e390c5ba99ced83343f742d438e5d72123eb79f Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Thu, 7 Jul 2022 16:20:40 +0300 Subject: [PATCH 63/86] bebra --- yogstation.dme | 1 + .../code/datums/martial/explosive_fist.dm | 130 ++++++++++++++++-- 2 files changed, 121 insertions(+), 10 deletions(-) diff --git a/yogstation.dme b/yogstation.dme index c46e74546070..f8f37f5b9316 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -3344,6 +3344,7 @@ #include "yogstation\code\datums\diseases\advance\symptoms\confusion.dm" #include "yogstation\code\datums\diseases\advance\symptoms\heal.dm" #include "yogstation\code\datums\looping_sounds\darkspawn.dm" +#include "yogstation\code\datums\martial\explosive_fist.dm" #include "yogstation\code\datums\martial\stealth.dm" #include "yogstation\code\datums\mood_events\generic_positive_events.dm" #include "yogstation\code\datums\mutations\alcohol.dm" diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index 66d828d3acc7..a65c15a319c5 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -8,12 +8,15 @@ #define PRE_LIFEFORCE_TRADE_COMBO "DG" #define ALMOST_LIFEFORCE_TRADE_COMBO "DGD" +#define IMMOLATE_COMBO "DHDG" +#define PRE_IMMOLATE_COMBO "DH" +#define ALMOST_IMMOLATE_COMBO "DHD" + /datum/martial_art/explosive_fist name = "Explosive Fist" id = MARTIALART_PRETERNISSTEALTH //help_verb = /mob/living/carbon/human/proc/preternis_martial_help - var/life_force_trade_active = FALSE /datum/martial_art/explosive_fist/can_use(mob/living/carbon/human/H) return isplasmaman(H) @@ -38,7 +41,7 @@ var/brute_block = D.run_armor_check(affecting, MELEE, 0) var/burn_block = D.run_armor_check(affecting, BOMB, 0) A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) + playsound(get_turf(D), 'sound/effects/explosion1.ogg', 50, TRUE, -1) D.apply_damage(10, BRUTE, selected_zone, brute_block) D.apply_damage(10, BURN, selected_zone, burn_block) D.visible_message(span_danger("[A] [A.dna.species.attack_verb]s [D]!"), \ @@ -65,13 +68,14 @@ return TRUE if(findtext(streak, PRE_LIFEFORCE_TRADE_COMBO)) lifeforce_trade(A,D) - return TRUE + if(findtext(streak,PRE_IMMOLATE_COMBO)) + return immolate(A,D) /datum/martial_art/explosive_fist/proc/explosive_disarm(mob/living/carbon/human/A, mob/living/carbon/human/D) var/selected_zone = A.zone_selected var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) var/armor_block = D.run_armor_check(affecting, BOMB, 0) - D.apply_damage(18, BURN, BODY_ZONE_CHEST, armor_block) + D.apply_damage(18, BURN, selected_zone, armor_block) var/obj/item/bodypart/affecting_p = A.get_bodypart(BODY_ZONE_CHEST) // p - plasmamen var/armor_block_p = A.run_armor_check(affecting_p, BOMB) @@ -157,18 +161,120 @@ log_combat(A, D, "headbutts(Explosive Fist)") streak = "" else - if(!life_force_trade_active) - return if(A.grab_state < GRAB_NECK) A.grab_state = GRAB_NECK if(!(A.pulling == D)) D.grabbedby(A, 1) + D.visible_message(span_danger("[A] violently grabs [D]'s neck!"), \ + span_userdanger("[A] violently grabs your neck!")) + log_combat(A, D, "grabs by the neck(Explosive Fist)") + playsound(target, 'sound/weapons/punch.ogg', 50, TRUE, -1) streak = "" A.adjust_fire_stacks(3) D.adjust_fire_stacks(3) A.IgniteMob() D.IgniteMob() - proceed_lifeforce_trade(A, D) + proceed_lifeforce_trade(A, D) + + else if(findtext(streak, ALMOST_LIFEFORCE_TRADE_COMBO)) + A.do_attack_animation(D, ATTACK_EFFECT_DISARM) + playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + + D.visible_message(span_danger("[A] staggers [D]!"), \ + span_userdanger("[A] staggers you!")) + log_combat(A, D, "staggers(Explosive Fist)") + + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) + var/stamina_block = D.run_armor_check(affecting, MELEE, 0) + var/burn_block = D.run_armor_check(affecting, BOMB, 0) + D.apply_damage(20, STAMINA, selected_zone, stamina_block) + D.apply_damage(5, BURN, selected_zone, burn_block) + + if(!D.has_movespeed_modifier(MOVESPEED_ID_SHOVE)) /// We apply a more long shove slowdown if our target doesn't already have one + D.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH) + addtimer(CALLBACK(D, /mob/living/carbon/human/proc/clear_shove_slowdown), 4 SECONDS) + + ADD_TRAIT(D, TRAIT_POOR_AIM, "martial") + addtimer(CALLBACK(src, .proc/remove_stagger, D), 2 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) + else + A.do_attack_animation(D, ATTACK_EFFECT_DISARM) + + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) + var/armor_block = D.run_armor_check(affecting, BOMB, 0) + D.apply_damage(20, BURN, selected_zone, armor_block) + + var/obj/item/bodypart/affecting_p = A.get_bodypart(BODY_ZONE_CHEST) + var/armor_block_p = A.run_armor_check(affecting_p, BOMB) + A.apply_damage(5, BURN, BODY_ZONE_CHEST, armor_block_p) + + D.visible_message(span_danger("[A] burns [D]!"), \ + span_userdanger("[A] burns you!")) + log_combat(A, D, "burns(Explosive Fist)") + +/datum/martial_art/explosive_fist/proc/immolate(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(findtext(streak,IMMOLATE_COMBO)) + if(A.get_item_by_slot(ITEM_SLOT_HEAD)) //No helmets??? + streak = "" + return FALSE + else + for(var/mob/living/target in view_or_range(2, A, "range")) + if(target == A) + continue + if(get_dist(get_turf(A), get_turf(target) =< 1)) + target.IgniteMob() ///If we are close, we ignite, if not - take 30 burn damage + else + target.adjustFireLoss(30) + + var/obj/item/bodypart/hed = D.get_bodypart(BODY_ZONE_HEAD) + var/armor_block = D.run_armor_check(hed, BOMB) + D.apply_damage(10, BURN, BODY_ZONE_HEAD, armor_block) + D.emote("scream") + D.blur_eyes(4) + + var/obj/item/bodypart/affecting_p = A.get_bodypart(BODY_ZONE_CHEST) + var/armor_block_p = A.run_armor_check(affecting_p, BOMB) + A.apply_damage(15, BURN, BODY_ZONE_CHEST, armor_block_p) + + A.visible_message(span_danger("[A] explodes violently!"), \ + span_userdanger("You unleash the flames from yourself!")) + log_combat(A, D, "immolates(Explosive Fist)") + playsound(get_turf(A), 'sound/effects/explosion1.ogg', 50, TRUE, -1) + + else if(findtext(streak,ALMOST_IMMOLATE_COMBO)) + for(var/mob/living/target in view_or_range(2, A, "range")) + target.adjust_fire_stacks(5) + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(A.zone_selected)) + var/burn_block = target.run_armor_check(affecting, BOMB, 0) + var/brute_block = target.run_armor_check(affecting, MELEE, 0) + target.apply_damage(10, BURN, selected_zone, burn_block) + target.apply_damage(5, BRUTE, selected_zone, brute_block) + D.visible_message(span_danger("[A] primes [D]!"), \ + span_userdanger("[A] primes you!")) + log_combat(A, D, "primes(Explosive Fist)") + playsound(get_turf(D), 'sound/effects/explosion1.ogg', 50, TRUE, -1) + + + else + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + playsound(get_turf(D), 'sound/weapons/punch.ogg', 50, 1, -1) + + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) + var/armor_block = D.run_armor_check(affecting, BOMB, 0) + D.apply_damage(25, BURN, selected_zone, armor_block) + + var/obj/item/bodypart/affecting_p = A.get_bodypart(BODY_ZONE_CHEST) // p - plasmamen + var/armor_block_p = A.run_armor_check(affecting_p, BOMB) + A.apply_damage(5, BURN, BODY_ZONE_CHEST, armor_block_p) + + D.visible_message(span_danger("[A] burns [D]!"), \ + span_userdanger("[A] burns you!")) + log_combat(A, D, "burns(Explosive Fist)") + + return TRUE /datum/martial_art/explosive_fist/proc/proceed_lifeforce_trade(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_suck_life(A, D)) @@ -177,9 +283,11 @@ return if(!can_suck_life(A, D)) return - var/message = pick("You feel your life force being drained!", "It hurts!", "You stare into [A]'s expressionless skull and see only fire and death.") - to_chat(D, span_userdanger(message)) - D.emote("scream") + if(prob(35)) + var/message = pick("You feel your life force being drained!", "It hurts!", "You stare into [A]'s expressionless skull and see only fire and death.") + to_chat(D, span_userdanger(message)) + if(prob(25)) + D.emote("scream") var/dam = 2 D.adjustFireLoss(dam) var/bruteloss = D.getBruteLoss() @@ -205,3 +313,5 @@ return FALSE return TRUE +/datum/martial_art/explosive_fist/proc/remove_stagger(mob/living/carbon/human/D) + REMOVE_TRAIT(D, TRAIT_POOR_AIM, "martial") From 5671de1a39cd3c3e1982fb6c22ee75f97293cc19 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Thu, 7 Jul 2022 16:27:36 +0300 Subject: [PATCH 64/86] aboba --- .../code/datums/martial/explosive_fist.dm | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index a65c15a319c5..139e1ce120bb 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -46,7 +46,7 @@ D.apply_damage(10, BURN, selected_zone, burn_block) D.visible_message(span_danger("[A] [A.dna.species.attack_verb]s [D]!"), \ span_userdanger("[A] [A.dna.species.atk_verb]s you!")) - log_combat(A, D, "[A.dna.species.atk_verb]s(Explosive Fist)") + log_combat(A, D, "[A.dna.species.atk_verb]s(Explosive Fist)") /datum/martial_art/explosive_fist/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) @@ -87,7 +87,7 @@ log_combat(A, D, "blasts(Explosive Fist)") D.visible_message(span_danger("[A] blasts [D]!"), \ span_userdanger("[A] blasts you!")) - var/atom/throw_target = get_edge_target_turf(D, dir) + var/atom/throw_target = get_edge_target_turf(D, get_dir(A,D)) D.throw_at(throw_target, rand(1,2), 7, A) streak = "" @@ -97,12 +97,12 @@ log_combat(A, D, "detonates(Explosive Fist)") D.visible_message(span_danger("[A] detonates [D]!"), \ span_userdanger("[A] detonates you!")) - explosion(get_turf(affected_mob), -1, 0, 2, 0, 0, 2) + explosion(get_turf(D), -1, 0, 2, 0, 0, 2) D.IgniteMob() playsound(D, 'sound/effects/explosion1.ogg', 50, TRUE, -1) var/obj/item/bodypart/affecting = A.get_bodypart(BODY_ZONE_CHEST) - var/armor_block = target.run_armor_check(affecting, BOMB) + var/armor_block = A.run_armor_check(affecting, BOMB) A.apply_damage(15, BRUTE, BODY_ZONE_CHEST, armor_block) streak = "" @@ -111,7 +111,7 @@ var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) var/armor_block = D.run_armor_check(affecting, MELEE, 0) A.do_attack_animation(D, ATTACK_EFFECT_DISARM) - playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + playsound(D, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) var/current_stamina_damage = D.getStaminaLoss() var/damage_to_deal = 55 @@ -177,26 +177,26 @@ proceed_lifeforce_trade(A, D) else if(findtext(streak, ALMOST_LIFEFORCE_TRADE_COMBO)) - A.do_attack_animation(D, ATTACK_EFFECT_DISARM) - playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + A.do_attack_animation(D, ATTACK_EFFECT_DISARM) + playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) - D.visible_message(span_danger("[A] staggers [D]!"), \ - span_userdanger("[A] staggers you!")) - log_combat(A, D, "staggers(Explosive Fist)") + D.visible_message(span_danger("[A] staggers [D]!"), \ + span_userdanger("[A] staggers you!")) + log_combat(A, D, "staggers(Explosive Fist)") - var/selected_zone = A.zone_selected - var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) - var/stamina_block = D.run_armor_check(affecting, MELEE, 0) - var/burn_block = D.run_armor_check(affecting, BOMB, 0) - D.apply_damage(20, STAMINA, selected_zone, stamina_block) - D.apply_damage(5, BURN, selected_zone, burn_block) + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) + var/stamina_block = D.run_armor_check(affecting, MELEE, 0) + var/burn_block = D.run_armor_check(affecting, BOMB, 0) + D.apply_damage(20, STAMINA, selected_zone, stamina_block) + D.apply_damage(5, BURN, selected_zone, burn_block) - if(!D.has_movespeed_modifier(MOVESPEED_ID_SHOVE)) /// We apply a more long shove slowdown if our target doesn't already have one - D.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH) - addtimer(CALLBACK(D, /mob/living/carbon/human/proc/clear_shove_slowdown), 4 SECONDS) + if(!D.has_movespeed_modifier(MOVESPEED_ID_SHOVE)) /// We apply a more long shove slowdown if our target doesn't already have one + D.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH) + addtimer(CALLBACK(D, /mob/living/carbon/human/proc/clear_shove_slowdown), 4 SECONDS) - ADD_TRAIT(D, TRAIT_POOR_AIM, "martial") - addtimer(CALLBACK(src, .proc/remove_stagger, D), 2 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) + ADD_TRAIT(D, TRAIT_POOR_AIM, "martial") + addtimer(CALLBACK(src, .proc/remove_stagger, D), 2 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) else A.do_attack_animation(D, ATTACK_EFFECT_DISARM) @@ -222,7 +222,7 @@ for(var/mob/living/target in view_or_range(2, A, "range")) if(target == A) continue - if(get_dist(get_turf(A), get_turf(target) =< 1)) + if(get_dist(get_turf(A), get_turf(target)) =< 1) target.IgniteMob() ///If we are close, we ignite, if not - take 30 burn damage else target.adjustFireLoss(30) @@ -292,7 +292,7 @@ D.adjustFireLoss(dam) var/bruteloss = D.getBruteLoss() var/fireloss = D.getFireLoss() - A.heal_overall_damage(bruteloss/2, fireloss/2, 0, required_status, updating_health = TRUE, CONSCIOUS, TRUE) + A.heal_overall_damage(bruteloss/2, fireloss/2, 0, CONSCIOUS, TRUE) to_chat(A, span_notice("You drain lifeforce from [D]")) proceed_lifeforce_trade(A, D) From 46fe58c2cc463fedaad1bd95a3ab9339f17abfa5 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Thu, 7 Jul 2022 16:31:45 +0300 Subject: [PATCH 65/86] abobrus --- yogstation/code/datums/martial/explosive_fist.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index 139e1ce120bb..55ac6327431f 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -45,8 +45,8 @@ D.apply_damage(10, BRUTE, selected_zone, brute_block) D.apply_damage(10, BURN, selected_zone, burn_block) D.visible_message(span_danger("[A] [A.dna.species.attack_verb]s [D]!"), \ - span_userdanger("[A] [A.dna.species.atk_verb]s you!")) - log_combat(A, D, "[A.dna.species.atk_verb]s(Explosive Fist)") + span_userdanger("[A] [A.dna.species.attack_verb]s you!")) + log_combat(A, D, "[A.dna.species.attack_verb]s(Explosive Fist)") /datum/martial_art/explosive_fist/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) @@ -168,7 +168,7 @@ D.visible_message(span_danger("[A] violently grabs [D]'s neck!"), \ span_userdanger("[A] violently grabs your neck!")) log_combat(A, D, "grabs by the neck(Explosive Fist)") - playsound(target, 'sound/weapons/punch.ogg', 50, TRUE, -1) + playsound(get_turf(D), 'sound/weapons/punch.ogg', 50, TRUE, -1) streak = "" A.adjust_fire_stacks(3) D.adjust_fire_stacks(3) @@ -178,7 +178,7 @@ else if(findtext(streak, ALMOST_LIFEFORCE_TRADE_COMBO)) A.do_attack_animation(D, ATTACK_EFFECT_DISARM) - playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + playsound(get_turf(D), 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) D.visible_message(span_danger("[A] staggers [D]!"), \ span_userdanger("[A] staggers you!")) @@ -222,7 +222,7 @@ for(var/mob/living/target in view_or_range(2, A, "range")) if(target == A) continue - if(get_dist(get_turf(A), get_turf(target)) =< 1) + if(get_dist(get_turf(A), get_turf(target)) <= 1) target.IgniteMob() ///If we are close, we ignite, if not - take 30 burn damage else target.adjustFireLoss(30) From 6f1987f0301fef5623e7288a401f74aa6df19da7 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Thu, 7 Jul 2022 16:36:44 +0300 Subject: [PATCH 66/86] e --- yogstation/code/datums/martial/explosive_fist.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index 55ac6327431f..c47a2ff278a0 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -168,7 +168,7 @@ D.visible_message(span_danger("[A] violently grabs [D]'s neck!"), \ span_userdanger("[A] violently grabs your neck!")) log_combat(A, D, "grabs by the neck(Explosive Fist)") - playsound(get_turf(D), 'sound/weapons/punch.ogg', 50, TRUE, -1) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, TRUE, -1) streak = "" A.adjust_fire_stacks(3) D.adjust_fire_stacks(3) From 8a9f587216b91a68e2f6b5000b6ac658741cfaf3 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Thu, 7 Jul 2022 16:40:47 +0300 Subject: [PATCH 67/86] amon sus --- yogstation/code/datums/martial/explosive_fist.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index c47a2ff278a0..04de9a0cba5a 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -259,7 +259,7 @@ else A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - playsound(get_turf(D), 'sound/weapons/punch.ogg', 50, 1, -1) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) var/selected_zone = A.zone_selected var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) From 9a75443abc39681080d30fe81a1c33702acc28ca Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Thu, 7 Jul 2022 17:17:14 +0300 Subject: [PATCH 68/86] help_verb --- yogstation/code/datums/martial/explosive_fist.dm | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index 04de9a0cba5a..094d900b08fd 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -16,7 +16,7 @@ /datum/martial_art/explosive_fist name = "Explosive Fist" id = MARTIALART_PRETERNISSTEALTH - //help_verb = /mob/living/carbon/human/proc/preternis_martial_help + help_verb = /mob/living/carbon/human/proc/explosive_fist_help /datum/martial_art/explosive_fist/can_use(mob/living/carbon/human/H) return isplasmaman(H) @@ -315,3 +315,16 @@ /datum/martial_art/explosive_fist/proc/remove_stagger(mob/living/carbon/human/D) REMOVE_TRAIT(D, TRAIT_POOR_AIM, "martial") + +/mob/living/carbon/human/proc/explosive_fist_help() + set name = "Remember the basics" + set desc = "You try to remember some basic actions from the explosive fist art." + set category = "Explosive Fist" + to_chat(usr, "You try to remember some basic actions from the explosive fist art.") + + to_chat(usr, span_notice("Harm Intent Will deal 10 burn and 10 brute damage to people who you hit.")) + + to_chat(usr, "[span_notice("Explosive disarm")]: Disarm Disarm. Finishing this combo will deal 10 damage to you and 18 to your target, aswell as throwing your target away and knocking down for three seconds.") + to_chat(usr, "[span_notice("Detonate")]: Harm Harm Disarm Harm. Second strike will deal 12/12 brute/burn and apply 2 fire stacks to the target. Third strike will apply 4 fire stacks and deal some stamina damage if the target has less then 50 stamina damage. The final strike will ignite the target, make a light explosion and deal 15 damage to you.") + to_chat(usr, "[span_notice("Life force trade")]: Disarm Grab Disarm Grab. Second strike will deal 20 damage to the target and 5 damage to you. Third strike will deall 20 stamina and 5 burn damage to the target, and will make it unable to use ranged weapons for 2 second as well as a more long shove slowdown. Finishing the combo with a headwear on will just deal 25/25 brute/burn damage to the target, and if you don't wear a helmet, you will instantly grab the target by a neck, aswell as start to drain life from them.") + to_chat(usr, "[span_notice("Immolate")]: Disarm Disarm. Second strike will deal 25 burn damage to the target and 5 burn damage to you. Third strike will apply 5 fire stacks to EVERYONE in the range of 2 tiles. Finishing the combo will, if you don't wear any headwear, will deal 30 burn damage to anyone except you in the range of 2 tiles, or ignite them if they are close enough to you. You target will get additional 10 burn damage and get blurry vision.") \ No newline at end of file From d5b4768ec9039a3d73f1bafce22e2979295ab565 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Fri, 8 Jul 2022 15:06:39 +0300 Subject: [PATCH 69/86] bebra --- code/__DEFINES/melee.dm | 1 + .../code/datums/martial/explosive_fist.dm | 4 +- .../code/datums/martial/garden_warfare.dm | 56 +++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 yogstation/code/datums/martial/garden_warfare.dm diff --git a/code/__DEFINES/melee.dm b/code/__DEFINES/melee.dm index 972f2638f851..e5cd7d110a3e 100644 --- a/code/__DEFINES/melee.dm +++ b/code/__DEFINES/melee.dm @@ -13,6 +13,7 @@ #define MARTIALART_HUNTERFU "hunterfu" #define MARTIALART_FRENZYGRAB "frenzy grabbing" #define MARTIALART_PRETERNISSTEALTH "preternis stealth" +#define MARTIALART_EXPLOSIVEFIST "explosive fist" //Weapon stat defines diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index 094d900b08fd..ed008ab136bb 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -15,7 +15,7 @@ /datum/martial_art/explosive_fist name = "Explosive Fist" - id = MARTIALART_PRETERNISSTEALTH + id = MARTIALART_EXPLOSIVEFIST help_verb = /mob/living/carbon/human/proc/explosive_fist_help /datum/martial_art/explosive_fist/can_use(mob/living/carbon/human/H) @@ -55,7 +55,7 @@ add_to_streak("D",D) if(check_streak(A,D)) return TRUE - return FALSE ///Same as with harm_act + return FALSE /datum/martial_art/explosive_fist/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm new file mode 100644 index 000000000000..e8bee5bbc6b1 --- /dev/null +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -0,0 +1,56 @@ +#define VINE_SNATCH_COMBO "DD" + +/datum/martial_art/gardern_warfare + name = "Garden Warfare" //I feel like that I deserve a bullet into my head for this names + id = MARTIALART_KRAVMAGA + var/datum/action/vine_snatch/vine_snatch = new/datum/action/vine_snatch() + +/datum/martial_art/gardern_warfare/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_use(A)) + return FALSE + add_to_streak("H",D) + if(check_streak(A,D)) + return TRUE + return FALSE + +/datum/martial_art/gardern_warfare/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!(can_use(A))) + return FALSE + add_to_streak("D",D) + if(check_streak(A,D)) + return TRUE + return FALSE + +/datum/martial_art/gardern_warfare/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) + add_to_streak("G",D) + if(check_streak(A,D)) + return TRUE + return FALSE + else + return FALSE + +/datum/martial_art/gardern_warfare/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_use(A)) + return + if(findtext(streak, VINE_SNATCH_COMBO)) + vine_mark(A,D) + return FALSE + +/datum/martial_art/gardern_warfare/proc/vine_mark(mob/living/carbon/human/A, mob/living/carbon/human/D) + to_chat(A, span_notice("You mark [D] with a vine mark. Using vine snatch now will pull an item from their active hands to you, or knokdown them and pull them to you.")) + to_chat(D, span_danger("[A] marks you!")) + vine_snatch.target = D + vine_snatch.last_time_marked = world.time + streak = "" + +/datum/action/vine_snatch + name = "Vine Snatch - using it while having a target, recently marked with a vine mark in the range of 2 tiles will pull an item in their active hands to you, or pull and knockdown them.." + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "neckchop" + var/mob/living/carbon/human/target = null + var/last_time_marked = 0 + +/datum/action/vine_snatch/New() + . = ..() + last_time_marked = world.time From 58c4e2b7635833381eb307ce2583f0f66d9c7b86 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Fri, 8 Jul 2022 15:26:58 +0300 Subject: [PATCH 70/86] e --- .../code/datums/martial/garden_warfare.dm | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index e8bee5bbc6b1..e7a1ae0eb34c 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -54,3 +54,31 @@ /datum/action/vine_snatch/New() . = ..() last_time_marked = world.time + +/datum/action/vine_snatch/Trigger() + if(owner.incapacitated()) + to_chat(owner, span_warning("You can't use [name] while you're incapacitated.")) + return + if(!target) + to_chat(owner, span_warning("You can't use [name] while not having anyone marked.")) + return + if(world.time < last_time_marked + 3 SECONDS) + to_chat(owner, span_warning("Your mark has expired, you can't use [name].")) + return + if(get_dist(get_turf(owner),get_turf(target)) > 2) + to_chat(owner, span_warning("Your target needs to be in a range of two titles, to be able to use [name].")) + return + to_chat(owner, span_notice("You throw a vine into [target]!")) + var/obj/item/I = target.get_active_held_item() + if(I && HAS_TRAIT(I, TRAIT_NODROP)) + target.visible_message(span_warning("[owner] hits [target] with a vine, pulling [I] out of their hands!"), \ + span_userdanger("[owner] hits you with a vine, pulling [I] out of your hands!")) + if(I && D.temporarilyRemoveItemFromInventory(I)) + D.forceMove(get_turf(owner)) + else + target.throw_at(get_step_towards(owner, target), 7, 2) + target.visible_message(span_warning("[owner] hits [target] with a vine, knocking them down and pulling them to themselfes!"), \ + span_userdanger("[owner] hits you with a vine, pulling you to themselfs!")) + target.Knockdown(3 SECONDS) + target = null + From 651e0c2a58cb5e7acce28137efb39637a090ae7d Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Fri, 8 Jul 2022 15:59:36 +0300 Subject: [PATCH 71/86] vine snatch --- .../code/datums/martial/garden_warfare.dm | 88 ++++++++++++++----- 1 file changed, 67 insertions(+), 21 deletions(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index e7a1ae0eb34c..b797ecdcd7eb 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -1,5 +1,8 @@ #define VINE_SNATCH_COMBO "DD" +#define STRANGLE_COMBO "GGG" +#define PRE_STRANGLE_COMBO "GG" + /datum/martial_art/gardern_warfare name = "Garden Warfare" //I feel like that I deserve a bullet into my head for this names id = MARTIALART_KRAVMAGA @@ -11,7 +14,7 @@ add_to_streak("H",D) if(check_streak(A,D)) return TRUE - return FALSE + return FALSE /datum/martial_art/gardern_warfare/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!(can_use(A))) @@ -36,49 +39,92 @@ if(findtext(streak, VINE_SNATCH_COMBO)) vine_mark(A,D) return FALSE + if(findtext(streak, PRE_STRANGLE_COMBO)) + vine_mark(A,D) + return FALSE ///Zamn /datum/martial_art/gardern_warfare/proc/vine_mark(mob/living/carbon/human/A, mob/living/carbon/human/D) - to_chat(A, span_notice("You mark [D] with a vine mark. Using vine snatch now will pull an item from their active hands to you, or knokdown them and pull them to you.")) - to_chat(D, span_danger("[A] marks you!")) - vine_snatch.target = D - vine_snatch.last_time_marked = world.time - streak = "" + to_chat(A, span_notice("You mark [D] with a vine mark. Using vine snatch now will pull an item from their active hands to you, or knokdown them and pull them to you.")) + to_chat(D, span_danger("[A] marks you!")) + vine_snatch.target = D + vine_snatch.last_time_marked = world.time + streak = "" + +/datum/martial_art/gardern_warfare/proc/strangle(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(findtext(streak, STRANGLE_COMBO)) + streak = "" + ADD_TRAIT(D, TRAIT_MUTE, "martial") + final_strangle(A,D) + else + D.visible_message(span_danger("[A] wraps a vine around [D]'s throat!"), \ + span_userdanger("[A] wraps a vine around your throat!")) + log_combat(A, D, "pre-strangles(Garden Warfare)") + + D.Stun(1 SECONDS) + D.adjustOxyLoss(10) + +/datum/martial_art/gardern_warfare/proc/final_strangle(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_strangle(A, D)) + REMOVE_TRAIT(D, TRAIT_MUTE, "martial") + return + if(!do_mob(A, D, 1 SECONDS)) + REMOVE_TRAIT(D, TRAIT_MUTE, "martial") + return + if(!can_strangle(A, D)) + REMOVE_TRAIT(D, TRAIT_MUTE, "martial") + return + D.adjustOxyLoss(7) + if(prob(35)) + to_chat(D, span_danger("You can't breath!")) + +/datum/martial_art/gardern_warfare/proc/can_strangle(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_use(A)) + return FALSE + if(!A.pulling) + return FALSE + if(!(A.pulling == D)) + return FALSE + if(A.stat == DEAD || A.stat == UNCONSCIOUS) + return FALSE + if(D.stat == DEAD) + return FALSE + return TRUE /datum/action/vine_snatch name = "Vine Snatch - using it while having a target, recently marked with a vine mark in the range of 2 tiles will pull an item in their active hands to you, or pull and knockdown them.." icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "neckchop" - var/mob/living/carbon/human/target = null - var/last_time_marked = 0 + var/mob/living/carbon/human/target = null + var/last_time_marked = 0 /datum/action/vine_snatch/New() - . = ..() - last_time_marked = world.time + . = ..() + last_time_marked = world.time /datum/action/vine_snatch/Trigger() if(owner.incapacitated()) to_chat(owner, span_warning("You can't use [name] while you're incapacitated.")) return - if(!target) + if(!target) to_chat(owner, span_warning("You can't use [name] while not having anyone marked.")) return if(world.time < last_time_marked + 3 SECONDS) - to_chat(owner, span_warning("Your mark has expired, you can't use [name].")) + to_chat(owner, span_warning("Your mark has expired, you can't use [name].")) return if(get_dist(get_turf(owner),get_turf(target)) > 2) - to_chat(owner, span_warning("Your target needs to be in a range of two titles, to be able to use [name].")) + to_chat(owner, span_warning("Your target needs to be in a range of two titles, to be able to use [name].")) return - to_chat(owner, span_notice("You throw a vine into [target]!")) - var/obj/item/I = target.get_active_held_item() - if(I && HAS_TRAIT(I, TRAIT_NODROP)) + to_chat(owner, span_notice("You throw a vine into [target]!")) + var/obj/item/I = target.get_active_held_item() + if(I && HAS_TRAIT(I, TRAIT_NODROP)) target.visible_message(span_warning("[owner] hits [target] with a vine, pulling [I] out of their hands!"), \ span_userdanger("[owner] hits you with a vine, pulling [I] out of your hands!")) if(I && D.temporarilyRemoveItemFromInventory(I)) D.forceMove(get_turf(owner)) - else - target.throw_at(get_step_towards(owner, target), 7, 2) + else + target.throw_at(get_step_towards(owner, target), 7, 2) target.visible_message(span_warning("[owner] hits [target] with a vine, knocking them down and pulling them to themselfes!"), \ span_userdanger("[owner] hits you with a vine, pulling you to themselfs!")) - target.Knockdown(3 SECONDS) - target = null - + target.Knockdown(3 SECONDS) + target = null + From bb7a86bfc9afb5c020690b0c311ca39d5c309ec8 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Sat, 9 Jul 2022 14:55:19 +0300 Subject: [PATCH 72/86] sususus amogus --- yogstation.dme | 1 + .../code/datums/martial/garden_warfare.dm | 52 ++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/yogstation.dme b/yogstation.dme index f8f37f5b9316..ba13d7aa6ee7 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -3345,6 +3345,7 @@ #include "yogstation\code\datums\diseases\advance\symptoms\heal.dm" #include "yogstation\code\datums\looping_sounds\darkspawn.dm" #include "yogstation\code\datums\martial\explosive_fist.dm" +#include "yogstation\code\datums\martial\garden_warfare.dm" #include "yogstation\code\datums\martial\stealth.dm" #include "yogstation\code\datums\mood_events\generic_positive_events.dm" #include "yogstation\code\datums\mutations\alcohol.dm" diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index b797ecdcd7eb..f2eadb6f35ed 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -3,6 +3,9 @@ #define STRANGLE_COMBO "GGG" #define PRE_STRANGLE_COMBO "GG" +#define SPLINTER_COMBO "HHH" +#define PRE_SPLINTER_COMBO "HH" + /datum/martial_art/gardern_warfare name = "Garden Warfare" //I feel like that I deserve a bullet into my head for this names id = MARTIALART_KRAVMAGA @@ -40,8 +43,11 @@ vine_mark(A,D) return FALSE if(findtext(streak, PRE_STRANGLE_COMBO)) - vine_mark(A,D) + strangle(A,D) return FALSE ///Zamn + if(findtext(streak, PRE_SPLINTER_COMBO)) + splinter_stab(A,D) + return TRUE /datum/martial_art/gardern_warfare/proc/vine_mark(mob/living/carbon/human/A, mob/living/carbon/human/D) to_chat(A, span_notice("You mark [D] with a vine mark. Using vine snatch now will pull an item from their active hands to you, or knokdown them and pull them to you.")) @@ -63,6 +69,36 @@ D.Stun(1 SECONDS) D.adjustOxyLoss(10) +/datum/martial_art/gardern_warfare/proc/splinter_stab(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(findtext(streak, SPLINTER_COMBO)) + A.do_attack_animation(D, ATTACK_EFFECT_SLASH) + playsound(get_turf(D), 'sound/weapons/slash.ogg', 50, TRUE, -1) + D.visible_message(span_danger("[A] impales [D]!"), \ + span_userdanger("[A] impales you!")) + log_combat(A, D, "impales(Garden Warfare)") + + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) + var/armor_block = D.run_armor_check(affecting, MELEE, 30) + + D.apply_damage(20, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) + + var/obj/item/splinter = new /obj/item/splinter(D) + D.embed_object(splinter, affecting, FALSE, FALSE, TRUE) + streak = "" + else + A.do_attack_animation(D, ATTACK_EFFECT_SLASH) + playsound(get_turf(D), 'sound/weapons/slash.ogg', 50, TRUE, -1) + D.visible_message(span_danger("[A] stabs [D]!"), \ + span_userdanger("[A] stabs you!")) + log_combat(A, D, "stabs(Garden Warfare)") + + var/selected_zone = A.zone_selected + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) + var/armor_block = D.run_armor_check(affecting, MELEE, 30) + + D.apply_damage(15, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) + /datum/martial_art/gardern_warfare/proc/final_strangle(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_strangle(A, D)) REMOVE_TRAIT(D, TRAIT_MUTE, "martial") @@ -128,3 +164,17 @@ target.Knockdown(3 SECONDS) target = null +/obj/item/splinter + name = "splinter" + desc = "It's sharp!" + throwforce = 3 + sharpness = IS_SHARP + embedding = list("embedded_pain_multiplier" = 3, "embed_chance" = 100, "embedded_fall_chance" = 0) + var/passive_damage = 3 + +/obj/item/splinter/on_embed_removal(mob/living/carbon/human/embedde) + qdel(src) + . = ..() + +/obj/item/splinter/embed_tick(mob/living/carbon/human/embedde, obj/item/bodypart/part) + part.receive_damage(passive_damage, wound_bonus=-30, sharpness = TRUE) \ No newline at end of file From a1184a733b7e18ff397ccb85286a51b99c2dcc3b Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Sat, 9 Jul 2022 15:00:28 +0300 Subject: [PATCH 73/86] e --- .../code/datums/martial/garden_warfare.dm | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index f2eadb6f35ed..47486294bbde 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -52,7 +52,7 @@ /datum/martial_art/gardern_warfare/proc/vine_mark(mob/living/carbon/human/A, mob/living/carbon/human/D) to_chat(A, span_notice("You mark [D] with a vine mark. Using vine snatch now will pull an item from their active hands to you, or knokdown them and pull them to you.")) to_chat(D, span_danger("[A] marks you!")) - vine_snatch.target = D + vine_snatch.marked_dude = D vine_snatch.last_time_marked = world.time streak = "" @@ -130,7 +130,7 @@ name = "Vine Snatch - using it while having a target, recently marked with a vine mark in the range of 2 tiles will pull an item in their active hands to you, or pull and knockdown them.." icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "neckchop" - var/mob/living/carbon/human/target = null + var/mob/living/carbon/human/marked_dude = null var/last_time_marked = 0 /datum/action/vine_snatch/New() @@ -141,28 +141,28 @@ if(owner.incapacitated()) to_chat(owner, span_warning("You can't use [name] while you're incapacitated.")) return - if(!target) + if(!marked_dude) to_chat(owner, span_warning("You can't use [name] while not having anyone marked.")) return if(world.time < last_time_marked + 3 SECONDS) to_chat(owner, span_warning("Your mark has expired, you can't use [name].")) return - if(get_dist(get_turf(owner),get_turf(target)) > 2) + if(get_dist(get_turf(owner),get_turf(marked_dude)) > 2) to_chat(owner, span_warning("Your target needs to be in a range of two titles, to be able to use [name].")) return - to_chat(owner, span_notice("You throw a vine into [target]!")) - var/obj/item/I = target.get_active_held_item() + to_chat(owner, span_notice("You throw a vine into [marked_dude]!")) + var/obj/item/I = marked_dude.get_active_held_item() if(I && HAS_TRAIT(I, TRAIT_NODROP)) - target.visible_message(span_warning("[owner] hits [target] with a vine, pulling [I] out of their hands!"), \ + marked_dude.visible_message(span_warning("[owner] hits [marked_dude] with a vine, pulling [I] out of their hands!"), \ span_userdanger("[owner] hits you with a vine, pulling [I] out of your hands!")) if(I && D.temporarilyRemoveItemFromInventory(I)) D.forceMove(get_turf(owner)) else - target.throw_at(get_step_towards(owner, target), 7, 2) - target.visible_message(span_warning("[owner] hits [target] with a vine, knocking them down and pulling them to themselfes!"), \ + marked_dude.throw_at(get_step_towards(owner, marked_dude), 7, 2) + marked_dude.visible_message(span_warning("[owner] hits [marked_dude] with a vine, knocking them down and pulling them to themselfes!"), \ span_userdanger("[owner] hits you with a vine, pulling you to themselfs!")) - target.Knockdown(3 SECONDS) - target = null + marked_dude.Knockdown(3 SECONDS) + marked_dude = null /obj/item/splinter name = "splinter" From 2571ac6ab0eb06b1b5e3ca4a9d02d59d80888355 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Sat, 9 Jul 2022 15:06:15 +0300 Subject: [PATCH 74/86] wtf --- yogstation/code/datums/martial/garden_warfare.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index 47486294bbde..ad2bfb84d2b1 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -152,7 +152,7 @@ return to_chat(owner, span_notice("You throw a vine into [marked_dude]!")) var/obj/item/I = marked_dude.get_active_held_item() - if(I && HAS_TRAIT(I, TRAIT_NODROP)) + if(I && !HAS_TRAIT(I, TRAIT_NODROP)) marked_dude.visible_message(span_warning("[owner] hits [marked_dude] with a vine, pulling [I] out of their hands!"), \ span_userdanger("[owner] hits you with a vine, pulling [I] out of your hands!")) if(I && D.temporarilyRemoveItemFromInventory(I)) @@ -168,7 +168,7 @@ name = "splinter" desc = "It's sharp!" throwforce = 3 - sharpness = IS_SHARP + sharpness = SHARP_EDGED embedding = list("embedded_pain_multiplier" = 3, "embed_chance" = 100, "embedded_fall_chance" = 0) var/passive_damage = 3 From 9455ce4f2ec8a5b7eacbc4b2b1239357b7a39b7c Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Sat, 9 Jul 2022 15:13:08 +0300 Subject: [PATCH 75/86] D --- yogstation/code/datums/martial/garden_warfare.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index ad2bfb84d2b1..4d1e4b018568 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -155,8 +155,8 @@ if(I && !HAS_TRAIT(I, TRAIT_NODROP)) marked_dude.visible_message(span_warning("[owner] hits [marked_dude] with a vine, pulling [I] out of their hands!"), \ span_userdanger("[owner] hits you with a vine, pulling [I] out of your hands!")) - if(I && D.temporarilyRemoveItemFromInventory(I)) - D.forceMove(get_turf(owner)) + if(I && marked_dude.temporarilyRemoveItemFromInventory(I)) + I.forceMove(get_turf(owner)) else marked_dude.throw_at(get_step_towards(owner, marked_dude), 7, 2) marked_dude.visible_message(span_warning("[owner] hits [marked_dude] with a vine, knocking them down and pulling them to themselfes!"), \ From 4ef734792ac2e40a6c3fa0b3f20a337cd95d3875 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Sat, 9 Jul 2022 15:47:07 +0300 Subject: [PATCH 76/86] help --- code/__DEFINES/melee.dm | 1 + .../code/datums/martial/garden_warfare.dm | 56 ++++++++++++++++++- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/code/__DEFINES/melee.dm b/code/__DEFINES/melee.dm index e5cd7d110a3e..0fa552661fe4 100644 --- a/code/__DEFINES/melee.dm +++ b/code/__DEFINES/melee.dm @@ -14,6 +14,7 @@ #define MARTIALART_FRENZYGRAB "frenzy grabbing" #define MARTIALART_PRETERNISSTEALTH "preternis stealth" #define MARTIALART_EXPLOSIVEFIST "explosive fist" +#define MARTIALART_GARDENWARFARE "garden warfare" //Weapon stat defines diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index 4d1e4b018568..ddc4b3006511 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -8,9 +8,23 @@ /datum/martial_art/gardern_warfare name = "Garden Warfare" //I feel like that I deserve a bullet into my head for this names - id = MARTIALART_KRAVMAGA + id = MARTIALART_GARDENWARFARE + block_chance = 50 + help_verb = /mob/living/carbon/human/proc/gardern_warfare_help var/datum/action/vine_snatch/vine_snatch = new/datum/action/vine_snatch() +/datum/martial_art/gardern_warfare/can_use(mob/living/carbon/human/H) + return ispodperson(H) + +/datum/martial_art/krav_maga/teach(mob/living/carbon/human/H,make_temporary=0) + if(..()) + vine_snatch.Grant(H) + H.dna.species.speedmod = 0 + +/datum/martial_art/krav_maga/on_remove(mob/living/carbon/human/H) + vine_snatch.Remove(H) + H.dna.species.speedmod = initial(H.dna.species.speedmod) + /datum/martial_art/gardern_warfare/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) return FALSE @@ -100,6 +114,7 @@ D.apply_damage(15, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) /datum/martial_art/gardern_warfare/proc/final_strangle(mob/living/carbon/human/A, mob/living/carbon/human/D) + block_chance = initial(block_chance) if(!can_strangle(A, D)) REMOVE_TRAIT(D, TRAIT_MUTE, "martial") return @@ -109,9 +124,11 @@ if(!can_strangle(A, D)) REMOVE_TRAIT(D, TRAIT_MUTE, "martial") return - D.adjustOxyLoss(7) + block_chance = 25 + D.adjustOxyLoss(10) if(prob(35)) to_chat(D, span_danger("You can't breath!")) + final_strangle(A,D) /datum/martial_art/gardern_warfare/proc/can_strangle(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) @@ -177,4 +194,37 @@ . = ..() /obj/item/splinter/embed_tick(mob/living/carbon/human/embedde, obj/item/bodypart/part) - part.receive_damage(passive_damage, wound_bonus=-30, sharpness = TRUE) \ No newline at end of file + part.receive_damage(passive_damage, wound_bonus=-30, sharpness = TRUE) + +/datum/martial_art/gardern_warfare/handle_counter(mob/living/carbon/human/user, mob/living/carbon/human/attacker) + if(!can_use(user)) + return + if(!in_throw_mode) + return + user.do_attack_animation(attacker, ATTACK_EFFECT_SLASH) + playsound(get_turf(attacker), 'sound/weapons/slash.ogg', 50, TRUE, -1) + attacker.visible_message(span_danger("[user] stabs [attacker]!"), \ + span_userdanger("[user] stabs you!")) + log_combat(user, attacker, "counterattacks(Garden Warfare)") + + var/selected_zone = user.zone_selected + var/obj/item/bodypart/affecting = attacker.get_bodypart(ran_zone(selected_zone)) + var/armor_block = attacker.run_armor_check(affecting, MELEE, 0) + + attacker.apply_damage(10, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) + + var/obj/item/splinter = new /obj/item/splinter(attacker) + attacker.embed_object(splinter, affecting, FALSE, FALSE, TRUE) + streak = "" + +/mob/living/carbon/human/proc/gardern_warfare_help() + set name = "Remember the basics" + set desc = "You try to remember some basic actions from the garden warfare art." + set category = "Garden Warfare" + to_chat(usr, "You try to remember some basic actions from the garden warfare art.") + + to_chat(usr, "[span_notice("Vine snatch")]: Disarm Disarm. Finishning this combo will mark the victim with a vine mark, allowing you to drag them or an item in their active hand by using ["Vine Snatch"] ability. The mark lasts only 3 seconds.") + to_chat(usr, "[span_notice("Strangle")]: Grab Grab Grab. The second grab will deal 10 oxyloss damage to the target, and finishing the combo will upgrade your grab, making it mute the target and deal 10 oxyloss damage per second.") + to_chat(usr, "[span_notice("Splinter stab")]: Harm harm Harm. The second attack will deal increased damage with 30 armor penetration, and finishing the combo will deal 20 damage with 30 armor penetration, while also embedding a splinter into the targets limb.") + + to_chat(usr, span_notice("Additionaly, you have a passive 50% block chance(25% if strangling someone), and having throw mode on will allow you to counterattack attackers, dealing them 10 damage and embedding a splinter into them.")) \ No newline at end of file From 2f77e1618ac068c3d77fad5608b60c9f674af346 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Sat, 9 Jul 2022 15:51:17 +0300 Subject: [PATCH 77/86] amongus --- yogstation/code/datums/martial/garden_warfare.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index ddc4b3006511..9430d4d155ff 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -199,7 +199,7 @@ /datum/martial_art/gardern_warfare/handle_counter(mob/living/carbon/human/user, mob/living/carbon/human/attacker) if(!can_use(user)) return - if(!in_throw_mode) + if(!user.in_throw_mode) return user.do_attack_animation(attacker, ATTACK_EFFECT_SLASH) playsound(get_turf(attacker), 'sound/weapons/slash.ogg', 50, TRUE, -1) From cce92ca33a17849274e33541bc67279c43fb78ab Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Mon, 11 Jul 2022 14:17:53 +0300 Subject: [PATCH 78/86] granters --- code/game/objects/items/granters.dm | 66 +++++++++++++++++++ yogstation/code/modules/uplink/uplink_item.dm | 21 ++++++ 2 files changed, 87 insertions(+) diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index e3575748d999..4301b3f3d10a 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -419,6 +419,72 @@ name = "empty scroll" icon_state = "blankscroll" +/obj/item/book/granter/martial/preternis_stealth + martial = /datum/martial_art/stealth + name = "strange electronic board" + martialname = "Stealth" + desc = "A strange electronic board, containing some sort of software." + greet = "You have uploaded some combat modules into yourself. Your combos will now have special effects on your enemies, and mostly are not obvious to other people. \ + You can check what combos can you do, and their effect by using Refresh Data verb in Combat Modules tab." + icon = 'icons/obj/module.dmi' + icon_state = "cyborg_upgrade" + remarks = list("Processing data...") + +/obj/item/book/granter/martial/preternis_stealth/already_known(mob/user) + if(!ispreternis(user)) + to_chat(user, span_warning("You don't understand what to do with this strange electronic device.")) + return TRUE + return ..() + +/obj/item/book/granter/martial/preternis_stealth/onlearned(mob/living/carbon/user) + ..() + if(oneuse == TRUE) + desc = "It looks like it doesn't contain any data no more." + +/obj/item/book/granter/martial/garden_warfare + martial = /datum/martial_art/gardern_warfare + name = "mysterious scroll" + martialname = "Garden Warfare" + desc = "A scroll, filled with a tone of text. Looks like it says something about combat and... plants?" + greet = "You know the martial art of Garden Warfare! Now you control your body better, then other phytosians do, allowing you to extend vines from your body and impale people with splinters. \ + You can check what combos can you do, and their effect by using Remember the basics verb in Garden Warfare tab." + icon = 'icons/obj/wizard.dmi' + icon_state = "scroll2" + remarks = list("I didn't know that my body grows sprinklers...", "I am able to snatch people with vines? Interesting.", "Wow, strangling people is brutal.") ///Kill me please for this cringe + +/obj/item/book/granter/martial/garden_warfare/already_known(mob/user) + if(!ispodperson(user)) + to_chat(user, span_warning("You see that this scroll says something about natural abilitites of podpeople, but, unfortunately, you are not one of them.")) + return TRUE + return ..() + +/obj/item/book/granter/martial/garden_warfare/onlearned(mob/living/carbon/user) + ..() + if(oneuse == TRUE) + desc = "It's completely blank." + +/obj/item/book/granter/martial/explosive_fist + martial = /datum/martial_art/explosive_fist + name = "burnt scroll" + martialname = "Explosive Fist" + desc = "A burnt scroll, that glorifies plasmamen, and also says a lot things of explosions." + greet = "You know the martial art of Explosive Fist. Now your attacks deal brute and burn damage, while your combos are able to set people on fire, explode them, or all at once. \ + You can check what combos can you do, and their effect by using Remember the basics verb in Explosive Fist tab." + icon = 'icons/obj/wizard.dmi' + icon_state = "scroll2" + remarks = list("Set them on fire...", "Show the punny humans who is here the supreme race...", "Make them burn...", "Explosion are cool!") + +/obj/item/book/granter/martial/explosive_fist/already_known(mob/user) + if(!ispodperson(user)) + to_chat(user, span_warning("It says about very dangerous things, that you would prefer not to know.")) + return TRUE + return ..() + +/obj/item/book/granter/martial/explosive_fist/onlearned(mob/living/carbon/user) + ..() + if(oneuse == TRUE) + desc = "It's completely blank." + // I did not include mushpunch's grant, it is not a book and the item does it just fine. diff --git a/yogstation/code/modules/uplink/uplink_item.dm b/yogstation/code/modules/uplink/uplink_item.dm index d4a551810113..dc3a7fe41c5c 100644 --- a/yogstation/code/modules/uplink/uplink_item.dm +++ b/yogstation/code/modules/uplink/uplink_item.dm @@ -143,3 +143,24 @@ item = /obj/item/melee/fryingpan/bananium cost = 40 cant_discount = TRUE + +/datum/uplink_item/race_restricted/garden_warfare + name = "Martial art scroll" + desc = "A special scroll with a martial art, that teaches phytosians of capabilities of their body." + cost = 13 + item = /obj/item/book/granter/martial/garden_warfare + restricted_species = list("pod") + +/datum/uplink_item/race_restricted/combat_modules + name = "Combat Modules Board" + desc = "An upgrade board, containing upgrades and programs for your melee attacks." + cost = 11 + item = /obj/item/book/granter/martial/preternis_stealth + restricted_species = list("preternis") + +/datum/uplink_item/race_restricted/explosive_fist_art + name = "Burned scroll" + desc = "An ancient scroll, containing a guide to an ancient plasmamen martial art." + cost = 14 + item = /obj/item/book/granter/martial/explosive_fist + restricted_species = list("plasmaman") \ No newline at end of file From 6ad3320b3f6476eee3ed62fd12965d8163ca93b9 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com> Date: Mon, 11 Jul 2022 14:22:03 +0300 Subject: [PATCH 79/86] fix --- yogstation/code/datums/martial/garden_warfare.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index 9430d4d155ff..52cb42a1ce6a 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -16,12 +16,12 @@ /datum/martial_art/gardern_warfare/can_use(mob/living/carbon/human/H) return ispodperson(H) -/datum/martial_art/krav_maga/teach(mob/living/carbon/human/H,make_temporary=0) +/datum/martial_art/gardern_warfare/teach(mob/living/carbon/human/H,make_temporary=0) if(..()) vine_snatch.Grant(H) H.dna.species.speedmod = 0 -/datum/martial_art/krav_maga/on_remove(mob/living/carbon/human/H) +/datum/martial_art/gardern_warfare/on_remove(mob/living/carbon/human/H) vine_snatch.Remove(H) H.dna.species.speedmod = initial(H.dna.species.speedmod) From c22302dab5dbb476d84bb40fa4b54b283bbffc14 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+SuperSlayer0@users.noreply.github.com> Date: Wed, 20 Jul 2022 20:43:13 +0300 Subject: [PATCH 80/86] Update garden_warfare.dm --- yogstation/code/datums/martial/garden_warfare.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index 52cb42a1ce6a..fd7a88361cda 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -145,8 +145,8 @@ /datum/action/vine_snatch name = "Vine Snatch - using it while having a target, recently marked with a vine mark in the range of 2 tiles will pull an item in their active hands to you, or pull and knockdown them.." - icon_icon = 'icons/mob/actions/actions_items.dmi' - button_icon_state = "neckchop" + icon_icon = 'icons/obj/changeling.dmi' + button_icon_state = "tentacle" var/mob/living/carbon/human/marked_dude = null var/last_time_marked = 0 @@ -227,4 +227,4 @@ to_chat(usr, "[span_notice("Strangle")]: Grab Grab Grab. The second grab will deal 10 oxyloss damage to the target, and finishing the combo will upgrade your grab, making it mute the target and deal 10 oxyloss damage per second.") to_chat(usr, "[span_notice("Splinter stab")]: Harm harm Harm. The second attack will deal increased damage with 30 armor penetration, and finishing the combo will deal 20 damage with 30 armor penetration, while also embedding a splinter into the targets limb.") - to_chat(usr, span_notice("Additionaly, you have a passive 50% block chance(25% if strangling someone), and having throw mode on will allow you to counterattack attackers, dealing them 10 damage and embedding a splinter into them.")) \ No newline at end of file + to_chat(usr, span_notice("Additionaly, you have a passive 50% block chance(25% if strangling someone), and having throw mode on will allow you to counterattack attackers, dealing them 10 damage and embedding a splinter into them.")) From b25ebc3335276e7cf606190c9fae87fc331b54b7 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+SuperSlayer0@users.noreply.github.com> Date: Mon, 29 Aug 2022 14:47:42 +0300 Subject: [PATCH 81/86] fixed some bugs --- .../code/datums/martial/garden_warfare.dm | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index fd7a88361cda..e64147fa2fea 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -11,7 +11,8 @@ id = MARTIALART_GARDENWARFARE block_chance = 50 help_verb = /mob/living/carbon/human/proc/gardern_warfare_help - var/datum/action/vine_snatch/vine_snatch = new/datum/action/vine_snatch() + var/datum/action/vine_snatch/vine_snatch = new /datum/action/vine_snatch() + var/current_combo /datum/martial_art/gardern_warfare/can_use(mob/living/carbon/human/H) return ispodperson(H) @@ -28,6 +29,8 @@ /datum/martial_art/gardern_warfare/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) return FALSE + if(current_combo && current_combo != SPLINTER_COMBO) + streak = "" add_to_streak("H",D) if(check_streak(A,D)) return TRUE @@ -36,6 +39,8 @@ /datum/martial_art/gardern_warfare/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!(can_use(A))) return FALSE + if(current_combo && current_combo != VINE_SNATCH_COMBO) + streak = "" add_to_streak("D",D) if(check_streak(A,D)) return TRUE @@ -43,23 +48,26 @@ /datum/martial_art/gardern_warfare/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) + if(current_combo && current_combo != STRANGLE_COMBO) + streak = "" add_to_streak("G",D) if(check_streak(A,D)) return TRUE - return FALSE - else - return FALSE + return FALSE /datum/martial_art/gardern_warfare/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) return if(findtext(streak, VINE_SNATCH_COMBO)) + current_combo = VINE_SNATCH_COMBO vine_mark(A,D) return FALSE if(findtext(streak, PRE_STRANGLE_COMBO)) + current_combo = STRANGLE_COMBO strangle(A,D) return FALSE ///Zamn if(findtext(streak, PRE_SPLINTER_COMBO)) + current_combo = SPLINTER_COMBO splinter_stab(A,D) return TRUE @@ -74,7 +82,11 @@ if(findtext(streak, STRANGLE_COMBO)) streak = "" ADD_TRAIT(D, TRAIT_MUTE, "martial") + block_chance = 25 final_strangle(A,D) + block_chance = initial(block_chance) + REMOVE_TRAIT(D, TRAIT_MUTE, "martial") + streak = "" else D.visible_message(span_danger("[A] wraps a vine around [D]'s throat!"), \ span_userdanger("[A] wraps a vine around your throat!")) @@ -95,7 +107,17 @@ var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) var/armor_block = D.run_armor_check(affecting, MELEE, 30) - D.apply_damage(20, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) + D.apply_damage(20, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) + + var/list/arms = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) + var/arm_zone = pick(arms) + arms -= arm_zone + var/obj/item/bodypart/affecting_arm = A.get_bodypart(ran_zone(arm_zone)) + if(!affecting_arm) + affecting_arm = A.get_bodypart(ran_zone(pick(arms))) + var/arm_armor_block = A.run_armor_check(affecting_arm, MELEE, 5) + + A.apply_damage(5, BRUTE, arm_zone, arm_armor_block) var/obj/item/splinter = new /obj/item/splinter(D) D.embed_object(splinter, affecting, FALSE, FALSE, TRUE) @@ -114,17 +136,12 @@ D.apply_damage(15, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) /datum/martial_art/gardern_warfare/proc/final_strangle(mob/living/carbon/human/A, mob/living/carbon/human/D) - block_chance = initial(block_chance) if(!can_strangle(A, D)) - REMOVE_TRAIT(D, TRAIT_MUTE, "martial") return if(!do_mob(A, D, 1 SECONDS)) - REMOVE_TRAIT(D, TRAIT_MUTE, "martial") return if(!can_strangle(A, D)) - REMOVE_TRAIT(D, TRAIT_MUTE, "martial") return - block_chance = 25 D.adjustOxyLoss(10) if(prob(35)) to_chat(D, span_danger("You can't breath!")) @@ -161,7 +178,7 @@ if(!marked_dude) to_chat(owner, span_warning("You can't use [name] while not having anyone marked.")) return - if(world.time < last_time_marked + 3 SECONDS) + if(world.time > last_time_marked + 3 SECONDS) to_chat(owner, span_warning("Your mark has expired, you can't use [name].")) return if(get_dist(get_turf(owner),get_turf(marked_dude)) > 2) From f7b9f4be93727ac46f5f1854f6146f602a5b5c22 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+SuperSlayer0@users.noreply.github.com> Date: Mon, 29 Aug 2022 14:49:46 +0300 Subject: [PATCH 82/86] vine throw now actually throws a vine --- yogstation/code/datums/martial/garden_warfare.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index e64147fa2fea..b2a083e7a921 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -166,6 +166,7 @@ button_icon_state = "tentacle" var/mob/living/carbon/human/marked_dude = null var/last_time_marked = 0 + var/range = 2 /datum/action/vine_snatch/New() . = ..() @@ -181,10 +182,11 @@ if(world.time > last_time_marked + 3 SECONDS) to_chat(owner, span_warning("Your mark has expired, you can't use [name].")) return - if(get_dist(get_turf(owner),get_turf(marked_dude)) > 2) - to_chat(owner, span_warning("Your target needs to be in a range of two titles, to be able to use [name].")) + if(get_dist(get_turf(owner),get_turf(marked_dude)) > range) + to_chat(owner, span_warning("Your target needs to be in a range of [range] titles, to be able to use [name].")) return to_chat(owner, span_notice("You throw a vine into [marked_dude]!")) + owner.Beam(marked_dude, "vine", time= 10, maxdistance = range) var/obj/item/I = marked_dude.get_active_held_item() if(I && !HAS_TRAIT(I, TRAIT_NODROP)) marked_dude.visible_message(span_warning("[owner] hits [marked_dude] with a vine, pulling [I] out of their hands!"), \ From 5f3153a15d5e5cb2b8682c2899c2d985f698dcf1 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+SuperSlayer0@users.noreply.github.com> Date: Mon, 29 Aug 2022 14:57:49 +0300 Subject: [PATCH 83/86] Sex --- code/game/objects/items/granters.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 4301b3f3d10a..5c3190d74e3e 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -475,7 +475,7 @@ remarks = list("Set them on fire...", "Show the punny humans who is here the supreme race...", "Make them burn...", "Explosion are cool!") /obj/item/book/granter/martial/explosive_fist/already_known(mob/user) - if(!ispodperson(user)) + if(!isplasmaman(user)) to_chat(user, span_warning("It says about very dangerous things, that you would prefer not to know.")) return TRUE return ..() From 86b11bad6f91f28627f92e509515a25dca706028 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+SuperSlayer0@users.noreply.github.com> Date: Mon, 29 Aug 2022 15:09:04 +0300 Subject: [PATCH 84/86] preternis gun --- yogstation/code/datums/martial/garden_warfare.dm | 5 +++-- yogstation/code/datums/martial/stealth.dm | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index b2a083e7a921..25f3008f2c9b 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -107,7 +107,8 @@ var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) var/armor_block = D.run_armor_check(affecting, MELEE, 30) - D.apply_damage(20, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) + D.apply_damage(20, BRUTE, selected_zone, armor_block, sharpness = SHARP_POINTY) + D.Stun(1 SECONDS) var/list/arms = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) var/arm_zone = pick(arms) @@ -133,7 +134,7 @@ var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(selected_zone)) var/armor_block = D.run_armor_check(affecting, MELEE, 30) - D.apply_damage(15, BRUTE, selected_zone, armor_block, sharpness = SHARP_EDGED) + D.apply_damage(15, BRUTE, selected_zone, armor_block, sharpness = SHARP_POINTY) /datum/martial_art/gardern_warfare/proc/final_strangle(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_strangle(A, D)) diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index 1aa00439ec1d..162a1b9fce1f 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -97,6 +97,7 @@ fire_sound_volume = 30 lefthand_file = null ///We don't want it to be visible inhands righthand_file = null + mag_type = /obj/item/ammo_box/magazine/m10mm/martial var/mob/gun_owner var/dying = FALSE @@ -119,7 +120,7 @@ /obj/item/gun/ballistic/automatic/pistol/martial/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) if(!dying) - addtimer(CALLBACK(src, .proc/process_burst), 2 SECONDS) ///I, kinda, don't very understand what gun code does, but it seems to be OK. + addtimer(CALLBACK(src, .proc/process_burst), 1 SECONDS) ///I, kinda, don't very understand what gun code does, but it seems to be OK. dying = TRUE . = ..() @@ -127,6 +128,9 @@ to_chat(gun_owner, span_warning("You hide [src].")) qdel(src) +/obj/item/ammo_box/magazine/m10mm/martial + max_ammo = 1 + /mob/living/carbon/human/proc/preternis_martial_help() set name = "Refresh Data" set desc = "You try to remember some basic actions from your upgraded combat modules." From 6c4dde959a716a387610af40c379fa48d59fa578 Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+SuperSlayer0@users.noreply.github.com> Date: Tue, 30 Aug 2022 09:03:53 +0300 Subject: [PATCH 85/86] Update garden_warfare.dm --- yogstation/code/datums/martial/garden_warfare.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index 25f3008f2c9b..2152bc28cb47 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -30,6 +30,7 @@ if(!can_use(A)) return FALSE if(current_combo && current_combo != SPLINTER_COMBO) + current_combo = null streak = "" add_to_streak("H",D) if(check_streak(A,D)) @@ -40,6 +41,7 @@ if(!(can_use(A))) return FALSE if(current_combo && current_combo != VINE_SNATCH_COMBO) + current_combo = null streak = "" add_to_streak("D",D) if(check_streak(A,D)) @@ -49,6 +51,7 @@ /datum/martial_art/gardern_warfare/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) if(current_combo && current_combo != STRANGLE_COMBO) + current_combo = null streak = "" add_to_streak("G",D) if(check_streak(A,D)) From dae2c7b1b0b7cac1a5088514371a570e74a6bc2e Mon Sep 17 00:00:00 2001 From: SuperSlayer <91609255+SuperSlayer0@users.noreply.github.com> Date: Thu, 8 Sep 2022 14:27:21 +0300 Subject: [PATCH 86/86] Update garden_warfare.dm --- yogstation/code/datums/martial/garden_warfare.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index 2152bc28cb47..ef1061d2796f 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -246,7 +246,7 @@ set category = "Garden Warfare" to_chat(usr, "You try to remember some basic actions from the garden warfare art.") - to_chat(usr, "[span_notice("Vine snatch")]: Disarm Disarm. Finishning this combo will mark the victim with a vine mark, allowing you to drag them or an item in their active hand by using ["Vine Snatch"] ability. The mark lasts only 3 seconds.") + to_chat(usr, "[span_notice("Vine snatch")]: Disarm Disarm. Finishing this combo will mark the victim with a vine mark, allowing you to drag them or an item in their active hand by using ["Vine Snatch"] ability. The mark lasts only 3 seconds.") to_chat(usr, "[span_notice("Strangle")]: Grab Grab Grab. The second grab will deal 10 oxyloss damage to the target, and finishing the combo will upgrade your grab, making it mute the target and deal 10 oxyloss damage per second.") to_chat(usr, "[span_notice("Splinter stab")]: Harm harm Harm. The second attack will deal increased damage with 30 armor penetration, and finishing the combo will deal 20 damage with 30 armor penetration, while also embedding a splinter into the targets limb.")