mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
Moves revolution code of out of flash code, fixes April Fool conversion forcesay never working in any cirumstances (#74411)
## About The Pull Request
- Signallizes head revolutionary flash conversion code, moving it out of
core flash code.
- Removes "tacticool" flashing from head revs, but they can still
convert from any direction
- Fixes April Fools "You son of a bitch! I'm in" force say never
working.
- Revs are muted on conversion so they couldn't talk.
- Fixed by only muting revs on non-holidays
- Cultists are unconscious on conversion so they couldn't talk
- Fixed by only unconscious-ing cultists on non-holidays
- Brainwash victims are more often than not unconscious / asleep so they
couldn't talk
- Just left this one.
- Reduced the chance of them occurring and limits it to April Fools only
- A 1% chance of the force says ocurring means they will happen pretty
much once a week, given multiple rev / cult rounds happen every week and
on average like, 20 people are converted. A little absurd, it's good
that it never worked?
## Why It's Good For The Game
Antag code in core item code is bad
It's funny this meme has existed for like 2, 3 years now? No one's
tested it, it's never worked
## Changelog
🆑 Melbert
refactor: Removes Rev code from core flash code
fix: Getting converted on April Fools now triggers the meme force say as
always intended
del: The meme force say can no longer trigger on any day (it didn't work
before anyways)
/🆑
This commit is contained in:
@@ -172,6 +172,16 @@
|
||||
|
||||
///from living/flash_act(), when a mob is successfully flashed.
|
||||
#define COMSIG_MOB_FLASHED "mob_flashed"
|
||||
/// from /obj/item/assembly/flash/flash_carbon, to the mob flashing another carbon
|
||||
#define COMSIG_MOB_FLASHED_CARBON "mob_flashed_carbon"
|
||||
/// Return to override deviation to be full deviation (fail the flash, usually)
|
||||
#define DEVIATION_OVERRIDE_FULL (1<<0)
|
||||
/// Return to override deviation to be partial deviation
|
||||
#define DEVIATION_OVERRIDE_PARTIAL (1<<1)
|
||||
/// Return to override deviation to be no deviation
|
||||
#define DEVIATION_OVERRIDE_NONE (1<<2)
|
||||
/// Return to stop the flash entirely
|
||||
#define STOP_FLASH (1<<3)
|
||||
|
||||
/// from mob/get_status_tab_items(): (list/items)
|
||||
#define COMSIG_MOB_GET_STATUS_TAB_ITEMS "mob_get_status_tab_items"
|
||||
|
||||
@@ -880,6 +880,14 @@ GLOBAL_LIST_INIT(layers_to_offset, list(
|
||||
#define READING_CHECK_LITERACY (1<<0)
|
||||
#define READING_CHECK_LIGHT (1<<1)
|
||||
|
||||
// Flash deviation defines
|
||||
/// No deviation at all. Flashed from the front or front-left/front-right. Alternatively, flashed in direct view.
|
||||
#define DEVIATION_NONE 0
|
||||
/// Partial deviation. Flashed from the side. Alternatively, flashed out the corner of your eyes.
|
||||
#define DEVIATION_PARTIAL 1
|
||||
/// Full deviation. Flashed from directly behind or behind-left/behind-rack. Not flashed at all.
|
||||
#define DEVIATION_FULL 2
|
||||
|
||||
/// In dynamic human icon gen we don't replace the held item.
|
||||
#define NO_REPLACE 0
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
|
||||
else if(IS_REVOLUTIONARY(creator))
|
||||
var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE)
|
||||
converter.add_revolutionary(src,FALSE)
|
||||
converter.add_revolutionary(src, stun = FALSE, mute = FALSE)
|
||||
|
||||
else if(IS_NUKE_OP(creator))
|
||||
var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
var/end_message = "."
|
||||
var/rendered = begin_message + obj_message + end_message
|
||||
deadchat_broadcast(rendered, "<b>[L]</b>", follow_target = L, turf_target = get_turf(L), message_type=DEADCHAT_ANNOUNCEMENT)
|
||||
if(prob(1) || check_holidays(APRIL_FOOLS))
|
||||
L.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in.")
|
||||
if(check_holidays(APRIL_FOOLS))
|
||||
// Note: most of the time you're getting brainwashed you're unconscious
|
||||
L.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in. (April Fools)")
|
||||
|
||||
/datum/antagonist/brainwashed
|
||||
name = "\improper Brainwashed Victim"
|
||||
|
||||
@@ -262,30 +262,45 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
to_chat(M, span_warning("Something is shielding [convertee]'s mind!"))
|
||||
log_game("Offer rune with [convertee] on it failed - convertee had anti-magic.")
|
||||
return FALSE
|
||||
|
||||
var/brutedamage = convertee.getBruteLoss()
|
||||
var/burndamage = convertee.getFireLoss()
|
||||
if(brutedamage || burndamage)
|
||||
convertee.adjustBruteLoss(-(brutedamage * 0.75))
|
||||
convertee.adjustFireLoss(-(burndamage * 0.75))
|
||||
convertee.visible_message("<span class='warning'>[convertee] writhes in pain \
|
||||
[brutedamage || burndamage ? "even as [convertee.p_their()] wounds heal and close" : "as the markings below [convertee.p_them()] glow a bloody red"]!</span>", \
|
||||
span_cultlarge("<i>AAAAAAAAAAAAAA-</i>"))
|
||||
convertee.mind?.add_antag_datum(/datum/antagonist/cult)
|
||||
convertee.Unconscious(100)
|
||||
|
||||
convertee.visible_message(
|
||||
span_warning("[convertee] writhes in pain [(brutedamage || burndamage) \
|
||||
? "even as [convertee.p_their()] wounds heal and close" \
|
||||
: "as the markings below [convertee.p_them()] glow a bloody red"]!"),
|
||||
span_cultlarge("<i>AAAAAAAAAAAAAA-</i>"),
|
||||
)
|
||||
|
||||
// We're not guaranteed to be a human but we'll cast here since we use it in a few branches
|
||||
var/mob/living/carbon/human/human_convertee = convertee
|
||||
|
||||
if(check_holidays(APRIL_FOOLS) && prob(10))
|
||||
convertee.Paralyze(10 SECONDS)
|
||||
if(istype(human_convertee))
|
||||
human_convertee.force_say()
|
||||
convertee.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in. (April Fools)")
|
||||
|
||||
else
|
||||
convertee.Unconscious(10 SECONDS)
|
||||
|
||||
new /obj/item/melee/cultblade/dagger(get_turf(src))
|
||||
convertee.mind.special_role = ROLE_CULTIST
|
||||
to_chat(convertee, "<span class='cult italic'><b>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \
|
||||
and something evil takes root.</b></span>")
|
||||
to_chat(convertee, "<span class='cult italic'><b>Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve the Geometer above all else. Bring it back.\
|
||||
</b></span>")
|
||||
if(ishuman(convertee))
|
||||
var/mob/living/carbon/human/H = convertee
|
||||
H.uncuff()
|
||||
H.remove_status_effect(/datum/status_effect/speech/slurring/cult)
|
||||
H.remove_status_effect(/datum/status_effect/speech/stutter)
|
||||
|
||||
if(prob(1) || check_holidays(APRIL_FOOLS))
|
||||
H.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in.")
|
||||
to_chat(convertee, span_cultitalic("<b>Your blood pulses. Your head throbs. The world goes red. \
|
||||
All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \
|
||||
and something evil takes root.</b>"))
|
||||
to_chat(convertee, span_cultitalic("<b>Assist your new compatriots in their dark dealings. \
|
||||
Your goal is theirs, and theirs is yours. You serve the Geometer above all else. Bring it back.</b>"))
|
||||
|
||||
if(istype(human_convertee))
|
||||
human_convertee.uncuff()
|
||||
human_convertee.remove_status_effect(/datum/status_effect/speech/slurring/cult)
|
||||
human_convertee.remove_status_effect(/datum/status_effect/speech/stutter)
|
||||
if(isshade(convertee))
|
||||
convertee.icon_state = "shade_cult"
|
||||
convertee.name = convertee.real_name
|
||||
|
||||
@@ -184,6 +184,51 @@
|
||||
S.Remove(C)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/rev/head/apply_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
var/mob/living/real_mob = mob_override || owner.current
|
||||
RegisterSignal(real_mob, COMSIG_MOB_FLASHED_CARBON, PROC_REF(on_flash))
|
||||
|
||||
/datum/antagonist/rev/head/remove_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
var/mob/living/real_mob = mob_override || owner.current
|
||||
UnregisterSignal(real_mob, COMSIG_MOB_FLASHED_CARBON)
|
||||
|
||||
/// Signal proc for [COMSIG_MOB_FLASHED_CARBON].
|
||||
/// The bread and butter of head revolutionary conversions.
|
||||
/datum/antagonist/rev/head/proc/on_flash(mob/living/source, mob/living/carbon/flashed, obj/item/assembly/flash/flash, deviation)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// Always partial flash at the very least
|
||||
. = (deviation == DEVIATION_FULL) ? DEVIATION_OVERRIDE_PARTIAL : NONE
|
||||
|
||||
if(flashed.stat == DEAD)
|
||||
return .
|
||||
if(flashed.stat != CONSCIOUS)
|
||||
to_chat(source, span_warning("[flashed.p_they(capitalized = TRUE)] must be conscious before you can convert [flashed.p_them()]!"))
|
||||
return .
|
||||
|
||||
if(isnull(flashed.mind) || !GET_CLIENT(flashed))
|
||||
to_chat(source, span_warning("[flashed]'s mind is so vacant that it is not susceptible to influence!"))
|
||||
return .
|
||||
|
||||
var/holiday_meme_chance = check_holidays(APRIL_FOOLS) && prob(10)
|
||||
if(add_revolutionary(flashed.mind, mute = !holiday_meme_chance)) // don't mute if we roll the meme holiday chance
|
||||
if(holiday_meme_chance)
|
||||
INVOKE_ASYNC(src, PROC_REF(_async_holiday_meme_say), flashed)
|
||||
flash.times_used-- // Flashes are less likely to burn out for headrevs, when used for conversion
|
||||
else
|
||||
to_chat(source, span_warning("[flashed] seems resistant to [flash]!"))
|
||||
|
||||
return .
|
||||
|
||||
/// Used / called async from [proc/on_flash] to deliver a funny meme line
|
||||
/datum/antagonist/rev/head/proc/_async_holiday_meme_say(mob/living/carbon/flashed)
|
||||
if(ishuman(flashed))
|
||||
var/mob/living/carbon/human/human_flashed = flashed
|
||||
human_flashed.force_say()
|
||||
flashed.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in. (April Fools)")
|
||||
|
||||
/datum/antagonist/rev/head/antag_listing_name()
|
||||
return ..() + "(Leader)"
|
||||
|
||||
@@ -228,11 +273,20 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/antagonist/rev/proc/add_revolutionary(datum/mind/rev_mind,stun = TRUE)
|
||||
/**
|
||||
* Adds a new mind to our revoltuion
|
||||
*
|
||||
* * rev_mind - the mind we're adding
|
||||
* * stun - If TRUE, we will flash act and apply a long stun when we're applied
|
||||
* * mute - If TRUE, we will apply a mute when we're applied
|
||||
*/
|
||||
/datum/antagonist/rev/proc/add_revolutionary(datum/mind/rev_mind, stun = TRUE, mute = TRUE)
|
||||
if(!can_be_converted(rev_mind.current))
|
||||
return FALSE
|
||||
if(stun)
|
||||
|
||||
if(mute)
|
||||
rev_mind.current.set_silence_if_lower(10 SECONDS)
|
||||
if(stun)
|
||||
rev_mind.current.flash_act(1, 1)
|
||||
rev_mind.current.Stun(10 SECONDS)
|
||||
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
#define CONFUSION_STACK_MAX_MULTIPLIER 2
|
||||
|
||||
|
||||
/// No deviation at all. Flashed from the front or front-left/front-right. Alternatively, flashed in direct view.
|
||||
#define DEVIATION_NONE 0
|
||||
/// Partial deviation. Flashed from the side. Alternatively, flashed out the corner of your eyes.
|
||||
#define DEVIATION_PARTIAL 1
|
||||
/// Full deviation. Flashed from directly behind or behind-left/behind-rack. Not flashed at all.
|
||||
#define DEVIATION_FULL 2
|
||||
|
||||
/obj/item/assembly/flash
|
||||
name = "flash"
|
||||
desc = "A powerful and versatile flashbulb device, with applications ranging from disorienting attackers to acting as visual receptors in robot production."
|
||||
@@ -156,25 +148,26 @@
|
||||
|
||||
var/deviation = calculate_deviation(flashed, user || src)
|
||||
|
||||
var/datum/antagonist/rev/head/converter = user?.mind?.has_antag_datum(/datum/antagonist/rev/head)
|
||||
if(user)
|
||||
var/sigreturn = SEND_SIGNAL(user, COMSIG_MOB_FLASHED_CARBON, flashed, src, deviation)
|
||||
if(sigreturn & STOP_FLASH)
|
||||
return
|
||||
|
||||
if(sigreturn & DEVIATION_OVERRIDE_FULL)
|
||||
deviation = DEVIATION_FULL
|
||||
else if(sigreturn & DEVIATION_OVERRIDE_PARTIAL)
|
||||
deviation = DEVIATION_PARTIAL
|
||||
else if(sigreturn & DEVIATION_OVERRIDE_NONE)
|
||||
deviation = DEVIATION_NONE
|
||||
|
||||
//If you face away from someone they shouldnt notice any effects.
|
||||
if(deviation == DEVIATION_FULL && !converter)
|
||||
if(deviation == DEVIATION_FULL)
|
||||
return
|
||||
|
||||
if(targeted)
|
||||
if(flashed.flash_act(1, 1))
|
||||
flashed.set_confusion_if_lower(confusion_duration * CONFUSION_STACK_MAX_MULTIPLIER)
|
||||
// Special check for if we're a revhead. Special cases to attempt conversion.
|
||||
if(converter)
|
||||
// Did we try to flash them from behind?
|
||||
if(deviation == DEVIATION_FULL)
|
||||
// Headrevs can use a tacticool leaning technique so that they don't have to worry about facing for their conversions.
|
||||
to_chat(user, span_notice("You use the tacticool tier, lean over the shoulder technique to blind [flashed] with a flash!"))
|
||||
deviation = DEVIATION_PARTIAL
|
||||
// Convert them. Terribly.
|
||||
terrible_conversion_proc(flashed, user)
|
||||
visible_message(span_danger("[user] blinds [flashed] with the flash!"), span_userdanger("[user] blinds you with the flash!"))
|
||||
visible_message(span_danger("[user] blinds [flashed] with the flash!"), span_userdanger("[user] blinds you with the flash!"))
|
||||
//easy way to make sure that you can only long stun someone who is facing in your direction
|
||||
flashed.adjustStaminaLoss(rand(80, 120) * (1 - (deviation * 0.5)))
|
||||
flashed.Paralyze(rand(25, 50) * (1 - (deviation * 0.5)))
|
||||
@@ -277,34 +270,6 @@
|
||||
return
|
||||
AOE_flash()
|
||||
|
||||
/**
|
||||
* Converts the victim to revs
|
||||
*
|
||||
* Arguments:
|
||||
* * victim - Victim
|
||||
* * aggressor - Attacker
|
||||
*/
|
||||
/obj/item/assembly/flash/proc/terrible_conversion_proc(mob/living/carbon/victim, mob/aggressor)
|
||||
if(!istype(victim) || victim.stat == DEAD)
|
||||
return
|
||||
if(!aggressor.mind)
|
||||
return
|
||||
if(!victim.client)
|
||||
to_chat(aggressor, span_warning("This mind is so vacant that it is not susceptible to influence!"))
|
||||
return
|
||||
if(victim.stat != CONSCIOUS)
|
||||
to_chat(aggressor, span_warning("They must be conscious before you can convert [victim.p_them()]!"))
|
||||
return
|
||||
//If this proc fires the mob must be a revhead
|
||||
var/datum/antagonist/rev/head/converter = aggressor.mind.has_antag_datum(/datum/antagonist/rev/head)
|
||||
if(converter.add_revolutionary(victim.mind))
|
||||
if(prob(1) || check_holidays(APRIL_FOOLS))
|
||||
victim.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in.")
|
||||
times_used -- //Flashes less likely to burn out for headrevs when used for conversion
|
||||
else
|
||||
to_chat(aggressor, span_warning("This mind seems resistant to the flash!"))
|
||||
|
||||
|
||||
/obj/item/assembly/flash/cyborg
|
||||
|
||||
/obj/item/assembly/flash/cyborg/attack(mob/living/M, mob/user)
|
||||
@@ -415,6 +380,3 @@
|
||||
M.adjust_pacifism(4 SECONDS)
|
||||
|
||||
#undef CONFUSION_STACK_MAX_MULTIPLIER
|
||||
#undef DEVIATION_NONE
|
||||
#undef DEVIATION_PARTIAL
|
||||
#undef DEVIATION_FULL
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
#include "reagent_recipe_collisions.dm"
|
||||
#include "reagent_transfer.dm"
|
||||
#include "resist.dm"
|
||||
#include "rev_conversion.dm"
|
||||
#include "say.dm"
|
||||
#include "screenshot_antag_icons.dm"
|
||||
#include "screenshot_basic.dm"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/// Tests that headrevs can convert people by clicking on them with flashes
|
||||
/datum/unit_test/revolution_conversion
|
||||
|
||||
/datum/unit_test/revolution_conversion/Run()
|
||||
var/mob/living/carbon/human/leader = allocate(/mob/living/carbon/human/consistent, run_loc_floor_bottom_left)
|
||||
var/mob/living/carbon/human/peasant = allocate(/mob/living/carbon/human/consistent, run_loc_floor_bottom_left)
|
||||
|
||||
leader.mind_initialize()
|
||||
leader.mock_client = new()
|
||||
peasant.mind_initialize()
|
||||
peasant.mock_client = new()
|
||||
|
||||
var/datum/antagonist/rev/head/lead_datum = leader.mind.add_antag_datum(/datum/antagonist/rev/head)
|
||||
var/datum/team/revolution/revolution = lead_datum.get_team()
|
||||
|
||||
var/obj/item/assembly/flash/handheld/converter = allocate(/obj/item/assembly/flash/handheld)
|
||||
leader.put_in_active_hand(converter, forced = TRUE)
|
||||
leader.ClickOn(peasant)
|
||||
|
||||
TEST_ASSERT(peasant.IsParalyzed(), "Peasant was not paralyzed after being flashed by the leader") // Flash paralyze
|
||||
TEST_ASSERT(peasant.IsStun(), "Peasant was not stunned after being converted by the leader") // Conversion stun
|
||||
TEST_ASSERT_EQUAL(length(revolution.members), 2, "Expected revolution to have 2 members after the leader flashes the peasant.")
|
||||
Reference in New Issue
Block a user