Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIRROR] [MIRROR] Cult Vs. Heretic: 7 Months Later Edition [MDB IGNORE] #806

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code/__DEFINES/antagonists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
#define CONSTRUCT_JUGGERNAUT "Juggernaut"
#define CONSTRUCT_WRAITH "Wraith"
#define CONSTRUCT_ARTIFICER "Artificer"
#define CONSTRUCT_HARVESTER "Harvester"

/// The Classic Wizard wizard loadout.
#define WIZARD_LOADOUT_CLASSIC "loadout_classic"
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/colors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
#define COLOR_LIME "#32CD32"
#define COLOR_DARK_LIME "#00aa00"
#define COLOR_VERY_PALE_LIME_GREEN "#DDFFD3"
#define COLOR_HERETIC_GREEN COLOR_VERY_PALE_LIME_GREEN // i am co-opting this as heretic glow.
#define COLOR_VERY_DARK_LIME_GREEN "#003300"
#define COLOR_GREEN "#008000"
#define COLOR_CHRISTMAS_GREEN "#00873E"
Expand Down Expand Up @@ -130,6 +131,7 @@
#define COLOR_DARK_ORANGE "#C3630C"
#define COLOR_PRISONER_ORANGE "#A54900"
#define COLOR_DARK_MODERATE_ORANGE "#8B633B"
#define COLOR_RUSTED_GLASS "#917c65"

#define COLOR_BROWN "#BA9F6D"
#define COLOR_DARK_BROWN "#997C4F"
Expand Down
9 changes: 9 additions & 0 deletions code/__DEFINES/cult.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#define RUNE_COLOR_SUMMON COLOR_VIBRANT_LIME

//blood magic
/// The maximum number of cult spell slots each cultist is allowed to scribe at once.
#define ENHANCED_BLOODCHARGE 5
#define MAX_BLOODCHARGE 4
#define RUNELESS_MAX_BLOODCHARGE 1
/// percent before rise
Expand All @@ -28,6 +30,8 @@
#define THEME_CULT "cult"
#define THEME_WIZARD "wizard"
#define THEME_HOLY "holy"
/// Only used for heretic Harvesters, obtained from sacrificing cultists
#define THEME_HERETIC "heretic"

/// Defines for cult item_dispensers.
#define PREVIEW_IMAGE "preview"
Expand All @@ -51,3 +55,8 @@ GLOBAL_LIST(sacrificed)
#define CULT_VICTORY 1
#define CULT_LOSS 0
#define CULT_NARSIE_KILLED -1

// Used to keep track of items rewarded after a heretic is sacked.
#define CURSED_BLADE_UNLOCKED "Cursed Blade"
#define CRIMSON_FOCUS_UNLOCKED "Crimson Focus"
#define PROTEON_ORB_UNLOCKED "Proteon Orb"
10 changes: 10 additions & 0 deletions code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,13 @@
#define COMSIG_ATOM_PRE_CLEAN "atom_pre_clean"
///cancel clean
#define COMSIG_ATOM_CANCEL_CLEAN (1<<0)
<<<<<<< HEAD

Check failure on line 136 in code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm

View workflow job for this annotation

GitHub Actions / Run Linters

got '<<', expected one of: newline, '/', identifier
=======

/// From /obj/item/stack/make_item()
#define COMSIG_ATOM_CONSTRUCTED "atom_constructed"

/// From /obj/effect/particle_effect/sparks/proc/sparks_touched(datum/source, atom/movable/singed)
#define COMSIG_ATOM_TOUCHED_SPARKS "atom_touched_sparks"
#define COMSIG_ATOM_TOUCHED_HAZARDOUS_SPARKS "atom_touched_hazardous_sparks"
>>>>>>> 0c4df344b8a... [MIRROR] Cult Vs. Heretic: 7 Months Later Edition [MDB IGNORE] (#3384)
4 changes: 4 additions & 0 deletions code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@
#define STOP_SACRIFICE (1<<0)
/// Don't send a message for sacrificing this thing, we have our own
#define SILENCE_SACRIFICE_MESSAGE (1<<1)
/// Don't send a message for sacrificing this thing UNLESS it's the cult target
#define SILENCE_NONTARGET_SACRIFICE_MESSAGE (1<<2)
/// Dusts the target instead of gibbing them (no soulstone)
#define DUST_SACRIFICE (1<<3)

/// From /mob/living/befriend() : (mob/living/new_friend)
#define COMSIG_LIVING_BEFRIENDED "living_befriended"
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/is_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list(

#define islandmine(A) (istype(A, /obj/effect/mine))

#define iscloset(A) (istype(A, /obj/structure/closet))

#define issupplypod(A) (istype(A, /obj/structure/closet/supplypod))

#define isammocasing(A) (istype(A, /obj/item/ammo_casing))
Expand Down
10 changes: 10 additions & 0 deletions code/__DEFINES/traits/declarations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_IWASBATONED "iwasbatoned"
#define TRAIT_SLEEPIMMUNE "sleep_immunity"
#define TRAIT_PUSHIMMUNE "push_immunity"
/// can't be kicked to the side
#define TRAIT_NO_SIDE_KICK "no_side_kick"
/// Are we immune to shocks?
#define TRAIT_SHOCKIMMUNE "shock_immunity"
/// Are we immune to specifically tesla / SM shocks?
Expand Down Expand Up @@ -1085,6 +1087,11 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Note this doesn't mean all spells are guaranteed to work or the mob is guaranteed to cast
#define TRAIT_CASTABLE_LOC "castable_loc"

/// Needs above trait to work.
/// This trait makes it so that any cast spells will attempt to transfer to the location's location.
/// For example, a heretic inside the haunted blade's spells would emanate from the mob wielding the sword.
#define TRAIT_SPELLS_TRANSFER_TO_LOC "spells_transfer_to_loc"

///Trait given by /datum/element/relay_attacker
#define TRAIT_RELAYING_ATTACKER "relaying_attacker"

Expand Down Expand Up @@ -1147,6 +1154,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Trait applied to objects and mobs that can attack a boulder and break it down. (See /obj/item/boulder/manual_process())
#define TRAIT_BOULDER_BREAKER "boulder_breaker"

/// Trait given to anything linked to, not necessarily allied to, the mansus
#define TRAIT_MANSUS_TOUCHED "mansus_touched"

/// Trait given to mobs wearing the clown mask
#define TRAIT_PERCEIVED_AS_CLOWN "perceived_as_clown"
/// Does this item bypass ranged armor checks?
Expand Down
11 changes: 5 additions & 6 deletions code/__HELPERS/turfs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -400,19 +400,18 @@ Turf and target are separate in case you want to teleport some distance from a t
/**
* Checks whether or not a particular typepath or subtype of it is present on a turf
*
* Returns TRUE if an instance of the desired type or a subtype of it is found
* Returns FALSE if the type is not found, or if no turf is supplied
* Returns the first instance located if an instance of the desired type or a subtype of it is found
* Returns null if the type is not found, or if no turf is supplied
*
* Arguments:
* * location - The turf to be checked for the desired type
* * type_to_find - The typepath whose presence you are checking for
*/
/proc/is_type_on_turf(turf/location, type_to_find)
if(!location)
return FALSE
if(locate(type_to_find) in location)
return TRUE
return FALSE
return
var/found_type = locate(type_to_find) in location
return found_type

/**
* get_blueprint_data
Expand Down
1 change: 0 additions & 1 deletion code/_globalvars/phobias.dm
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,6 @@ GLOBAL_LIST_INIT(phobia_objs, list(
/obj/item/clothing/suit/wizrobe,
/obj/item/clothing/under/rank/civilian/chaplain,
/obj/item/codex_cicatrix,
/obj/item/cult_bastard,
/obj/item/gun/magic,
/obj/item/melee/cultblade,
/obj/item/melee/rune_carver,
Expand Down
4 changes: 4 additions & 0 deletions code/_globalvars/traits/_traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_NO_MISSING_ITEM_ERROR" = TRAIT_NO_MISSING_ITEM_ERROR,
"TRAIT_NO_THROW_HITPUSH" = TRAIT_NO_THROW_HITPUSH,
"TRAIT_NOT_ENGRAVABLE" = TRAIT_NOT_ENGRAVABLE,
"TRAIT_SPELLS_TRANSFER_TO_LOC" = TRAIT_SPELLS_TRANSFER_TO_LOC,
"TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT" = TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT,
"TRAIT_RUNECHAT_HIDDEN" = TRAIT_RUNECHAT_HIDDEN,
"TRAIT_SECLUDED_LOCATION" = TRAIT_SECLUDED_LOCATION,
Expand Down Expand Up @@ -152,6 +153,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_BOMBIMMUNE" = TRAIT_BOMBIMMUNE,
"TRAIT_BONSAI" = TRAIT_BONSAI,
"TRAIT_BOOZE_SLIDER" = TRAIT_BOOZE_SLIDER,
"TRAIT_BOXING_READY" = TRAIT_BOXING_READY,
"TRAIT_BORN_MONKEY" = TRAIT_BORN_MONKEY,
"TRAIT_BRAINWASHING" = TRAIT_BRAINWASHING,
"TRAIT_BRAWLING_KNOCKDOWN_BLOCKED" = TRAIT_BRAWLING_KNOCKDOWN_BLOCKED,
Expand Down Expand Up @@ -297,6 +299,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_MAGICALLY_GIFTED" = TRAIT_MAGICALLY_GIFTED,
"TRAIT_MAGICALLY_PHASED" = TRAIT_MAGICALLY_PHASED,
"TRAIT_MARTIAL_ARTS_IMMUNE" = TRAIT_MARTIAL_ARTS_IMMUNE,
"TRAIT_MANSUS_TOUCHED" = TRAIT_MANSUS_TOUCHED,
"TRAIT_MEDIBOTCOMINGTHROUGH" = TRAIT_MEDIBOTCOMINGTHROUGH,
"TRAIT_MEDICAL_HUD" = TRAIT_MEDICAL_HUD,
"TRAIT_MESON_VISION" = TRAIT_MESON_VISION,
Expand Down Expand Up @@ -538,6 +541,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_NO_BARCODES" = TRAIT_NO_BARCODES,
"TRAIT_NO_STORAGE_INSERT" = TRAIT_NO_STORAGE_INSERT,
"TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT,
"TRAIT_NO_SIDE_KICK" = TRAIT_NO_SIDE_KICK,
"TRAIT_NODROP" = TRAIT_NODROP,
"TRAIT_OMNI_BAIT" = TRAIT_OMNI_BAIT,
"TRAIT_PLANT_WILDMUTATE" = TRAIT_PLANT_WILDMUTATE,
Expand Down
87 changes: 48 additions & 39 deletions code/_onclick/hud/alert.dm
Original file line number Diff line number Diff line change
Expand Up @@ -525,15 +525,15 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
alerttooltipstyle = "cult"
var/static/image/narnar
var/angle = 0
var/mob/living/basic/construct/Cviewer
var/mob/living/basic/construct/construct_owner

/atom/movable/screen/alert/bloodsense/Initialize(mapload, datum/hud/hud_owner)
. = ..()
narnar = new('icons/hud/screen_alert.dmi', "mini_nar")
START_PROCESSING(SSprocessing, src)

/atom/movable/screen/alert/bloodsense/Destroy()
Cviewer = null
construct_owner = null
STOP_PROCESSING(SSprocessing, src)
return ..()

Expand All @@ -543,45 +543,53 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
if(!owner.mind)
return

if(isconstruct(owner))
construct_owner = owner
else
construct_owner = null

// construct track
if(construct_owner?.seeking && construct_owner.master)
blood_target = construct_owner.master
desc = "Your blood sense is leading you to [construct_owner.master]"

// cult track
var/datum/antagonist/cult/antag = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!antag)
return
var/datum/objective/sacrifice/sac_objective = locate() in antag.cult_team.objectives
if(antag)
var/datum/objective/sacrifice/sac_objective = locate() in antag.cult_team.objectives
if(antag.cult_team.blood_target)
if(!get_turf(antag.cult_team.blood_target))
antag.cult_team.unset_blood_target()
else
blood_target = antag.cult_team.blood_target
if(!blood_target)
if(sac_objective && !sac_objective.check_completion())
if(icon_state == "runed_sense0")
return
animate(src, transform = null, time = 1, loop = 0)
angle = 0
cut_overlays()
icon_state = "runed_sense0"
desc = "Nar'Sie demands that [sac_objective.target] be sacrificed before the summoning ritual can begin."
add_overlay(sac_objective.sac_image)
else
var/datum/objective/eldergod/summon_objective = locate() in antag.cult_team.objectives
if(!summon_objective)
return
var/list/location_list = list()
for(var/area/area_to_check in summon_objective.summon_spots)
location_list += area_to_check.get_original_area_name()
desc = "The sacrifice is complete, summon Nar'Sie! The summoning can only take place in [english_list(location_list)]!"
if(icon_state == "runed_sense1")
return
animate(src, transform = null, time = 1, loop = 0)
angle = 0
cut_overlays()
icon_state = "runed_sense1"
add_overlay(narnar)
return

if(antag.cult_team.blood_target)
if(!get_turf(antag.cult_team.blood_target))
antag.cult_team.unset_blood_target()
else
blood_target = antag.cult_team.blood_target
if(Cviewer?.seeking && Cviewer.master)
blood_target = Cviewer.master
desc = "Your blood sense is leading you to [Cviewer.master]"
if(!blood_target)
if(sac_objective && !sac_objective.check_completion())
if(icon_state == "runed_sense0")
return
animate(src, transform = null, time = 1, loop = 0)
angle = 0
cut_overlays()
icon_state = "runed_sense0"
desc = "Nar'Sie demands that [sac_objective.target] be sacrificed before the summoning ritual can begin."
add_overlay(sac_objective.sac_image)
else
var/datum/objective/eldergod/summon_objective = locate() in antag.cult_team.objectives
if(!summon_objective)
return
var/list/location_list = list()
for(var/area/area_to_check in summon_objective.summon_spots)
location_list += area_to_check.get_original_area_name()
desc = "The sacrifice is complete, summon Nar'Sie! The summoning can only take place in [english_list(location_list)]!"
if(icon_state == "runed_sense1")
return
animate(src, transform = null, time = 1, loop = 0)
angle = 0
cut_overlays()
icon_state = "runed_sense1"
add_overlay(narnar)
return
// actual tracking
var/turf/P = get_turf(blood_target)
var/turf/Q = get_turf(owner)
if(!P || !Q || (P.z != Q.z)) //The target is on a different Z level, we cannot sense that far.
Expand All @@ -593,6 +601,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
desc = "You are currently tracking [real_target.real_name] in [get_area_name(blood_target)]."
else
desc = "You are currently tracking [blood_target] in [get_area_name(blood_target)]."

var/target_angle = get_angle(Q, P)
var/target_dist = get_dist(P, Q)
cut_overlays()
Expand Down
8 changes: 4 additions & 4 deletions code/datums/actions/items/cult_dagger.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
return ..()

/datum/action/item_action/cult_dagger/Trigger(trigger_flags)
for(var/obj/item/held_item as anything in owner.held_items) // In case we were already holding a dagger
if(istype(held_item, /obj/item/melee/cultblade/dagger))
held_item.attack_self(owner)
return
if(target in owner.held_items)
var/obj/item/target_item = target
target_item.attack_self(owner)
return
var/obj/item/target_item = target
if(owner.can_equip(target_item, ITEM_SLOT_HANDS))
owner.temporarilyRemoveItemFromInventory(target_item)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/// This component will intercept bare-handed attacks by the owner on sufficiently injured carbons and amputate random limbs instead
/datum/element/amputating_limbs
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
/datum/component/amputating_limbs
/// How long does it take?
var/surgery_time
/// What is the means by which we describe the act of amputation?
Expand All @@ -12,34 +10,38 @@
var/snip_chance
/// The types of limb we can remove
var/list/target_zones
/// Callback for a proc right before confirming the attack. If it returns FALSE, cancel
var/datum/callback/pre_hit_callback

/datum/element/amputating_limbs/Attach(
datum/target,
/datum/component/amputating_limbs/Initialize(
surgery_time = 5 SECONDS,
surgery_verb = "prying",
minimum_stat = SOFT_CRIT,
snip_chance = 100,
list/target_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_ARM, BODY_ZONE_R_LEG),
datum/callback/pre_hit_callback,
)
. = ..()
if (!isliving(target))
return ELEMENT_INCOMPATIBLE
if (!isliving(parent))
return COMPONENT_INCOMPATIBLE
if (!length(target_zones))
CRASH("[src] for [target] was not provided a valid list of body zones to target.")
CRASH("[src] for [parent] was not provided a valid list of body zones to target.")

src.surgery_time = surgery_time
src.surgery_verb = surgery_verb
src.minimum_stat = minimum_stat
src.snip_chance = snip_chance
src.target_zones = target_zones
RegisterSignals(target, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET), PROC_REF(try_amputate))
src.pre_hit_callback = pre_hit_callback

/datum/element/amputating_limbs/Detach(datum/source)
UnregisterSignal(source, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET))
return ..()
/datum/component/amputating_limbs/RegisterWithParent()
RegisterSignals(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET), PROC_REF(try_amputate))

/datum/component/amputating_limbs/UnregisterFromParent()
UnregisterSignal(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET))

/// Called when you click on literally anything with your hands, see if it is an injured carbon and then try to cut it up
/datum/element/amputating_limbs/proc/try_amputate(mob/living/surgeon, atom/victim, proximity, modifiers)
/datum/component/amputating_limbs/proc/try_amputate(mob/living/surgeon, atom/victim, proximity, modifiers)
SIGNAL_HANDLER
if (!proximity || !iscarbon(victim) || HAS_TRAIT(victim, TRAIT_NODISMEMBER) || !prob(snip_chance))
return
Expand All @@ -52,6 +54,9 @@
surgeon.balloon_alert(surgeon, "already busy!")
return COMPONENT_CANCEL_ATTACK_CHAIN

if(pre_hit_callback && !pre_hit_callback.Invoke(victim))
return

var/list/valid_targets = list()
for (var/obj/item/bodypart/possible_target as anything in limbed_victim.bodyparts)
if (possible_target.bodypart_flags & BODYPART_UNREMOVABLE)
Expand All @@ -67,8 +72,9 @@
return COMPONENT_CANCEL_ATTACK_CHAIN

/// Chop one off
/datum/element/amputating_limbs/proc/amputate(mob/living/surgeon, mob/living/carbon/victim, obj/item/bodypart/to_remove)
surgeon.visible_message(span_warning("[surgeon] [surgery_verb] [to_remove] off of [victim]!"))
/datum/component/amputating_limbs/proc/amputate(mob/living/surgeon, mob/living/carbon/victim, obj/item/bodypart/to_remove)
if(surgery_time > 0 SECONDS)
surgeon.visible_message(span_warning("[surgeon] is [surgery_verb] the [to_remove] off of [victim]!"))
if (surgery_time > 0 && !do_after(surgeon, delay = surgery_time, target = victim))
return
to_remove.dismember()
Loading
Loading