Skip to content

Commit

Permalink
Xeno Alliance Announcements + Greeno Civil War (#3990)
Browse files Browse the repository at this point in the history
# About the pull request

Xenos now get messages when their queen set/break alliance to another
faction and when other queen set/break alliance with their hive.

Corrupted Xenos with implanted IFF tag now has a choice to defect from
the hive and become Renegade (hive allied to USCM) when Queen decides to
break alliance with USCM. Xenos that stay loyal to Queen rip the IFF
tags out. You have only 10 seconds to make a decision, so think quick.
By default xenos stay loyal to Queen.

Renegade Hive is allied to all human factions, but it mostly affects
structures and weeds. Renegade ability to attack someone fully depends
on its IFF tag settings.

Please check my messages because I'm not very good at writing.

# Explain why it's good for the game

More announcements are good because it's less confusing. You know when
someone set ally to you and you know when someone is betraying you. It
makes sense because allied xenos share announcements anyway. And sudden
betrayals are always a bit cheesy.

I think the Renegade addition makes research a little more fun and
rewarding. Now, if you implant corrupted xeno with an IFF tag, the xeno
player can choose to remain loyal to you if/when the Queen decides to
betray. Plus corrupted xenos with the IFF tag are no longer forced to
betray, so it's also good. Not sure if that makes sense lore-wise, but
since corrupted are artificially created and their DNA is decrypted, it
makes at least some sense. Plus we kinda have tamed xenos which work
really similarly.

# Testing Photographs and Procedure
<details>
<summary>Screenshots & Videos</summary>

Put screenshots and videos here with an empty line between the
screenshots and the `<details>` tags.

</details>


# Changelog
:cl: ihatethisengine
add: Added announcements for xenos about forming and breaking alliances.
add: Xenos with IFF tag now have a choice to stay loyal to USCM when
Queen decides to betray.
/:cl:

---------

Co-authored-by: ihatethisengine <[email protected]>
Co-authored-by: Drathek <[email protected]>
Co-authored-by: harryob <[email protected]>
  • Loading branch information
4 people authored Jul 28, 2023
1 parent 92fdada commit ce09b07
Show file tree
Hide file tree
Showing 11 changed files with 156 additions and 18 deletions.
3 changes: 2 additions & 1 deletion code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,9 @@
#define XENO_HIVE_MUTATED "xeno_hive_mutated"
#define XENO_HIVE_FORSAKEN "xeno_hive_forsaken"
#define XENO_HIVE_YAUTJA "xeno_hive_yautja"
#define XENO_HIVE_RENEGADE "xeno_hive_renegade"

#define ALL_XENO_HIVES list(XENO_HIVE_NORMAL, XENO_HIVE_CORRUPTED, XENO_HIVE_ALPHA, XENO_HIVE_BRAVO, XENO_HIVE_CHARLIE, XENO_HIVE_DELTA, XENO_HIVE_FERAL, XENO_HIVE_TAMED, XENO_HIVE_MUTATED, XENO_HIVE_FORSAKEN, XENO_HIVE_YAUTJA)
#define ALL_XENO_HIVES list(XENO_HIVE_NORMAL, XENO_HIVE_CORRUPTED, XENO_HIVE_ALPHA, XENO_HIVE_BRAVO, XENO_HIVE_CHARLIE, XENO_HIVE_DELTA, XENO_HIVE_FERAL, XENO_HIVE_TAMED, XENO_HIVE_MUTATED, XENO_HIVE_FORSAKEN, XENO_HIVE_YAUTJA, XENO_HIVE_RENEGADE)

//=================================================

Expand Down
4 changes: 4 additions & 0 deletions code/__DEFINES/typecheck/xenos.dm
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
if(!hive)
return FALSE

if(hivenumber == XENO_HIVE_RENEGADE)
var/datum/hive_status/corrupted/renegade/renegade_hive = hive
return renegade_hive.iff_protection_check(src, attempt_harm_mob)

return hive.is_ally(attempt_harm_mob)

// need this to set the data for walls/eggs/huggers when they are initialized
Expand Down
3 changes: 2 additions & 1 deletion code/_globalvars/global_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ GLOBAL_LIST_INIT_TYPED(hive_datum, /datum/hive_status, list(
XENO_HIVE_TAMED = new /datum/hive_status/corrupted/tamed(),
XENO_HIVE_MUTATED = new /datum/hive_status/mutated(),
XENO_HIVE_FORSAKEN = new /datum/hive_status/forsaken(),
XENO_HIVE_YAUTJA = new /datum/hive_status/yautja()
XENO_HIVE_YAUTJA = new /datum/hive_status/yautja(),
XENO_HIVE_RENEGADE = new /datum/hive_status/corrupted/renegade(),
))

GLOBAL_LIST_INIT(xeno_evolve_times, setup_xeno_evolve_times())
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/xenomorph/Evolution.dm
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
if(!evolve_checks())
return

if((!hive.living_xeno_queen) && castepick != XENO_CASTE_QUEEN && !islarva(src) && !hive.allow_no_queen_actions)
if((!hive.living_xeno_queen) && castepick != XENO_CASTE_QUEEN && !islarva(src) && !hive.allow_no_queen_evo)
to_chat(src, SPAN_WARNING("The Hive is shaken by the death of the last Queen. You can't find the strength to evolve."))
return

Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@

if(caste && caste.evolution_allowed)
evolve_progress = "[min(stored_evolution, evolution_threshold)]/[evolution_threshold]"
if(hive && !hive.allow_no_queen_actions && !caste?.evolve_without_queen)
if(hive && !hive.allow_no_queen_evo && !caste?.evolve_without_queen)
if(!hive.living_xeno_queen)
evolve_progress += " (NO QUEEN)"
else if(!(hive.living_xeno_queen.ovipositor || hive.evolution_without_ovipositor))
Expand Down
2 changes: 2 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/damage_procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
user.put_in_hands(iff_tag)
iff_tag = null
user.visible_message(SPAN_NOTICE("[user] removes \the [src]'s IFF tag."), SPAN_NOTICE("You remove \the [src]'s IFF tag."), max_distance = 3)
if(hive.hivenumber == XENO_HIVE_RENEGADE) //it's important to know their IFF settings for renegade
to_chat(src, SPAN_NOTICE("With the removal of the device, your instincts have returned to normal."))
return
return ..()

Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/hive_faction.dm
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,5 @@ GLOBAL_LIST_INIT(hive_alliable_factions, generate_alliable_factions())

var/should_ally = text2num(params["should_ally"])
assoc_hive.allies[params["target_faction"]] = should_ally
assoc_hive.on_stance_change(params["target_faction"])
. = TRUE
4 changes: 4 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/items/iff_tag.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
injector.visible_message(SPAN_NOTICE("[injector] forces \the [src] into [xeno]'s carapace!"), SPAN_NOTICE("You force \the [src] into [xeno]'s carapace!"))
xeno.iff_tag = src
injector.drop_inv_item_to_loc(src, xeno)
if(xeno.hive.hivenumber == XENO_HIVE_RENEGADE) //it's important to know their IFF settings for renegade
to_chat(xeno, SPAN_NOTICE("With the insertion of the device into your carapace, your instincts have changed compelling you to protect [english_list(faction_groups, "no one")]."))
return
return ..()

Expand Down Expand Up @@ -48,6 +50,8 @@
if("Remove")
faction_groups = list()
to_chat(programmer, SPAN_NOTICE("You <b>[option]</b> the IFF group data, the IFF group on the tag now reads as: [english_list(faction_groups, "None")]"))
if(xeno?.hive.hivenumber == XENO_HIVE_RENEGADE) //it's important to know their IFF settings for renegade
to_chat(xeno, SPAN_NOTICE("Your instincts have changed, you seem compelled to protect [english_list(faction_groups, "no one")]."))
return TRUE

/obj/item/iff_tag/pmc_handler
Expand Down
12 changes: 3 additions & 9 deletions code/modules/mob/living/carbon/xenomorph/life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
var/progress_amount = 1
if(SSxevolution)
progress_amount = SSxevolution.get_evolution_boost_power(hive.hivenumber)
var/ovipositor_check = (hive.allow_no_queen_actions || hive.evolution_without_ovipositor || (hive.living_xeno_queen && hive.living_xeno_queen.ovipositor))
var/ovipositor_check = (hive.allow_no_queen_evo || hive.evolution_without_ovipositor || (hive.living_xeno_queen && hive.living_xeno_queen.ovipositor))
if(caste && caste.evolution_allowed && (ovipositor_check || caste?.evolve_without_queen))
if(evolution_stored >= evolution_threshold)
if(!got_evolution_message)
Expand Down Expand Up @@ -334,11 +334,6 @@ Make sure their actual health updates immediately.*/
if(!T || !istype(T))
return

var/is_runner_hiding

if(isrunner(src) && layer != initial(layer))
is_runner_hiding = 1

if(caste)
if(caste.innate_healing || check_weeds_for_healing())
if(!hive) return // can't heal if you have no hive, sorry bud
Expand Down Expand Up @@ -369,9 +364,8 @@ Make sure their actual health updates immediately.*/
if(armor_integrity > armor_integrity_max)
armor_integrity = armor_integrity_max

else //Xenos restore plasma VERY slowly off weeds, regardless of health, as long as they are not using special abilities
if(prob(50) && !is_runner_hiding && !current_aura)
plasma_stored += 0.1 * plasma_max / 100
else if(prob(50) && !current_aura) //Xenos restore plasma VERY slowly off weeds, regardless of health, as long as they are not using special abilities
plasma_stored += 0.1 * plasma_max / 100


for(var/datum/action/xeno_action/action in src.actions)
Expand Down
134 changes: 129 additions & 5 deletions code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,9 @@
var/evolution_bonus = 0

var/allow_no_queen_actions = FALSE
var/allow_no_queen_evo = FALSE
var/evolution_without_ovipositor = TRUE //Temporary for the roundstart.
/// Set to true if you want to prevent evolutions into Queens
/// Set to false if you want to prevent evolutions into Queens
var/allow_queen_evolve = TRUE
/// Set to true if you want to prevent bursts and spawns of new xenos. Will also prevent healing if the queen no longer exists
var/hardcore = FALSE
Expand Down Expand Up @@ -1112,13 +1113,15 @@

need_round_end_check = TRUE

/datum/hive_status/corrupted/add_xeno(mob/living/carbon/xenomorph/X)
var/list/defectors = list()

/datum/hive_status/corrupted/add_xeno(mob/living/carbon/xenomorph/xeno)
. = ..()
X.add_language(LANGUAGE_ENGLISH)
xeno.add_language(LANGUAGE_ENGLISH)

/datum/hive_status/corrupted/remove_xeno(mob/living/carbon/xenomorph/X, hard)
/datum/hive_status/corrupted/remove_xeno(mob/living/carbon/xenomorph/xeno, hard)
. = ..()
X.remove_language(LANGUAGE_ENGLISH)
xeno.remove_language(LANGUAGE_ENGLISH)

/datum/hive_status/corrupted/can_delay_round_end(mob/living/carbon/xenomorph/xeno)
if(!faction_is_ally(FACTION_MARINE, TRUE))
Expand Down Expand Up @@ -1181,6 +1184,7 @@
destruction_allowed = XENO_NOBODY
dynamic_evolution = FALSE
allow_no_queen_actions = TRUE
allow_no_queen_evo = TRUE
allow_queen_evolve = FALSE
ignore_slots = TRUE
latejoin_burrowed = FALSE
Expand All @@ -1195,6 +1199,7 @@

dynamic_evolution = FALSE
allow_no_queen_actions = TRUE
allow_no_queen_evo = TRUE
allow_queen_evolve = FALSE
ignore_slots = TRUE
latejoin_burrowed = FALSE
Expand All @@ -1212,6 +1217,7 @@

dynamic_evolution = FALSE
allow_no_queen_actions = TRUE
allow_no_queen_evo = TRUE
allow_queen_evolve = FALSE
ignore_slots = TRUE
latejoin_burrowed = FALSE
Expand Down Expand Up @@ -1241,6 +1247,7 @@

dynamic_evolution = FALSE
allow_no_queen_actions = TRUE
allow_no_queen_evo = TRUE
allow_queen_evolve = FALSE
ignore_slots = TRUE
latejoin_burrowed = FALSE
Expand Down Expand Up @@ -1296,6 +1303,123 @@

return ..()

/datum/hive_status/corrupted/renegade
name = "Renegade Hive"
reporting_id = "renegade"
hivenumber = XENO_HIVE_RENEGADE
prefix = "Renegade "
color = "#9c7a4d"
ui_color ="#80705c"

dynamic_evolution = FALSE
allow_queen_evolve = FALSE
allow_no_queen_evo = TRUE
latejoin_burrowed = FALSE

/datum/hive_status/corrupted/renegade/New()
. = ..()
hive_structures_limit[XENO_STRUCTURE_EGGMORPH] = 0
hive_structures_limit[XENO_STRUCTURE_EVOPOD] = 0
for(var/faction in FACTION_LIST_HUMANOID) //renegades allied to all humanoids, but it mostly affects structures. Their ability to attack humanoids and other xenos (including of the same hive) depends on iff settings
allies[faction] = TRUE

/datum/hive_status/corrupted/renegade/can_spawn_as_hugger(mob/dead/observer/user)
to_chat(user, SPAN_WARNING("The [name] cannot support facehuggers."))
return FALSE

/datum/hive_status/corrupted/renegade/proc/iff_protection_check(mob/living/carbon/xenomorph/xeno, mob/living/carbon/attempt_harm_mob)
if(xeno == attempt_harm_mob)
return TRUE //you cannot hurt yourself...
if(!xeno.iff_tag)
return FALSE //can attack anyone if you don't have iff tag
if(isxeno(attempt_harm_mob))
var/mob/living/carbon/xenomorph/target_xeno = attempt_harm_mob
if(!target_xeno.iff_tag)
return FALSE //can attack any xeno who don't have iff tag
for(var/faction in xeno.iff_tag.faction_groups)
if(faction in target_xeno.iff_tag.faction_groups)
return TRUE //cannot attack xenos with same iff setting
return FALSE
for(var/faction in xeno.iff_tag.faction_groups)
if(faction in attempt_harm_mob.faction_group)
return TRUE //cannot attack mob if iff is set to at least one of its factions
return FALSE

/datum/hive_status/corrupted/renegade/faction_is_ally(faction, ignore_queen_check = TRUE)
return ..()

/datum/hive_status/proc/on_stance_change(faction)
if(!living_xeno_queen)
return
if(allies[faction])
xeno_message(SPAN_XENOANNOUNCE("Your Queen set up an alliance with [faction]!"), 3, hivenumber)
else
xeno_message(SPAN_XENOANNOUNCE("Your Queen broke the alliance with [faction]!"), 3, hivenumber)

for(var/number in GLOB.hive_datum)
var/datum/hive_status/target_hive = GLOB.hive_datum[number]
if(target_hive.name != faction)
continue
if(!target_hive.living_xeno_queen && !target_hive.allow_no_queen_actions)
return
if(allies[faction])
xeno_message(SPAN_XENOANNOUNCE("You sense that [name] Queen set up an alliance with us!"), 3, target_hive.hivenumber)
return

xeno_message(SPAN_XENOANNOUNCE("You sense that [name] Queen broke the alliance with us!"), 3, target_hive.hivenumber)

/datum/hive_status/corrupted/on_stance_change(faction)
. = ..()
if(allies[faction])
return
if(!(faction in FACTION_LIST_HUMANOID))
return

for(var/mob/living/carbon/xenomorph/xeno in totalXenos) // handle defecting xenos on betrayal
if(!xeno.iff_tag)
continue
if(!(faction in xeno.iff_tag.faction_groups))
continue
if(xeno in defectors)
continue
if(xeno.caste_type == XENO_CASTE_QUEEN)
continue
INVOKE_ASYNC(src, PROC_REF(give_defection_choice), xeno, faction)
addtimer(CALLBACK(src, PROC_REF(handle_defectors), faction), 11 SECONDS)

/datum/hive_status/corrupted/proc/give_defection_choice(mob/living/carbon/xenomorph/xeno, faction)
if(tgui_alert(xeno, "Your Queen has broken the alliance with the [faction]. The device inside your carapace begins to suppress your connection with the Hive. Do you remove it and stay loyal to her?", "Alliance broken!", list("Stay loyal", "Obey the talls"), 10 SECONDS) == "Obey the talls")
if(!xeno.iff_tag)
to_chat(xeno, SPAN_XENOWARNING("It's too late now. The device is gone and your service to the Queen continues."))
return
defectors += xeno
xeno.set_hive_and_update(XENO_HIVE_RENEGADE)
to_chat(xeno, SPAN_XENOANNOUNCE("You lost the connection with your Hive. Now you have no Queen, only your masters."))
to_chat(xeno, SPAN_NOTICE("Your instincts have changed, you seem compelled to protect [english_list(xeno.iff_tag.faction_groups, "no one")]."))
return
xeno.visible_message(SPAN_XENOWARNING("[xeno] rips out [xeno.iff_tag]!"), SPAN_XENOWARNING("You rip out [xeno.iff_tag]! For the Hive!"))
xeno.adjustBruteLoss(50)
xeno.iff_tag.forceMove(get_turf(xeno))
xeno.iff_tag = null

/datum/hive_status/corrupted/proc/handle_defectors(faction)
for(var/mob/living/carbon/xenomorph/xeno in totalXenos)
if(!xeno.iff_tag)
continue
if(xeno in defectors)
continue
if(!(faction in xeno.iff_tag.faction_groups))
continue
xeno.visible_message(SPAN_XENOWARNING("[xeno] rips out [xeno.iff_tag]!"), SPAN_XENOWARNING("You rip out [xeno.iff_tag]! For the hive!"))
xeno.adjustBruteLoss(50)
xeno.iff_tag.forceMove(get_turf(xeno))
xeno.iff_tag = null
if(!length(defectors))
return

xeno_message(SPAN_XENOANNOUNCE("You sense that [english_list(defectors)] turned their backs against their sisters and the Queen in favor of their slavemasters!"), 3, hivenumber)
defectors.Cut()

//Xeno Resin Mark Shit, the very best place for it too :0)
//Defines at the bottom of this list here will show up at the top in the mark menu
/datum/xeno_mark_define
Expand Down
7 changes: 7 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
if(!hive)
return

if(hive.hivenumber == XENO_HIVE_RENEGADE) //Renegade's ability to attack someone depends on IFF settings, not on alliance
if(!iff_tag)
to_chat(src, SPAN_NOTICE("You are not obligated to protect anyone."))
return
to_chat(src, SPAN_NOTICE("You seem compelled to protect [english_list(iff_tag.faction_groups, "no one")]."))
return

if((!hive.living_xeno_queen || Check_WO()) && !hive.allow_no_queen_actions) //No Hive status on WO
to_chat(src, SPAN_WARNING("There is no Queen. You are alone."))
return
Expand Down

0 comments on commit ce09b07

Please sign in to comment.